blob: fd814b323ac20f5dbae5c632c0fc9e24170d64b8 [file] [log] [blame]
peusterm9c252b62016-01-06 16:59:53 +01001"""
2Distributed Cloud Emulator (dcemulator)
3(c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
4"""
5
6import logging
7import threading
8import zerorpc
9
peustermbd44f4a2016-01-13 14:53:30 +010010logging.basicConfig(level=logging.INFO)
peusterm9c252b62016-01-06 16:59:53 +010011
12
13class ZeroRpcApiEndpoint(object):
peusterme4e89d32016-01-07 09:14:54 +010014 """
15 Simple API endpoint that offers a zerorpc-based
16 interface. This interface will be used by the
17 default command line client.
18 It can be used as a reference to implement
19 REST interfaces providing the same semantics,
20 like e.g. OpenStack compute API.
21 """
peusterm9c252b62016-01-06 16:59:53 +010022
23 def __init__(self, listenip, port):
24 self.dcs = {}
25 self.ip = listenip
26 self.port = port
27 logging.debug("Created API endpoint %s(%s:%d)" % (
28 self.__class__.__name__, self.ip, self.port))
29
30 def connectDatacenter(self, dc):
peusterma47db032016-02-04 14:55:29 +010031 self.dcs[dc.label] = dc
peusterm9c252b62016-01-06 16:59:53 +010032 logging.info("Connected DC(%s) to API endpoint %s(%s:%d)" % (
peusterma47db032016-02-04 14:55:29 +010033 dc.label, self.__class__.__name__, self.ip, self.port))
peusterm9c252b62016-01-06 16:59:53 +010034
35 def start(self):
36 thread = threading.Thread(target=self._api_server_thread, args=())
37 thread.daemon = True
38 thread.start()
39 logging.debug("Started API endpoint %s(%s:%d)" % (
40 self.__class__.__name__, self.ip, self.port))
41
42 def _api_server_thread(self):
43 s = zerorpc.Server(MultiDatacenterApi(self.dcs))
44 s.bind("tcp://%s:%d" % (self.ip, self.port))
45 s.run()
46
47
48class MultiDatacenterApi(object):
peusterme4e89d32016-01-07 09:14:54 +010049 """
50 Just pass through the corresponding request to the
51 selected data center. Do not implement provisioning
52 logic here because will will have multiple API
53 endpoint implementations at the end.
54 """
peusterm9c252b62016-01-06 16:59:53 +010055
56 def __init__(self, dcs):
57 self.dcs = dcs
58
stevenvanrossem8fbf9782016-02-17 11:40:23 +010059 def compute_action_start(self, dc_label, compute_name, image, command, network):
peusterm45dce612016-01-29 15:34:38 +010060 # network e.g. {"ip": "10.0.0.254/8"}
peusterm4e98b632016-01-12 14:08:07 +010061 # TODO what to return UUID / given name / internal name ?
peusterm70baaf82016-01-06 17:14:40 +010062 logging.debug("RPC CALL: compute start")
peusterm7aae6852016-01-12 14:53:18 +010063 try:
peusterm53504942016-02-04 16:09:28 +010064 c = self.dcs.get(dc_label).startCompute(
stevenvanrossem8fbf9782016-02-17 11:40:23 +010065 compute_name, image=image, command=command, network=network)
peustermfa4bcc72016-01-15 11:08:09 +010066 return str(c.name)
peusterm7aae6852016-01-12 14:53:18 +010067 except Exception as ex:
68 logging.exception("RPC error.")
69 return ex.message
peusterm9c252b62016-01-06 16:59:53 +010070
peusterm53504942016-02-04 16:09:28 +010071 def compute_action_stop(self, dc_label, compute_name):
peustermbd44f4a2016-01-13 14:53:30 +010072 logging.debug("RPC CALL: compute stop")
peusterm7aae6852016-01-12 14:53:18 +010073 try:
peusterm53504942016-02-04 16:09:28 +010074 return self.dcs.get(dc_label).stopCompute(compute_name)
peusterm7aae6852016-01-12 14:53:18 +010075 except Exception as ex:
76 logging.exception("RPC error.")
77 return ex.message
peusterm9c252b62016-01-06 16:59:53 +010078
peusterm53504942016-02-04 16:09:28 +010079 def compute_list(self, dc_label):
peustermbd44f4a2016-01-13 14:53:30 +010080 logging.debug("RPC CALL: compute list")
peusterm7aae6852016-01-12 14:53:18 +010081 try:
peusterm53504942016-02-04 16:09:28 +010082 if dc_label is None:
peusterm2ec74e12016-01-13 11:17:53 +010083 # return list with all compute nodes in all DCs
84 all_containers = []
85 for dc in self.dcs.itervalues():
86 all_containers += dc.listCompute()
87 return [(c.name, c.getStatus())
88 for c in all_containers]
89 else:
90 # return list of compute nodes for specified DC
91 return [(c.name, c.getStatus())
peusterm53504942016-02-04 16:09:28 +010092 for c in self.dcs.get(dc_label).listCompute()]
peusterm7aae6852016-01-12 14:53:18 +010093 except Exception as ex:
94 logging.exception("RPC error.")
95 return ex.message
peusterm4e98b632016-01-12 14:08:07 +010096
peusterm53504942016-02-04 16:09:28 +010097 def compute_status(self, dc_label, compute_name):
peustermbd44f4a2016-01-13 14:53:30 +010098 logging.debug("RPC CALL: compute status")
peusterm7aae6852016-01-12 14:53:18 +010099 try:
100 return self.dcs.get(
peusterm53504942016-02-04 16:09:28 +0100101 dc_label).containers.get(compute_name).getStatus()
peusterm7aae6852016-01-12 14:53:18 +0100102 except Exception as ex:
103 logging.exception("RPC error.")
104 return ex.message
peustermd313dc12016-02-04 15:36:02 +0100105
106 def datacenter_list(self):
107 logging.debug("RPC CALL: datacenter list")
108 try:
109 return [d.getStatus() for d in self.dcs.itervalues()]
110 except Exception as ex:
111 logging.exception("RPC error.")
112 return ex.message
peusterm53504942016-02-04 16:09:28 +0100113
114 def datacenter_status(self, dc_label):
115 logging.debug("RPC CALL: datacenter status")
116 try:
117 return self.dcs.get(dc_label).getStatus()
118 except Exception as ex:
119 logging.exception("RPC error.")
120 return ex.message