1 import xmlrpclib
2 import os
3 import os.path
4 import hashlib
5
6 try:
7 import xml.etree.ElementTree as ET
8 except ImportError:
9
10 import elementtree.ElementTree as ET
13
14 DEFAULT_ONE_AUTH = "~/.one/one_auth"
15
16 - def __init__(self, host, port, user, password):
17 uri = "http://%s:%i" % (host, port)
18 self.rpc = xmlrpclib.ServerProxy(uri)
19 try:
20 methods = self.rpc.system.listMethods()
21 except xmlrpclib.Fault, err:
22 raise Exception("Cannot connect to ONE XML RPC server at %s" % uri)
23
24 if not set(["one.hostpool.info",
25 "one.host.info",
26 "one.vmpool.info",
27 "one.vm.info"]).issubset(set(methods)):
28 raise Exception("XML RPC server does not support required methods. OpenNebula 1.4 or higher is required.")
29
30 passhash = hashlib.sha1(password).hexdigest()
31
32 self.auth = "%s:%s" % (user, passhash)
33
34 @staticmethod
36 if not os.environ.has_key("ONE_AUTH"):
37 one_auth = OpenNebulaXMLRPCClient.DEFAULT_ONE_AUTH
38 else:
39 one_auth = os.environ["ONE_AUTH"]
40
41 one_auth = os.path.expanduser(one_auth)
42
43 if not os.path.exists(one_auth):
44 raise Exception("Authorization file %s does not exists" % one_auth)
45
46 f = open(one_auth, "r")
47 try:
48 line = f.readline().strip()
49 user, passw = line.split(":")
50 return user, passw
51 except:
52 raise Exception("Authorization file is malformed")
53
54
56 try:
57 (rc, value) = self.rpc.one.hostpool.info(self.auth)
58 if rc == False:
59 raise Exception("ONE reported an error: %s" % value)
60 else:
61 hosts = OpenNebulaHost.from_hostpool_xml(value)
62 return hosts
63 except xmlrpclib.Fault, err:
64 raise Exception("XMLRPC fault: %s" % err.faultString)
65
67 try:
68 (rc, value) = self.rpc.one.host.info(self.auth, hid)
69 if rc == False:
70 raise Exception("ONE reported an error: %s" % value)
71 else:
72 host = OpenNebulaHost.from_host_xml(value)
73 return host
74 except xmlrpclib.Fault, err:
75 raise Exception("XMLRPC fault: %s" % err.faultString)
76
78 try:
79 (rc, value) = self.rpc.one.vmpool.info(self.auth, -2)
80 if rc == False:
81 raise Exception("ONE reported an error: %s" % value)
82 else:
83 hosts = OpenNebulaVM.from_vmpool_xml(value)
84 return hosts
85 except xmlrpclib.Fault, err:
86 raise Exception("XMLRPC fault: %s" % err.faultString)
87
89 try:
90 (rc, value) = self.rpc.one.vm.info(self.auth, id)
91 if rc == False:
92 raise Exception("ONE reported an error: %s" % value)
93 else:
94 host = OpenNebulaVM.from_vm_xml(value)
95 return host
96 except xmlrpclib.Fault, err:
97 raise Exception("XMLRPC fault: %s" % err.faultString)
98
100 try:
101 rv = self.rpc.one.vm.deploy(self.auth, vid, hid)
102 if rv[0] == False:
103 raise Exception("ONE reported an error: %s" % rv[1])
104 else:
105 return
106 except xmlrpclib.Fault, err:
107 raise Exception("XMLRPC fault: %s" % err.faultString)
108
110 if not action in ["shutdown", "hold", "release", "stop",
111 "cancel", "suspend", "resume", "restart",
112 "finalize" ]:
113 raise Exception("%s is not a valid action" % action)
114 try:
115 rv = self.rpc.one.vm.action(self.auth, action, vid)
116 if rv[0] == False:
117 raise Exception("ONE reported an error: %s" % rv[1])
118 else:
119 return
120 except xmlrpclib.Fault, err:
121 raise Exception("XMLRPC fault: %s" % err.faultString)
122
125
128
131
134
137
140
143
146
149
152
153 STATE_INIT = 0
154 STATE_MONITORING = 1
155 STATE_MONITORED = 2
156 STATE_ERROR = 3
157 STATE_DISABLED = 4
158
159
161 self.id = int(host_element.find("ID").text)
162 self.name = host_element.find("NAME").text
163 self.state = int(host_element.find("STATE").text)
164 self.im_mad = host_element.find("IM_MAD").text
165 self.vm_mad = host_element.find("VM_MAD").text
166 self.tm_mad = host_element.find("TM_MAD").text
167 self.last_mon_time = int(host_element.find("LAST_MON_TIME").text)
168
169 host_share_element = host_element.find("HOST_SHARE")
170
171 self.disk_usage = int(host_share_element.find("DISK_USAGE").text)
172 self.mem_usage = int(host_share_element.find("MEM_USAGE").text)
173 self.cpu_usage = int(host_share_element.find("CPU_USAGE").text)
174 self.max_disk = int(host_share_element.find("MAX_DISK").text)
175 self.max_mem = int(host_share_element.find("MAX_MEM").text)
176 self.max_cpu = int(host_share_element.find("MAX_CPU").text)
177 self.free_disk = int(host_share_element.find("FREE_DISK").text)
178 self.free_mem = int(host_share_element.find("FREE_MEM").text)
179 self.free_cpu = int(host_share_element.find("FREE_CPU").text)
180 self.used_disk = int(host_share_element.find("USED_DISK").text)
181 self.used_mem = int(host_share_element.find("USED_MEM").text)
182 self.used_cpu = int(host_share_element.find("USED_CPU").text)
183 self.running_vms = int(host_share_element.find("RUNNING_VMS").text)
184
185 self.template = parse_template(host_element.find("TEMPLATE"))
186
187
188 @classmethod
190 host_element = ET.fromstring(xmlstr)
191 return cls(host_element)
192
193 @classmethod
195 hostpool_element = ET.fromstring(xmlstr)
196 host_elements = hostpool_element.findall("HOST")
197 return [cls(host_element) for host_element in host_elements]
198
266
268 template = {}
269 if template_element != None:
270 for subelement in template_element:
271 name = subelement.tag
272 if len(subelement) == 0:
273 template[name] = subelement.text
274 else:
275 template[name] = {}
276 for subsubelement in subelement:
277 template[name][subsubelement.tag] = subsubelement.text
278
279 return template
280