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 from flask_restful
import Resource
30 from flask
import request
33 logging
.basicConfig(level
=logging
.INFO
)
35 CORS_HEADER
= {'Access-Control-Allow-Origin': '*'}
40 class Compute(Resource
):
42 Start a new compute instance: A docker container (note: zerorpc does not support keyword arguments)
43 :param dc_label: name of the DC
44 :param compute_name: compute container name
45 :param image: image name
46 :param command: command to execute
47 :param network: list of all interface of the vnf, with their parameters (id=id1,ip=x.x.x.x/x),...
48 example networks list({"id":"input","ip": "10.0.0.254/8"}, {"id":"output","ip": "11.0.0.254/24"})
49 :return: docker inspect dict of deployed docker
53 def put(self
, dc_label
, compute_name
, resource
=None, value
=None):
54 # check if resource update
55 if resource
and value
:
56 c
= self
._update
_resource
(dc_label
, compute_name
, resource
, value
)
57 return c
.getStatus(), 200
59 # deploy new container
60 # check if json data is a dict
64 elif type(data
) is not dict:
65 data
= json
.loads(request
.json
)
67 network
= data
.get("network")
68 nw_list
= self
._parse
_network
(network
)
69 image
= data
.get("image")
70 command
= data
.get("docker_command")
73 logging
.debug("API CALL: compute start")
74 c
= dcs
.get(dc_label
).startCompute(
75 compute_name
, image
=image
, command
=command
, network
=nw_list
)
76 # return docker inspect dict
77 return c
.getStatus(), 200, CORS_HEADER
78 except Exception as ex
:
79 logging
.exception("API error.")
80 return ex
.message
, 500, CORS_HEADER
82 def _update_resource(self
, dc_label
, compute_name
, resource
, value
):
83 #check if container exists
84 d
= dcs
.get(dc_label
).net
.getNodeByName(compute_name
)
86 cpu_period
= int(dcs
.get(dc_label
).net
.cpu_period
)
87 cpu_quota
= int(cpu_period
* float(value
))
88 #put default values back
92 d
.updateCpuLimit(cpu_period
=cpu_period
, cpu_quota
=cpu_quota
)
96 def get(self
, dc_label
, compute_name
):
98 logging
.debug("API CALL: compute status")
101 return dcs
.get(dc_label
).containers
.get(compute_name
).getStatus(), 200, CORS_HEADER
102 except Exception as ex
:
103 logging
.exception("API error.")
104 return ex
.message
, 500, CORS_HEADER
106 def delete(self
, dc_label
, compute_name
):
107 logging
.debug("API CALL: compute stop")
109 return dcs
.get(dc_label
).stopCompute(compute_name
), 200, CORS_HEADER
110 except Exception as ex
:
111 logging
.exception("API error.")
112 return ex
.message
, 500, CORS_HEADER
114 def _parse_network(self
, network_str
):
116 parse the options for all network interfaces of the vnf
117 :param network_str: (id=x,ip=x.x.x.x/x), ...
118 :return: list of dicts [{"id":x,"ip":"x.x.x.x/x"}, ...]
122 # TODO make this more robust with regex check
123 if network_str
is None:
126 networks
= network_str
[1:-1].split('),(')
128 nw_dict
= dict(tuple(e
.split('=')) for e
in nw
.split(','))
129 nw_list
.append(nw_dict
)
134 class ComputeList(Resource
):
137 def get(self
, dc_label
=None):
138 logging
.debug("API CALL: compute list")
140 if dc_label
is None or dc_label
== 'None':
141 # return list with all compute nodes in all DCs
143 for dc
in dcs
.itervalues():
144 all_containers
+= dc
.listCompute()
145 return [(c
.name
, c
.getStatus()) for c
in all_containers
], 200, CORS_HEADER
147 # return list of compute nodes for specified DC
148 return [(c
.name
, c
.getStatus())
149 for c
in dcs
.get(dc_label
).listCompute()], 200, CORS_HEADER
150 except Exception as ex
:
151 logging
.exception("API error.")
152 return ex
.message
, 500, CORS_HEADER
155 class DatacenterList(Resource
):
159 logging
.debug("API CALL: datacenter list")
161 return [d
.getStatus() for d
in dcs
.itervalues()], 200, CORS_HEADER
162 except Exception as ex
:
163 logging
.exception("API error.")
164 return ex
.message
, 500, CORS_HEADER
167 class DatacenterStatus(Resource
):
170 def get(self
, dc_label
):
171 logging
.debug("API CALL: datacenter status")
173 return dcs
.get(dc_label
).getStatus(), 200, CORS_HEADER
174 except Exception as ex
:
175 logging
.exception("API error.")
176 return ex
.message
, 500, CORS_HEADER