2 Copyright (c) 2015 SONATA-NFV and Paderborn University
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
9 http://www.apache.org/licenses/LICENSE-2.0
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
17 Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
18 nor the names of its contributors may be used to endorse or promote
19 products derived from this software without specific prior written
22 This work has been performed in the framework of the SONATA project,
23 funded by the European Commission under Grant number 671517 through
24 the Horizon 2020 and 5G-PPP programmes. The authors would like to
25 acknowledge the contributions of their colleagues of the SONATA
26 partner consortium (www.sonata-nfv.eu).
29 Distributed Cloud Emulator (dcemulator)
30 (c) 2015 by Manuel Peuster <manuel.peuster@upb.de>
37 logging
.basicConfig(level
=logging
.INFO
)
40 class ZeroRpcApiEndpoint(object):
42 Simple API endpoint that offers a zerorpc-based
43 interface. This interface will be used by the
44 default command line client.
45 It can be used as a reference to implement
46 REST interfaces providing the same semantics,
47 like e.g. OpenStack compute API.
50 def __init__(self
, listenip
, port
):
54 logging
.debug("Created API endpoint %s(%s:%d)" % (
55 self
.__class
__.__name
__, self
.ip
, self
.port
))
57 def connectDatacenter(self
, dc
):
58 self
.dcs
[dc
.label
] = dc
59 logging
.info("Connected DC(%s) to API endpoint %s(%s:%d)" % (
60 dc
.label
, self
.__class
__.__name
__, self
.ip
, self
.port
))
63 thread
= threading
.Thread(target
=self
._api
_server
_thread
, args
=())
66 logging
.debug("Started API endpoint %s(%s:%d)" % (
67 self
.__class
__.__name
__, self
.ip
, self
.port
))
69 def _api_server_thread(self
):
70 s
= zerorpc
.Server(MultiDatacenterApi(self
.dcs
))
71 s
.bind("tcp://%s:%d" % (self
.ip
, self
.port
))
75 class MultiDatacenterApi(object):
77 Just pass through the corresponding request to the
78 selected data center. Do not implement provisioning
79 logic here because will will have multiple API
80 endpoint implementations at the end.
83 def __init__(self
, dcs
):
86 def compute_action_start(self
, dc_label
, compute_name
, image
, network
, command
):
88 Start a new compute instance: A docker container (note: zerorpc does not support keyword arguments)
89 :param dc_label: name of the DC
90 :param compute_name: compute container name
91 :param image: image name
92 :param command: command to execute
93 :param network: list of all interface of the vnf, with their parameters (id=id1,ip=x.x.x.x/x),...
94 :return: networks list({"id":"input","ip": "10.0.0.254/8"}, {"id":"output","ip": "11.0.0.254/24"})
96 # TODO what to return UUID / given name / internal name ?
97 logging
.debug("RPC CALL: compute start")
99 c
= self
.dcs
.get(dc_label
).startCompute(
100 compute_name
, image
=image
, command
=command
, network
=network
)
102 # return docker inspect dict
104 except Exception as ex
:
105 logging
.exception("RPC error.")
108 def compute_action_stop(self
, dc_label
, compute_name
):
109 logging
.debug("RPC CALL: compute stop")
111 return self
.dcs
.get(dc_label
).stopCompute(compute_name
)
112 except Exception as ex
:
113 logging
.exception("RPC error.")
116 def compute_list(self
, dc_label
):
117 logging
.debug("RPC CALL: compute list")
120 # return list with all compute nodes in all DCs
122 for dc
in self
.dcs
.itervalues():
123 all_containers
+= dc
.listCompute()
124 return [(c
.name
, c
.getStatus())
125 for c
in all_containers
]
127 # return list of compute nodes for specified DC
128 return [(c
.name
, c
.getStatus())
129 for c
in self
.dcs
.get(dc_label
).listCompute()]
130 except Exception as ex
:
131 logging
.exception("RPC error.")
134 def compute_status(self
, dc_label
, compute_name
):
135 logging
.debug("RPC CALL: compute status")
138 dc_label
).containers
.get(compute_name
).getStatus()
139 except Exception as ex
:
140 logging
.exception("RPC error.")
143 def datacenter_list(self
):
144 logging
.debug("RPC CALL: datacenter list")
146 return [d
.getStatus() for d
in self
.dcs
.itervalues()]
147 except Exception as ex
:
148 logging
.exception("RPC error.")
151 def datacenter_status(self
, dc_label
):
152 logging
.debug("RPC CALL: datacenter status")
154 return self
.dcs
.get(dc_label
).getStatus()
155 except Exception as ex
:
156 logging
.exception("RPC error.")