blob: e8c6b9a81598d66e86346e9ec350851361f3b8b7 [file] [log] [blame]
peusterm72f09882018-05-15 17:10:27 +02001# Copyright (c) 2015 SONATA-NFV and Paderborn University
2# ALL RIGHTS RESERVED.
3#
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
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
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.
15#
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
19# permission.
20#
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#
27# Distributed Cloud Emulator (dcemulator)
28# Networking and monitoring functions
29# (c) 2015 by Steven Van Rossem <steven.vanrossem@intec.ugent.be>
stevenvanrossem73efd192016-06-29 01:44:07 +020030import logging
31from flask_restful import Resource
32from flask import request
stevenvanrossemf3712012017-05-04 00:01:52 +020033import networkx
stevenvanrossem73efd192016-06-29 01:44:07 +020034
peusterm5b428742017-06-16 10:08:11 +020035logging.basicConfig()
stevenvanrossem73efd192016-06-29 01:44:07 +020036
peustermdfc14602017-01-13 08:22:45 +010037CORS_HEADER = {'Access-Control-Allow-Origin': '*'}
38
peusterm72f09882018-05-15 17:10:27 +020039# the global net is set from the topology file, and connected via
40# connectDCNetwork function in rest_api_endpoint.py
stevenvanrossem73efd192016-06-29 01:44:07 +020041net = None
42
43
44class NetworkAction(Resource):
45 """
46 Add or remove chains between VNFs. These chain links are implemented as flow entries in the networks' SDN switches.
47 :param vnf_src_name: VNF name of the source of the link
48 :param vnf_dst_name: VNF name of the destination of the link
49 :param vnf_src_interface: VNF interface name of the source of the link
50 :param vnf_dst_interface: VNF interface name of the destination of the link
51 :param weight: weight of the link (can be useful for routing calculations)
52 :param match: OpenFlow match format of the flow entry
53 :param bidirectional: boolean value if the link needs to be implemented from src to dst and back
54 :param cookie: cookie value, identifier of the flow entry to be installed.
stevenvanrossem65819b82016-08-05 18:21:47 +020055 :param priority: integer indicating the priority of the flow entry
stevenvanrossembf1754e2016-11-17 10:20:52 +010056 :param skip_vlan_tag: boolean to indicate whether a new vlan tag should be created for this chain
57 :param monitor: boolean to indicate whether a new vlan tag should be created for this chain
58 :param monitor_placement: 'tx'=place the monitoring flowrule at the beginning of the chain, 'rx'=place at the end of the chain
stevenvanrossem73efd192016-06-29 01:44:07 +020059 :return: message string indicating if the chain action is succesful or not
60 """
61
62 global net
63
stevenvanrossem3c544ac2017-02-08 12:11:07 +010064 def put(self):
stevenvanrossem73efd192016-06-29 01:44:07 +020065 logging.debug("REST CALL: network chain add")
66 command = 'add-flow'
stevenvanrossem3c544ac2017-02-08 12:11:07 +010067 return self._NetworkAction(command=command)
stevenvanrossem73efd192016-06-29 01:44:07 +020068
stevenvanrossem3c544ac2017-02-08 12:11:07 +010069 def delete(self):
stevenvanrossem73efd192016-06-29 01:44:07 +020070 logging.debug("REST CALL: network chain remove")
71 command = 'del-flows'
stevenvanrossem3c544ac2017-02-08 12:11:07 +010072 return self._NetworkAction(command=command)
stevenvanrossem73efd192016-06-29 01:44:07 +020073
stevenvanrossem3c544ac2017-02-08 12:11:07 +010074 def _NetworkAction(self, command=None):
stevenvanrossem73efd192016-06-29 01:44:07 +020075 # call DCNetwork method, not really datacenter specific API for now...
76 # no check if vnfs are really connected to this datacenter...
77 try:
stevenvanrossem284ba2b2017-06-01 16:17:51 +020078 # check json payload
stevenvanrossem167aa3c2017-06-01 16:45:42 +020079 logging.debug("json: {}".format(request.json))
80 logging.debug("args: {}".format(request.args))
stevenvanrossem284ba2b2017-06-01 16:17:51 +020081
stevenvanrossemf693a3b2017-06-01 15:15:59 +020082 data = request.json
stevenvanrossem1027edc2016-07-14 22:02:02 +020083 if data is None:
stevenvanrossem1085e7e2017-06-01 16:37:52 +020084 data = request.args
85 if data is None:
stevenvanrossem1027edc2016-07-14 22:02:02 +020086 data = {}
stevenvanrossemff6b4042016-07-14 20:51:37 +020087
stevenvanrossem3c544ac2017-02-08 12:11:07 +010088 vnf_src_name = data.get("vnf_src_name")
89 vnf_dst_name = data.get("vnf_dst_name")
stevenvanrossemff6b4042016-07-14 20:51:37 +020090 vnf_src_interface = data.get("vnf_src_interface")
91 vnf_dst_interface = data.get("vnf_dst_interface")
92 weight = data.get("weight")
93 match = data.get("match")
94 bidirectional = data.get("bidirectional")
95 cookie = data.get("cookie")
stevenvanrossem61699eb2016-08-05 15:57:59 +020096 priority = data.get("priority")
stevenvanrossembecc7c52016-11-07 05:52:01 +010097 skip_vlan_tag = data.get("skip_vlan_tag")
98 monitor = data.get("monitor")
99 monitor_placement = data.get("monitor_placement")
100
stevenvanrossem73efd192016-06-29 01:44:07 +0200101 c = net.setChain(
102 vnf_src_name, vnf_dst_name,
103 vnf_src_interface=vnf_src_interface,
104 vnf_dst_interface=vnf_dst_interface,
105 cmd=command,
106 weight=weight,
107 match=match,
108 bidirectional=bidirectional,
stevenvanrossem61699eb2016-08-05 15:57:59 +0200109 cookie=cookie,
stevenvanrossembecc7c52016-11-07 05:52:01 +0100110 priority=priority,
111 skip_vlan_tag=skip_vlan_tag,
112 monitor=monitor,
113 monitor_placement=monitor_placement)
stevenvanrossem73efd192016-06-29 01:44:07 +0200114 # return setChain response
peustermdfc14602017-01-13 08:22:45 +0100115 return str(c), 200, CORS_HEADER
stevenvanrossem73efd192016-06-29 01:44:07 +0200116 except Exception as ex:
117 logging.exception("API error.")
peustermdfc14602017-01-13 08:22:45 +0100118 return ex.message, 500, CORS_HEADER
stevenvanrossemba51a812017-04-23 01:22:59 +0200119
120
121class DrawD3jsgraph(Resource):
122
123 global net
124
125 def get(self):
126 nodes = list()
127 nodes2 = list()
128 links = list()
129 # add all DCs
stevenvanrossemf3712012017-05-04 00:01:52 +0200130 node_attr = networkx.get_node_attributes(net.DCNetwork_graph, 'type')
stevenvanrossemba51a812017-04-23 01:22:59 +0200131 for node_name in net.DCNetwork_graph.nodes():
132 nodes2.append(node_name)
stevenvanrossemf3712012017-05-04 00:01:52 +0200133 type = node_attr[node_name]
peusterm72f09882018-05-15 17:10:27 +0200134 node_dict = {"name": node_name, "group": type}
stevenvanrossemba51a812017-04-23 01:22:59 +0200135 nodes.append(node_dict)
136
137 # add links between other DCs
138 for node1_name in net.DCNetwork_graph.nodes():
139 node1_index = nodes2.index(node1_name)
140 for node2_name in net.DCNetwork_graph.neighbors(node1_name):
141 node2_index = nodes2.index(node2_name)
peusterm72f09882018-05-15 17:10:27 +0200142 edge_dict = {"source": node1_index,
143 "target": node2_index, "value": 10}
stevenvanrossemba51a812017-04-23 01:22:59 +0200144 links.append(edge_dict)
145
peusterm72f09882018-05-15 17:10:27 +0200146 json = {"nodes": nodes, "links": links}
peusterm5b428742017-06-16 10:08:11 +0200147 return json, 200, CORS_HEADER