38b0a0636d68b95aae80dd9fa206fdc75819bd21
[osm/vim-emu.git] / src / emuvim / api / zerorpc / compute.py
1 """
2 Distributed Cloud Emulator (dcemulator)
3 (c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
4 """
5
6 import logging
7 import threading
8 import zerorpc
9
10 logging.basicConfig(level=logging.INFO)
11
12
13 class ZeroRpcApiEndpoint(object):
14 """
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 """
22
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):
31 self.dcs[dc.label] = dc
32 logging.info("Connected DC(%s) to API endpoint %s(%s:%d)" % (
33 dc.label, self.__class__.__name__, self.ip, self.port))
34
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
48 class MultiDatacenterApi(object):
49 """
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 """
55
56 def __init__(self, dcs):
57 self.dcs = dcs
58
59 def compute_action_start(self, dc_label, compute_name, image, network, command):
60 """
61 Start a new compute instance: A docker container (note: zerorpc does not support keyword arguments)
62 :param dc_label: name of the DC
63 :param compute_name: compute container name
64 :param image: image name
65 :param command: command to execute
66 :param network: list of all interface of the vnf, with their parameters (id=id1,ip=x.x.x.x/x),...
67 :return: networks list({"id":"input","ip": "10.0.0.254/8"}, {"id":"output","ip": "11.0.0.254/24"})
68 """
69 # TODO what to return UUID / given name / internal name ?
70 logging.debug("RPC CALL: compute start")
71 logging.info('nwlist2: {0}'.format(network))
72 try:
73 c = self.dcs.get(dc_label).startCompute(
74 compute_name, image=image, command=command, network=network)
75 #return str(c.name)
76 # return docker inspect dict
77 return c.getStatus()
78 except Exception as ex:
79 logging.exception("RPC error.")
80 return ex.message
81
82 def compute_action_stop(self, dc_label, compute_name):
83 logging.debug("RPC CALL: compute stop")
84 try:
85 return self.dcs.get(dc_label).stopCompute(compute_name)
86 except Exception as ex:
87 logging.exception("RPC error.")
88 return ex.message
89
90 def compute_list(self, dc_label):
91 logging.debug("RPC CALL: compute list")
92 try:
93 if dc_label is None:
94 # return list with all compute nodes in all DCs
95 all_containers = []
96 for dc in self.dcs.itervalues():
97 all_containers += dc.listCompute()
98 return [(c.name, c.getStatus())
99 for c in all_containers]
100 else:
101 # return list of compute nodes for specified DC
102 return [(c.name, c.getStatus())
103 for c in self.dcs.get(dc_label).listCompute()]
104 except Exception as ex:
105 logging.exception("RPC error.")
106 return ex.message
107
108 def compute_status(self, dc_label, compute_name):
109 logging.debug("RPC CALL: compute status")
110 try:
111 return self.dcs.get(
112 dc_label).containers.get(compute_name).getStatus()
113 except Exception as ex:
114 logging.exception("RPC error.")
115 return ex.message
116
117 def compute_profile(self, dc_label, compute_name, image, kwargs):
118 # note: zerorpc does not support keyword arguments
119
120 # start vnf
121 vnf_status = self.compute_action_start(self, dc_label, compute_name, image,
122 kwargs.get('network'),
123 kwargs.get('command'))
124
125 # start traffic source (with fixed ip addres, no use for now...)
126 self.compute_action_start(self, dc_label, 'psrc', 'profile_source', [{'id':'output','ip':'10.0.10.1/24'}], None)
127
128
129
130
131
132 def datacenter_list(self):
133 logging.debug("RPC CALL: datacenter list")
134 try:
135 return [d.getStatus() for d in self.dcs.itervalues()]
136 except Exception as ex:
137 logging.exception("RPC error.")
138 return ex.message
139
140 def datacenter_status(self, dc_label):
141 logging.debug("RPC CALL: datacenter status")
142 try:
143 return self.dcs.get(dc_label).getStatus()
144 except Exception as ex:
145 logging.exception("RPC error.")
146 return ex.message
147
148 '''
149 if __name__ == "__main__":
150 test = MultiDatacenterApi({})
151 test.compute_profile('dc1','vnf1', 'image',network='',command='test',other='other')
152 '''
153