1 # Copyright (c) 2015 SONATA-NFV and Paderborn University
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 # Neither the name of the SONATA-NFV, Paderborn University
17 # nor the names of its contributors may be used to endorse or promote
18 # products derived from this software without specific prior written
21 # This work has been performed in the framework of the SONATA project,
22 # funded by the European Commission under Grant number 671517 through
23 # the Horizon 2020 and 5G-PPP programmes. The authors would like to
24 # acknowledge the contributions of their colleagues of the SONATA
25 # partner consortium (www.sonata-nfv.eu).
26 from flask_restful
import Resource
27 from flask
import request
, Response
33 def __init__(self
, api
):
37 ###############################################################################
39 ###############################################################################
41 class PortPairsCreate(SFC
):
43 logging
.debug("API CALL: %s POST" % str(self
.__class
__.__name
__))
46 request_dict
= json
.loads(request
.data
).get("port_pair")
47 name
= request_dict
["name"]
49 ingress_port
= self
.api
.compute
.find_port_by_name_or_id(
50 request_dict
["ingress"])
51 egress_port
= self
.api
.compute
.find_port_by_name_or_id(
52 request_dict
["egress"])
54 port_pair
= self
.api
.compute
.create_port_pair(name
)
55 port_pair
.ingress
= ingress_port
56 port_pair
.egress
= egress_port
57 if "description" in request_dict
:
58 port_pair
.description
= request_dict
["description"]
59 if "service_function_parameters" in request_dict
:
60 port_pair
.service_function_parameters
= request_dict
["service_function_parameters"]
63 "port_pair": port_pair
.create_dict(self
.api
.compute
)
65 return Response(json
.dumps(resp
), status
=201,
66 mimetype
='application/json')
67 except Exception as ex
:
68 logging
.exception("Neutron SFC: %s Exception." %
69 str(self
.__class
__.__name
__))
70 return Response(ex
.message
, status
=500,
71 mimetype
='application/json')
74 class PortPairsUpdate(SFC
):
75 def put(self
, pair_id
):
76 logging
.debug("API CALL: %s PUT" % str(self
.__class
__.__name
__))
79 request_dict
= json
.loads(request
.data
).get("port_pair")
80 port_pair
= self
.api
.compute
.find_port_pair_by_name_or_id(pair_id
)
81 if "name" in request_dict
:
82 port_pair
.name
= request_dict
["name"]
83 if "description" in request_dict
:
84 port_pair
.description
= request_dict
["description"]
87 "port_pair": port_pair
.create_dict(self
.api
.compute
)
89 return Response(json
.dumps(resp
), status
=200,
90 mimetype
='application/json')
91 except Exception as ex
:
92 logging
.exception("Neutron SFC: %s Exception." %
93 str(self
.__class
__.__name
__))
94 return Response(ex
.message
, status
=500,
95 mimetype
='application/json')
98 class PortPairsDelete(SFC
):
99 def delete(self
, pair_id
):
100 logging
.debug("API CALL: %s DELETE" % str(self
.__class
__.__name
__))
102 self
.api
.compute
.delete_port_pair(pair_id
)
104 return Response("", status
=204,
105 mimetype
='application/json')
106 except Exception as ex
:
107 logging
.exception("Neutron SFC: %s Exception." %
108 str(self
.__class
__.__name
__))
109 return Response(ex
.message
, status
=500,
110 mimetype
='application/json')
113 class PortPairsList(SFC
):
115 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
117 port_pairs
= self
.api
.compute
.port_pairs
.values()
118 id = request
.args
.get('id')
120 port_pairs
= filter(lambda port_pair
: port_pair
.id == id, port_pairs
)
121 resp
= {"port_pairs": map(lambda port_pair
: port_pair
.create_dict(self
.api
.compute
), port_pairs
)}
123 return Response(json
.dumps(resp
), status
=200,
124 mimetype
='application/json')
125 except Exception as ex
:
126 logging
.exception("Neutron SFC: %s Exception." %
127 str(self
.__class
__.__name
__))
128 return Response(ex
.message
, status
=500,
129 mimetype
='application/json')
132 class PortPairsShow(SFC
):
133 def get(self
, pair_id
):
134 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
137 port_pair
= self
.api
.compute
.find_port_pair_by_name_or_id(pair_id
)
139 "port_pair": port_pair
.create_dict(self
.api
.compute
)
141 return Response(json
.dumps(resp
), status
=200,
142 mimetype
='application/json')
143 except Exception as ex
:
144 logging
.exception("Neutron SFC: %s Exception." %
145 str(self
.__class
__.__name
__))
146 return Response(ex
.message
, status
=500,
147 mimetype
='application/json')
150 ###############################################################################
152 ###############################################################################
154 class PortPairGroupCreate(SFC
):
156 logging
.debug("API CALL: %s POST" % str(self
.__class
__.__name
__))
159 request_dict
= json
.loads(request
.data
).get("port_pair_group")
161 port_pair_group
= self
.api
.compute
.create_port_pair_group(
162 request_dict
["name"])
163 port_pair_group
.port_pairs
= request_dict
["port_pairs"]
164 if "description" in request_dict
:
165 port_pair_group
.description
= request_dict
["description"]
166 if "port_pair_group_parameters" in request_dict
:
167 port_pair_group
.port_pair_group_parameters
= request_dict
[
168 "port_pair_group_parameters"]
171 "port_pair_group": port_pair_group
.create_dict(self
.api
.compute
)
173 return Response(json
.dumps(resp
), status
=201,
174 mimetype
='application/json')
175 except Exception as ex
:
176 logging
.exception("Neutron SFC: %s Exception." %
177 str(self
.__class
__.__name
__))
178 return Response(ex
.message
, status
=500,
179 mimetype
='application/json')
182 class PortPairGroupUpdate(SFC
):
183 def put(self
, group_id
):
184 logging
.debug("API CALL: %s PUT" % str(self
.__class
__.__name
__))
187 request_dict
= json
.loads(request
.data
).get("port_pair_group")
188 port_pair_group
= self
.api
.compute
.find_port_pair_group_by_name_or_id(
190 if "name" in request_dict
:
191 port_pair_group
.name
= request_dict
["name"]
192 if "description" in request_dict
:
193 port_pair_group
.description
= request_dict
["description"]
194 if "port_pairs" in request_dict
:
195 port_pair_group
.port_pairs
= request_dict
["port_pairs"]
198 "port_pair_group": port_pair_group
.create_dict(self
.api
.compute
)
200 return Response(json
.dumps(resp
), status
=200,
201 mimetype
='application/json')
202 except Exception as ex
:
203 logging
.exception("Neutron SFC: %s Exception." %
204 str(self
.__class
__.__name
__))
205 return Response(ex
.message
, status
=500,
206 mimetype
='application/json')
209 class PortPairGroupDelete(SFC
):
210 def delete(self
, group_id
):
211 logging
.debug("API CALL: %s DELETE" % str(self
.__class
__.__name
__))
213 self
.api
.compute
.delete_port_pair_group(group_id
)
215 return Response("", status
=204,
216 mimetype
='application/json')
217 except Exception as ex
:
218 logging
.exception("Neutron SFC: %s Exception." %
219 str(self
.__class
__.__name
__))
220 return Response(ex
.message
, status
=500,
221 mimetype
='application/json')
224 class PortPairGroupList(SFC
):
226 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
228 port_pair_group_list
= []
229 for port_pair_group
in self
.api
.compute
.port_pair_groups
.values():
230 port_pair_group_list
.append(
231 port_pair_group
.create_dict(self
.api
.compute
))
232 resp
= {"port_pair_groups": port_pair_group_list
}
234 return Response(json
.dumps(resp
), status
=200,
235 mimetype
='application/json')
236 except Exception as ex
:
237 logging
.exception("Neutron SFC: %s Exception." %
238 str(self
.__class
__.__name
__))
239 return Response(ex
.message
, status
=500,
240 mimetype
='application/json')
243 class PortPairGroupShow(SFC
):
244 def get(self
, group_id
):
245 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
248 port_pair_group
= self
.api
.compute
.find_port_pair_group_by_name_or_id(
251 "port_pair_group": port_pair_group
.create_dict(self
.api
.compute
)
253 return Response(json
.dumps(resp
), status
=200,
254 mimetype
='application/json')
255 except Exception as ex
:
256 logging
.exception("Neutron SFC: %s Exception." %
257 str(self
.__class
__.__name
__))
258 return Response(ex
.message
, status
=500,
259 mimetype
='application/json')
262 ###############################################################################
264 ###############################################################################
266 class FlowClassifierCreate(SFC
):
268 logging
.debug("API CALL: %s POST" % str(self
.__class
__.__name
__))
271 request_dict
= json
.loads(request
.data
).get("flow_classifier")
273 flow_classifier
= self
.api
.compute
.create_flow_classifier(
274 request_dict
["name"])
275 if "description" in request_dict
:
276 flow_classifier
.description
= request_dict
["description"]
277 if "ethertype" in request_dict
:
278 flow_classifier
.ethertype
= request_dict
["ethertype"]
279 if "protocol" in request_dict
:
280 flow_classifier
.protocol
= request_dict
["protocol"]
281 if "source_port_range_min" in request_dict
:
282 flow_classifier
.source_port_range_min
= request_dict
["source_port_range_min"]
283 if "source_port_range_max" in request_dict
:
284 flow_classifier
.source_port_range_max
= request_dict
["source_port_range_max"]
285 if "destination_port_range_min" in request_dict
:
286 flow_classifier
.destination_port_range_min
= request_dict
[
287 "destination_port_range_min"]
288 if "destination_port_range_max" in request_dict
:
289 flow_classifier
.destination_port_range_max
= request_dict
[
290 "destination_port_range_max"]
291 if "source_ip_prefix" in request_dict
:
292 flow_classifier
.source_ip_prefix
= request_dict
["source_ip_prefix"]
293 if "destination_ip_prefix" in request_dict
:
294 flow_classifier
.destination_ip_prefix
= request_dict
["destination_ip_prefix"]
295 if "logical_source_port" in request_dict
:
296 flow_classifier
.logical_source_port
= request_dict
["logical_source_port"]
297 if "logical_destination_port" in request_dict
:
298 flow_classifier
.logical_destination_port
= request_dict
["logical_destination_port"]
299 if "l7_parameters" in request_dict
:
300 flow_classifier
.l7_parameters
= request_dict
["l7_parameters"]
303 "flow_classifier": flow_classifier
.create_dict(self
.api
.compute
)
305 return Response(json
.dumps(resp
), status
=201,
306 mimetype
='application/json')
307 except Exception as ex
:
308 logging
.exception("Neutron SFC: %s Exception." %
309 str(self
.__class
__.__name
__))
310 return Response(ex
.message
, status
=500,
311 mimetype
='application/json')
314 class FlowClassifierUpdate(SFC
):
315 def put(self
, flow_classifier_id
):
316 logging
.debug("API CALL: %s PUT" % str(self
.__class
__.__name
__))
319 request_dict
= json
.loads(request
.data
).get("flow_classifier")
320 flow_classifier
= self
.api
.compute
.find_flow_classifier_by_name_or_id(
322 if "name" in request_dict
:
323 flow_classifier
.name
= request_dict
["name"]
324 if "description" in request_dict
:
325 flow_classifier
.description
= request_dict
["description"]
328 "flow_classifier": flow_classifier
.create_dict(self
.api
.compute
)
330 return Response(json
.dumps(resp
), status
=200,
331 mimetype
='application/json')
332 except Exception as ex
:
333 logging
.exception("Neutron SFC: %s Exception." %
334 str(self
.__class
__.__name
__))
335 return Response(ex
.message
, status
=500,
336 mimetype
='application/json')
339 class FlowClassifierDelete(SFC
):
340 def delete(self
, flow_classifier_id
):
341 logging
.debug("API CALL: %s DELETE" % str(self
.__class
__.__name
__))
343 self
.api
.compute
.delete_flow_classifier(flow_classifier_id
)
345 return Response("", status
=204,
346 mimetype
='application/json')
347 except Exception as ex
:
348 logging
.exception("Neutron SFC: %s Exception." %
349 str(self
.__class
__.__name
__))
350 return Response(ex
.message
, status
=500,
351 mimetype
='application/json')
354 class FlowClassifierList(SFC
):
356 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
358 flow_classifier_list
= []
359 for flow_classifier
in self
.api
.compute
.flow_classifiers
.values():
360 flow_classifier_list
.append(
361 flow_classifier
.create_dict(self
.api
.compute
))
362 resp
= {"flow_classifiers": flow_classifier_list
}
364 return Response(json
.dumps(resp
), status
=200,
365 mimetype
='application/json')
366 except Exception as ex
:
367 logging
.exception("Neutron SFC: %s Exception." %
368 str(self
.__class
__.__name
__))
369 return Response(ex
.message
, status
=500,
370 mimetype
='application/json')
373 class FlowClassifierShow(SFC
):
374 def get(self
, flow_classifier_id
):
375 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
378 flow_classifier
= self
.api
.compute
.find_flow_classifier_by_name_or_id(
381 "flow_classifier": flow_classifier
.create_dict(self
.api
.compute
)
383 return Response(json
.dumps(resp
), status
=200,
384 mimetype
='application/json')
385 except Exception as ex
:
386 logging
.exception("Neutron SFC: %s Exception." %
387 str(self
.__class
__.__name
__))
388 return Response(ex
.message
, status
=500,
389 mimetype
='application/json')
392 ###############################################################################
394 ###############################################################################
396 class PortChainCreate(SFC
):
398 logging
.debug("API CALL: %s POST" % str(self
.__class
__.__name
__))
401 request_dict
= json
.loads(request
.data
).get("port_chain")
403 port_chain
= self
.api
.compute
.create_port_chain(
404 request_dict
["name"])
405 port_chain
.port_pair_groups
= request_dict
["port_pair_groups"]
406 if "description" in request_dict
:
407 port_chain
.description
= request_dict
["description"]
408 if "flow_classifiers" in request_dict
:
409 port_chain
.flow_classifiers
= request_dict
["flow_classifiers"]
410 if "chain_parameters" in request_dict
:
411 port_chain
.chain_parameters
= request_dict
["chain_parameters"]
413 port_chain
.install(self
.api
.compute
)
416 "port_chain": port_chain
.create_dict(self
.api
.compute
)
418 return Response(json
.dumps(resp
), status
=201,
419 mimetype
='application/json')
420 except Exception as ex
:
421 logging
.exception("Neutron SFC: %s Exception." %
422 str(self
.__class
__.__name
__))
423 return Response(ex
.message
, status
=500,
424 mimetype
='application/json')
427 class PortChainUpdate(SFC
):
428 def put(self
, chain_id
):
429 logging
.debug("API CALL: %s PUT" % str(self
.__class
__.__name
__))
430 request_dict
= json
.loads(request
.data
).get("port_chain")
432 port_chain
= self
.api
.compute
.find_port_chain_by_name_or_id(chain_id
)
433 if "name" in request_dict
:
434 port_chain
.name
= request_dict
["name"]
435 if "description" in request_dict
:
436 port_chain
.description
= request_dict
["description"]
437 if "flow_classfiers" in request_dict
:
438 # TODO: update chain implementation
439 port_chain
.description
= request_dict
["flow_classifiers"]
440 if "no_flow_classfiers" in request_dict
:
441 port_chain
.description
= []
442 if "port_pair_groups" in request_dict
:
443 # TODO: update chain implementation
444 port_chain
.port_pair_groups
= request_dict
["port_pair_groups"]
449 "port_chain": port_chain
.create_dict(self
.api
.compute
)
451 return Response(json
.dumps(resp
), status
=200,
452 mimetype
='application/json')
453 except Exception as ex
:
454 logging
.exception("Neutron SFC: %s Exception." %
455 str(self
.__class
__.__name
__))
456 return Response(ex
.message
, status
=500,
457 mimetype
='application/json')
460 class PortChainDelete(SFC
):
461 def delete(self
, chain_id
):
462 logging
.debug("API CALL: %s DELETE" % str(self
.__class
__.__name
__))
464 self
.api
.compute
.delete_port_chain(chain_id
)
466 return Response("", status
=204,
467 mimetype
='application/json')
468 except Exception as ex
:
469 logging
.exception("Neutron SFC: %s Exception." %
470 str(self
.__class
__.__name
__))
471 return Response(ex
.message
, status
=500,
472 mimetype
='application/json')
475 class PortChainList(SFC
):
477 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
480 for port_chain
in self
.api
.compute
.port_chains
.values():
481 port_chain_list
.append(
482 port_chain
.create_dict(self
.api
.compute
))
483 resp
= {"port_chains": port_chain_list
}
485 return Response(json
.dumps(resp
), status
=200,
486 mimetype
='application/json')
487 except Exception as ex
:
488 logging
.exception("Neutron SFC: %s Exception." %
489 str(self
.__class
__.__name
__))
490 return Response(ex
.message
, status
=500,
491 mimetype
='application/json')
494 class PortChainShow(SFC
):
495 def get(self
, chain_id
):
496 logging
.debug("API CALL: %s GET" % str(self
.__class
__.__name
__))
499 port_chain
= self
.api
.compute
.find_port_chain_by_name_or_id(
502 "port_chain": port_chain
.create_dict(self
.api
.compute
)
504 return Response(json
.dumps(resp
), status
=200,
505 mimetype
='application/json')
506 except Exception as ex
:
507 logging
.exception("Neutron SFC: %s Exception." %
508 str(self
.__class
__.__name
__))
509 return Response(ex
.message
, status
=500,
510 mimetype
='application/json')