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).
27 # Distributed Cloud Emulator (dcemulator)
28 # Networking and monitoring functions
29 # (c) 2015 by Steven Van Rossem <steven.vanrossem@intec.ugent.be>
31 from flask_restful
import Resource
32 from flask
import request
36 CORS_HEADER
= {'Access-Control-Allow-Origin': '*'}
41 class MonitorInterfaceAction(Resource
):
43 Monitor the counters of a VNF interface
44 :param vnf_name: name of the VNF to be monitored
45 :param vnf_interface: name of the VNF interface to be monitored
46 :param metric: tx_bytes, rx_bytes, tx_packets, rx_packets
47 :return: message string indicating if the monitor action is succesful or not
52 logging
.debug("REST CALL: start monitor VNF interface")
57 vnf_name
= data
.get("vnf_name")
58 vnf_interface
= data
.get("vnf_interface", None)
59 metric
= data
.get("metric", 'tx_packets')
60 cookie
= data
.get("cookie")
64 c
= net
.monitor_agent
.setup_flow(
65 vnf_name
, vnf_interface
, metric
, cookie
)
67 c
= net
.monitor_agent
.setup_metric(
68 vnf_name
, vnf_interface
, metric
)
69 # return monitor message response
70 return str(c
), 200, CORS_HEADER
71 except Exception as ex
:
72 logging
.exception("API error.")
73 return ex
.message
, 500, CORS_HEADER
76 logging
.debug("REST CALL: stop monitor VNF interface")
81 vnf_name
= data
.get("vnf_name")
82 vnf_interface
= data
.get("vnf_interface", None)
83 metric
= data
.get("metric", 'tx_packets')
84 cookie
= data
.get("cookie")
88 c
= net
.monitor_agent
.stop_flow(
89 vnf_name
, vnf_interface
, metric
, cookie
)
91 c
= net
.monitor_agent
.stop_metric(
92 vnf_name
, vnf_interface
, metric
)
93 # return monitor message response
94 return str(c
), 200, CORS_HEADER
95 except Exception as ex
:
96 logging
.exception("API error.")
97 return ex
.message
, 500, CORS_HEADER
100 class MonitorFlowAction(Resource
):
102 Monitor the counters of a specific flow
103 :param vnf_name: name of the VNF to be monitored
104 :param vnf_interface: name of the VNF interface to be monitored
105 :param metric: tx_bytes, rx_bytes, tx_packets, rx_packets
106 :param cookie: specific identifier of flows to monitor
107 :return: message string indicating if the monitor action is succesful or not
112 logging
.debug("REST CALL: start monitor VNF interface")
117 vnf_name
= data
.get("vnf_name")
118 vnf_interface
= data
.get("vnf_interface", None)
119 metric
= data
.get("metric", 'tx_packets')
120 cookie
= data
.get("cookie", 0)
123 c
= net
.monitor_agent
.setup_flow(
124 vnf_name
, vnf_interface
, metric
, cookie
)
125 # return monitor message response
126 return str(c
), 200, CORS_HEADER
127 except Exception as ex
:
128 logging
.exception("API error.")
129 return ex
.message
, 500, CORS_HEADER
132 logging
.debug("REST CALL: stop monitor VNF interface")
137 vnf_name
= data
.get("vnf_name")
138 vnf_interface
= data
.get("vnf_interface", None)
139 metric
= data
.get("metric", 'tx_packets')
140 cookie
= data
.get("cookie", 0)
143 c
= net
.monitor_agent
.stop_flow(
144 vnf_name
, vnf_interface
, metric
, cookie
)
145 # return monitor message response
146 return str(c
), 200, CORS_HEADER
147 except Exception as ex
:
148 logging
.exception("API error.")
149 return ex
.message
, 500, CORS_HEADER
152 class MonitorLinkAction(Resource
):
154 Add or remove flow monitoring on chains between VNFs.
155 These chain links are implemented as flow entries in the networks' SDN switches.
156 The monitoring is an extra flow entry on top of the existing chain, with a specific match. (preserving the chaining)
157 The counters of this new monitoring flow are exported
158 :param vnf_src_name: VNF name of the source of the link
159 :param vnf_dst_name: VNF name of the destination of the link
160 :param vnf_src_interface: VNF interface name of the source of the link
161 :param vnf_dst_interface: VNF interface name of the destination of the link
162 :param weight: weight of the link (can be useful for routing calculations)
163 :param match: OpenFlow match format of the flow entry
164 :param bidirectional: boolean value if the link needs to be implemented from src to dst and back
165 :param cookie: cookie value, identifier of the flow entry to be installed.
166 :param priority: integer indicating the priority of the flow entry
167 :param skip_vlan_tag: boolean to indicate whether a new vlan tag should be created for this chain
168 :param monitor: boolean to indicate whether a new vlan tag should be created for this chain
169 :param monitor_placement: 'tx'=place the monitoring flowrule at the beginning of the chain, 'rx'=place at the end of the chain
170 :param metric: tx_packet_rate, tx_byte_rate, rx_packet_rate, rx_byte_rate
171 :return: message string indicating if the chain action is succesful or not
174 # the global net is set from the topology file, and connected via
175 # connectDCNetwork function in rest_api_endpoint.py
179 logging
.debug("REST CALL: monitor link flow add")
183 return self
._MonitorLinkAction
(command
=command
)
184 except Exception as ex
:
185 logging
.exception("API error.")
186 return ex
.message
, 500, CORS_HEADER
189 logging
.debug("REST CALL: monitor link flow remove")
192 command
= 'del-flows'
193 return self
._MonitorLinkAction
(command
=command
)
194 except Exception as ex
:
195 logging
.exception("API error.")
196 return ex
.message
, 500, CORS_HEADER
198 def _MonitorLinkAction(self
, command
=None):
199 # call DCNetwork method, not really datacenter specific API for now...
200 # no check if vnfs are really connected to this datacenter...
204 logging
.debug("json: {}".format(request
.json
))
205 logging
.debug("args: {}".format(request
.args
))
213 vnf_src_name
= data
.get("vnf_src_name")
214 vnf_dst_name
= data
.get("vnf_dst_name")
215 vnf_src_interface
= data
.get("vnf_src_interface")
216 vnf_dst_interface
= data
.get("vnf_dst_interface")
217 weight
= data
.get("weight")
218 match
= data
.get("match")
219 bidirectional
= data
.get("bidirectional")
220 cookie
= data
.get("cookie")
221 priority
= data
.get("priority")
222 skip_vlan_tag
= data
.get("skip_vlan_tag")
223 monitor
= data
.get("monitor")
224 monitor_placement
= data
.get("monitor_placement")
226 # first install monitor flow
228 vnf_src_name
, vnf_dst_name
,
229 vnf_src_interface
=vnf_src_interface
,
230 vnf_dst_interface
=vnf_dst_interface
,
234 bidirectional
=bidirectional
,
237 skip_vlan_tag
=skip_vlan_tag
,
239 monitor_placement
=monitor_placement
)
241 # then export monitor flow
242 metric
= data
.get("metric")
243 if 'rx' in monitor_placement
:
244 vnf_name
= vnf_dst_name
245 vnf_interface
= vnf_dst_interface
246 elif 'tx' in monitor_placement
:
247 vnf_name
= vnf_src_name
248 vnf_interface
= vnf_src_interface
250 c2
= 'command unknown'
251 if command
== 'add-flow':
252 c2
= net
.monitor_agent
.setup_flow(
253 vnf_name
, vnf_interface
, metric
, cookie
)
254 elif command
== 'del-flows':
255 c2
= net
.monitor_agent
.stop_flow(
256 vnf_name
, vnf_interface
, metric
, cookie
)
258 # return setChain response
259 return (str(c1
) + " " + str(c2
)), 200, CORS_HEADER
260 except Exception as ex
:
261 logging
.exception("API error.")
262 return ex
.message
, 500, CORS_HEADER
265 class MonitorSkewAction(Resource
):
267 Monitor the counters of a VNF interface
268 :param vnf_name: name of the VNF to be monitored
269 :param resource: the resource to be monitored (cpu, mem, ...)
270 :return: message string indicating if the monitor action is succesful or not
275 logging
.debug("REST CALL: start monitor skewness")
280 vnf_name
= data
.get("vnf_name")
281 resource_name
= data
.get("resource_name", 'cpu')
284 c
= net
.monitor_agent
.update_skewmon(
285 vnf_name
, resource_name
, action
='start')
287 # return monitor message response
288 return str(c
), 200, CORS_HEADER
289 except Exception as ex
:
290 logging
.exception("API error.")
291 return ex
.message
, 500, CORS_HEADER
294 logging
.debug("REST CALL: stop monitor skewness")
299 vnf_name
= data
.get("vnf_name")
300 resource_name
= data
.get("resource_name", 'cpu')
303 c
= net
.monitor_agent
.update_skewmon(
304 vnf_name
, resource_name
, action
='stop')
306 # return monitor message response
307 return str(c
), 200, CORS_HEADER
308 except Exception as ex
:
309 logging
.exception("API error.")
310 return ex
.message
, 500, CORS_HEADER
313 class MonitorTerminal(Resource
):
315 start a terminal for the selected VNFs
316 :param vnf_list: list of names of the VNFs to start a terminal from (all VNFs if None)
317 :return: message string indicating if the monitor action is succesful or not
326 vnf_list
= data
.get("vnf_list")
327 logging
.debug("REST CALL: start terminal for: {}".format(vnf_list
))
330 c
= net
.monitor_agent
.term(vnf_list
)
332 # return monitor message response
333 return str(c
), 200, CORS_HEADER
334 except Exception as ex
:
335 logging
.exception("API error.")
336 return ex
.message
, 500, CORS_HEADER