2 Distributed Cloud Emulator (dcemulator)
3 (c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
10 logging
.basicConfig(level
=logging
.INFO
)
13 class ZeroRpcApiEndpoint(object):
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.
23 def __init__(self
, listenip
, port
):
27 logging
.debug("Created API endpoint %s(%s:%d)" % (
28 self
.__class
__.__name
__, self
.ip
, self
.port
))
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
))
36 thread
= threading
.Thread(target
=self
._api
_server
_thread
, args
=())
39 logging
.debug("Started API endpoint %s(%s:%d)" % (
40 self
.__class
__.__name
__, self
.ip
, self
.port
))
42 def _api_server_thread(self
):
43 s
= zerorpc
.Server(MultiDatacenterApi(self
.dcs
))
44 s
.bind("tcp://%s:%d" % (self
.ip
, self
.port
))
48 class MultiDatacenterApi(object):
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.
56 def __init__(self
, dcs
):
59 def compute_action_start(self
, dc_label
, compute_name
, image
, network
, command
):
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"})
69 # TODO what to return UUID / given name / internal name ?
70 logging
.debug("RPC CALL: compute start")
72 c
= self
.dcs
.get(dc_label
).startCompute(
73 compute_name
, image
=image
, command
=command
, network
=network
)
75 # return docker inspect dict
77 except Exception as ex
:
78 logging
.exception("RPC error.")
81 def compute_action_stop(self
, dc_label
, compute_name
):
82 logging
.debug("RPC CALL: compute stop")
84 return self
.dcs
.get(dc_label
).stopCompute(compute_name
)
85 except Exception as ex
:
86 logging
.exception("RPC error.")
89 def compute_list(self
, dc_label
):
90 logging
.debug("RPC CALL: compute list")
93 # return list with all compute nodes in all DCs
95 for dc
in self
.dcs
.itervalues():
96 all_containers
+= dc
.listCompute()
97 return [(c
.name
, c
.getStatus())
98 for c
in all_containers
]
100 # return list of compute nodes for specified DC
101 return [(c
.name
, c
.getStatus())
102 for c
in self
.dcs
.get(dc_label
).listCompute()]
103 except Exception as ex
:
104 logging
.exception("RPC error.")
107 def compute_status(self
, dc_label
, compute_name
):
108 logging
.debug("RPC CALL: compute status")
111 dc_label
).containers
.get(compute_name
).getStatus()
112 except Exception as ex
:
113 logging
.exception("RPC error.")
116 def compute_profile(self
, dc_label
, compute_name
, image
, kwargs
):
117 # note: zerorpc does not support keyword arguments
119 ## VIM/dummy gatekeeper's tasks:
121 vnf_status
= self
.compute_action_start( dc_label
, compute_name
, image
,
122 kwargs
.get('network'),
123 kwargs
.get('command'))
124 # start traffic source (with fixed ip addres, no use for now...)
125 self
.compute_action_start( dc_label
, 'psrc', 'profile_source', [{'id':'output'}], None)
126 # link vnf to traffic source
127 DCNetwork
= self
.dcs
.get(dc_label
).net
128 DCNetwork
.setChain('psrc', compute_name
,
129 vnf_src_interface
='output',
130 vnf_dst_interface
=kwargs
.get('input'),
131 cmd
='add-flow', weight
=None)
134 # get monitor data and analyze
138 ## VIM/dummy gatekeeper's tasks:
139 # remove vnfs and chain
142 def datacenter_list(self
):
143 logging
.debug("RPC CALL: datacenter list")
145 return [d
.getStatus() for d
in self
.dcs
.itervalues()]
146 except Exception as ex
:
147 logging
.exception("RPC error.")
150 def datacenter_status(self
, dc_label
):
151 logging
.debug("RPC CALL: datacenter status")
153 return self
.dcs
.get(dc_label
).getStatus()
154 except Exception as ex
:
155 logging
.exception("RPC error.")
159 if __name__ == "__main__":
160 test = MultiDatacenterApi({})
161 test.compute_profile('dc1','vnf1', 'image',network='',command='test',other='other')