def _getNFFG(self, nffg_name): try: logging.debug("Trying to get the NFFG with name %s" % nffg_name) resp = requests.get(self.nffg_url % nffg_name, headers=self.headers, timeout=int(self.timeout)) except Exception as e: logging.error("Error during the get of NFFG with name %s : %s" % (nffg_name, e)) raise ConnectionException(e.message) if resp.status_code == 401: logging.info( "Authentication needed during the get of NFFG with name %s " % nffg_name) raise NotAuthenticatedException("Not authenticated") logging.debug( "The get of NFFG with name %s completed wit HTTP status %s" % (nffg_name, resp.status_code)) resp.raise_for_status() nffg_dict = json.loads(resp.text) ValidateNF_FG().validate(nffg_dict) nffg = NF_FG() nffg.parseDict(nffg_dict) return nffg
def addTemplate(self, vnf, uri): ''' Retrieve the Template of a specific VNF. It is possible that the template of a VNF is a graph, in that case that VNF will be expanded. The two graph will be connected together, accordingly to the original connection of the VNF that has been expanded. ''' logging.debug("Getting manifest: "+str(uri)+" of vnf :"+str(vnf.name)) template = self.getTemplate(uri) if template.checkExpansion() is True: logging.debug("Expanding a VNF: "+str(vnf.name)) nffg_from_template = self.getNFFGDict(template.uri) # Validate forwarding graph ValidateNF_FG().validate(nffg_from_template) internal_nffg = NF_FG() internal_nffg.parseDict(nffg_from_template) NFFG_Manager(internal_nffg).addTemplates() self.nffg.expandNode(vnf, internal_nffg) else: vnf.addTemplate(template) # Check min port and max port vnf.checkPortsAgainstTemplate()
def getNFFG(self, nffg_id): resp = requests.get(self.get_nffg_url % (nffg_id), headers=self.headers, timeout=long(self.timeout)) resp.raise_for_status() nffg_dict = json.loads(resp.text) ValidateNF_FG().validate(nffg_dict) nffg = NF_FG() nffg.parseDict(nffg_dict) logging.debug("Get NFFG completed") return nffg
def getNF_FGFromFile(self, file_name): ''' Read from file a nf-fg Returns a NF_FG Object ''' base_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0])).rpartition('/')[0] json_data=open(base_folder+"/graphs/"+file_name).read() nffg_dict = json.loads(json_data) ValidateNF_FG().validate(nffg_dict) nffg = NF_FG() nffg.parseDict(nffg_dict) return nffg
def put(self, nffg_id): """ Update a Network Functions Forwarding Graph Update a graph """ try: user_data = UserAuthentication().authenticateUserFromRESTRequest(request) nffg_dict = json.loads(request.data.decode()) ValidateNF_FG().validate(nffg_dict) nffg = NF_FG() nffg.parseDict(nffg_dict) controller = OpenstackOrchestratorController(user_data) controller.put(nffg, nffg_id) resp = Response(response=None, status=202, mimetype="application/json") return resp except wrongRequest as err: logging.exception(err) return ("Bad Request", 400) except UserTokenExpired as err: logging.exception(err) return (err.message, 401) except (unauthorizedRequest, UserNotFound) as err: if request.headers.get("X-Auth-User") is not None: logging.debug("Unauthorized access attempt from user " + request.headers.get("X-Auth-User")) logging.debug(err.message) return ("Unauthorized", 401) except NF_FGValidationError as err: logging.exception(err) return ("NF-FG Validation Error: " + err.message, 400) except requests.HTTPError as err: logging.exception(err) return (str(err), 500) except requests.ConnectionError as err: logging.exception(err) return (str(err), 500) except NoGraphFound as err: logging.exception(err) return err.message, 404 except Exception as err: logging.exception(err) return ("Contact the admin " + str(err), 500)
def getNFFG(self, nffg_id): if self.token is None: self.getToken(self.user_data) try: resp = requests.get(self.get_nffg_url % (nffg_id), headers=self.headers, timeout=int(self.timeout)) resp.raise_for_status() logging.debug(resp.text) nffg_dict = json.loads(resp.text) ValidateNF_FG().validate(nffg_dict) nffg = NF_FG() nffg.parseDict(nffg_dict) logging.debug("Get NFFG completed") return nffg except HTTPError as err: if err.response.status_code == 401: logging.debug("Token expired, getting a new one...") self.getToken(self.user_data) resp = requests.get(self.get_nffg_url % (nffg_id), headers=self.headers, timeout=int(self.timeout)) resp.raise_for_status() logging.debug(resp.text) nffg_dict = json.loads(resp.text) ValidateNF_FG().validate(nffg_dict) nffg = NF_FG() nffg.parseDict(nffg_dict) logging.debug("Get NFFG completed") return nffg else: raise err
def on_put(self, request, response): """ Take as body request the NF-FG """ try: user_data = UserAuthentication().authenticateUserFromRESTRequest(request) nffg_dict = json.load(request.stream, 'utf-8') ValidateNF_FG().validate(nffg_dict) nffg = NF_FG() nffg.parseDict(nffg_dict) controller = UpperLayerOrchestratorController(user_data) response.body = controller.put(nffg) response.status = falcon.HTTP_202 except wrongRequest as err: logging.exception(err) raise falcon.HTTPBadRequest("Bad Request", err.description) except unauthorizedRequest as err: logging.debug("Unauthorized access attempt from user "+request.get_header("X-Auth-User")) raise falcon.HTTPUnauthorized("Unauthorized", err.message) except requests.HTTPError as err: logging.exception(err) if err.response.status_code == 401: raise falcon.HTTPInternalServerError('Unauthorized.',err.message) elif err.response.status_code == 403: raise falcon.HTTPInternalServerError('Forbidden.',err.message) elif err.response.status_code == 404: raise falcon.HTTPInternalServerError('Resource Not found.',err.message) raise err except Exception as err: logging.exception(err) raise falcon.HTTPInternalServerError('Contact the admin. ', err.message)
def put(self): """ Put a graph Deploy a graph --- tags: - NF-FG parameters: - name: X-Auth-User in: header description: Username required: true type: string - name: X-Auth-Pass in: header description: Password required: true type: string - name: X-Auth-Tenant in: header description: Tenant required: true type: string - name: NF-FG in: body description: Graph to be deployed required: true schema: type: string responses: 202: description: Graph correctly deployed 401: description: Unauthorized 400: description: Bad request 500: description: Internal Error """ try: user_data = UserAuthentication().authenticateUserFromRESTRequest(request) nffg_dict = json.loads(request.data.decode()) ValidateNF_FG().validate(nffg_dict) nffg = NF_FG() nffg.parseDict(nffg_dict) controller = UpperLayerOrchestratorController(user_data, self.counter) response = controller.put(nffg) self.counter +=1 return (response, 202) except wrongRequest as err: logging.exception(err) return ("Bad Request", 400) except (unauthorizedRequest, UserNotFound) as err: if request.headers.get("X-Auth-User") is not None: logging.debug("Unauthorized access attempt from user "+request.headers.get("X-Auth-User")) logging.debug(err.message) return ("Unauthorized", 401) except NF_FGValidationError as err: logging.exception(err) return ("NF-FG Validation Error: "+ err.message, 400) except requests.HTTPError as err: logging.exception(err) return (str(err), 500) except requests.ConnectionError as err: logging.exception(err) return (str(err), 500) except VNFRepositoryError as err: return (err.message, 500) except Exception as err: logging.exception(err) return ("Contact the admin: "+ str(err), 500)
def put(self, nffg_id): """ Put a graph Deploy a graph --- tags: - NF-FG parameters: - name: nffg_id in: path description: ID of the graph type: string required: true - name: X-Auth-Token in: header description: Authentication token required: true type: string - name: NF-FG in: body description: Graph to be deployed required: true schema: type: string responses: 202: description: Graph correctly deployed 400: description: Bad request 401: description: Unauthorized 404: description: No results 406: description: Not acceptable 500: description: Internal Error """ try: userdata = UserAuthentication().authenticateUserFromRESTRequest(request) request_body = request.data.decode('utf-8') nffg_dict = json.loads(request_body, 'utf-8') ValidateNF_FG().validate(nffg_dict) nffg = NF_FG() nffg.parseDict(nffg_dict) NCDO = DO(userdata) NCDO.NFFG_Validate(nffg) NCDO.NFFG_Put(nffg) return ("Graph correctly deployed", 202) # User auth request - raised by UserAuthentication().authenticateUserFromRESTRequest except wrongRequest as err: logging.exception(err) return ("Bad Request", 400) # User auth credentials - raised by UserAuthentication().authenticateUserFromRESTRequest except unauthorizedRequest as err: if request.headers.get("X-Auth-User") is not None: logging.debug("Unauthorized access attempt from user "+request.headers.get("X-Auth-User")) logging.debug(err.message) return ("Unauthorized", 401) # User auth credentials - raised by UserAuthentication().authenticateUserFromRESTRequest except UserTokenExpired as err: logging.exception(err) return (err.message, 401) # NFFG validation - raised by json.loads() except ValueError as err: logging.exception(err) return ("ValueError", 406) # NFFG validation - raised by ValidateNF_FG().validate except NF_FGValidationError as err: logging.exception(err) return ("NF_FGValidationError", 406) # NFFG validation - raised by the class DO() except GraphError as err: logging.exception(err) return ("GraphError", 406) # Custom NFFG sub-validation - raised by DO().NFFG_Validate except NffgUselessInformations as err: logging.exception(err) return (err.message, 406) # No Results except UserNotFound as err: logging.exception(err) return ("UserNotFound", 404) except TenantNotFound as err: logging.exception(err) return ("TenantNotFound", 404) except NoResultFound as err: logging.exception(err) return ("NoResultFound", 404) except sessionNotFound as err: logging.exception(err) return ("sessionNotFound", 404) # Other errors except requests.HTTPError as err: logging.exception(err) return (str(err), 500) except Exception as err: logging.exception(err) return (str(err), 500)
Created on Nov 4, 2015 @author: fabiomignini ''' import logging from orchestrator_core.userAuthentication import UserData from orchestrator_core.controller import UpperLayerOrchestratorController from nffg_library.nffg import NF_FG from nffg_library.validator import ValidateNF_FG nffg_dict = {"forwarding-graph":{"VNFs":[{"ports":[{"id":"WAN:0"},{"id":"User:0"},{"id":"control:0","name":"Control port"}],"vnf_template":"firewall-web.json","id":"00000002","name":"firewall"},{"ports":[{"id":"inout:0"}],"vnf_template":"dhcp.json","id":"ingress-00000002","name":"DHCP server"},{"ports":[{"id":"WAN:0","name":"data-lan"},{"id":"User:0","name":"data-lan"}],"vnf_template":"nat.json","id":"egress-00000001","name":"isp-nat"},{"ports":[{"id":"L2Port:0","name":"auto-generated-port"},{"id":"L2Port:1","name":"auto-generated-port"}],"vnf_template":"switch.json","id":"524ecb7cccd441cc87546afc07e6bb3e","name":"Control_Switch"},{"ports":[{"id":"L2Port:0","name":"auto-generated-port"},{"id":"L2Port:1","name":"auto-generated-port"},{"id":"L2Port:2","name":"auto-generated-port"}],"vnf_template":"switch.json","id":"f82a748fa9004084a0cb052707b692d3","name":"Switch"}],"end-points":[{"interface":{"node":"130.192.225.193","interface":"to-br-usr"},"type":"interface","id":"00000001","name":"INGRESS"},{"remote_endpoint_id":"isp-00000001:00000001","type":"internal","id":"00000002","name":"ISP_CONNECTION"},{"remote_endpoint_id":"isp-00000001:9941e6c1ac134dae9113ac93b8d613b2","type":"internal","id":"c29d730b2f49432e82b5d6cbae14923b","name":"USER_CONTROL_EGRESS"}],"big-switch":{"flow-rules":[{"priority":1,"actions":[{"output":"vnf:f82a748fa9004084a0cb052707b692d3:L2Port:2"}],"id":"000000003","match":{"port_in":"vnf:00000002:User:0"}},{"priority":1,"actions":[{"output":"vnf:00000002:User:0"}],"id":"000000004","match":{"port_in":"vnf:f82a748fa9004084a0cb052707b692d3:L2Port:2"}},{"priority":1,"actions":[{"output":"vnf:f82a748fa9004084a0cb052707b692d3:L2Port:0"}],"id":"3bca88b673f64d5ba4013e2091c1890a","match":{"port_in":"endpoint:00000001"}},{"priority":1,"actions":[{"output":"endpoint:00000001"}],"id":"a083f9361dea40128e59d955f77faf58","match":{"port_in":"vnf:f82a748fa9004084a0cb052707b692d3:L2Port:0"}},{"priority":1,"actions":[{"output":"vnf:f82a748fa9004084a0cb052707b692d3:L2Port:1"}],"id":"83a3a89fcf674d14b63047cb6c1f7396","match":{"port_in":"vnf:ingress-00000002:inout:0"}},{"priority":1,"actions":[{"output":"vnf:ingress-00000002:inout:0"}],"id":"d76f978f6f934437b959982ec6ca7a03","match":{"port_in":"vnf:f82a748fa9004084a0cb052707b692d3:L2Port:1"}},{"priority":1,"actions":[{"output":"vnf:00000002:WAN:0"}],"id":"31259c06b6a2434993add836751c2246","match":{"port_in":"vnf:egress-00000001:User:0"}},{"priority":1,"actions":[{"output":"vnf:egress-00000001:User:0"}],"id":"88ea94d3afdc4f81a80aca4c618be2d9","match":{"port_in":"vnf:00000002:WAN:0"}},{"priority":1,"actions":[{"output":"vnf:egress-00000001:WAN:0"}],"id":"a234b7c167ba47b9b26ec7b78f67ba10","match":{"port_in":"endpoint:00000002"}},{"priority":1,"actions":[{"output":"endpoint:00000002"}],"id":"90f372fcdeba40acadd40f85b69eefd8","match":{"port_in":"vnf:egress-00000001:WAN:0"}},{"priority":200,"actions":[{"output":"vnf:524ecb7cccd441cc87546afc07e6bb3e:L2Port:0"}],"id":"b2ff3dbddb724561b46a43733eddfa62","match":{"port_in":"endpoint:c29d730b2f49432e82b5d6cbae14923b"}},{"priority":200,"actions":[{"output":"endpoint:c29d730b2f49432e82b5d6cbae14923b"}],"id":"1d7173b189b64c1d841bce0bdc76a05c","match":{"port_in":"vnf:524ecb7cccd441cc87546afc07e6bb3e:L2Port:0"}},{"priority":200,"actions":[{"output":"vnf:524ecb7cccd441cc87546afc07e6bb3e:L2Port:1"}],"id":"c3501d4a67ad49ffa839898b6e061ab3","match":{"port_in":"vnf:00000002:control:0"}},{"priority":200,"actions":[{"output":"vnf:00000002:control:0"}],"id":"1e7a09b9faef49959cd992cb588cea23","match":{"port_in":"vnf:524ecb7cccd441cc87546afc07e6bb3e:L2Port:1"}}]},"id":"00000001","name":"Protected access to the internet"}} username = '******' password = '******' tenant = 'demo2' logging.basicConfig(level=logging.DEBUG) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) sqlalchemy_log = logging.getLogger('sqlalchemy.engine') sqlalchemy_log.setLevel(logging.WARNING) ValidateNF_FG().validate(nffg_dict) nffg = NF_FG() nffg.parseDict(nffg_dict) controller = UpperLayerOrchestratorController(user_data=UserData(username, password, tenant)) controller.put(nffg) print 'Job completed' exit()
def getNFFG(self, session_id): session = get_session() session_ref = session.query(GraphSessionModel).filter_by(session_id=session_id).one() # [ NF-FG ] nffg = NF_FG() nffg.id = session_ref.graph_id nffg.name = session_ref.graph_name nffg.description = session_ref.description # [ ENDPOINTs ] end_points_ref = session.query(EndpointModel).filter_by(session_id=session_id).all() for end_point_ref in end_points_ref: # Add endpoint to NFFG end_point = EndPoint(_id=end_point_ref.graph_endpoint_id, name=end_point_ref.name, _type=end_point_ref.type, db_id=end_point_ref.id) nffg.addEndPoint(end_point) # End_point resource end_point_resorces_ref = session.query(EndpointResourceModel).filter_by(endpoint_id=end_point_ref.id).all() for end_point_resorce_ref in end_point_resorces_ref: if end_point_resorce_ref.resource_type == 'port': try: port_ref = session.query(PortModel).filter_by(id=end_point_resorce_ref.resource_id).one() except NoResultFound: port_ref = None logging.debug("Port not found for endpoint "+end_point_ref.graph_endpoint_id) if port_ref is not None: end_point.switch_id = port_ref.switch_id end_point.interface = port_ref.graph_port_id end_point.vlan_id = port_ref.vlan_id # [ FLOW RULEs ] flow_rules_ref = session.query(FlowRuleModel).filter_by(session_id=session_id).all() for flow_rule_ref in flow_rules_ref: if flow_rule_ref.type is not None: # None or 'external' continue # Add flow rule to NFFG flow_rule = FlowRule(_id=flow_rule_ref.graph_flow_rule_id, internal_id=flow_rule_ref.internal_id, priority=int(flow_rule_ref.priority), description=flow_rule_ref.description, db_id=flow_rule_ref.id) nffg.addFlowRule(flow_rule) # [ MATCH ] try: match_ref = session.query(MatchModel).filter_by(flow_rule_id=flow_rule_ref.id).one() except NoResultFound: match_ref = None logging.debug("Found flowrule without a match") if match_ref is not None: # Retrieve endpoint data port_in = None if match_ref.port_in_type == 'endpoint': end_point_ref = session.query(EndpointModel).filter_by(id=match_ref.port_in).first() port_in = 'endpoint:'+end_point_ref.graph_endpoint_id # Add match to this flow rule match = Match(port_in=port_in, ether_type=match_ref.ether_type, vlan_id=match_ref.vlan_id, vlan_priority=match_ref.vlan_priority, source_mac=match_ref.source_mac, dest_mac=match_ref.dest_mac, source_ip=match_ref.source_ip, dest_ip=match_ref.dest_ip, tos_bits=match_ref.tos_bits, source_port=match_ref.source_port, dest_port=match_ref.dest_port, protocol=match_ref.protocol, db_id=match_ref.id) flow_rule.match = match # [ ACTIONs ] actions_ref = session.query(ActionModel).filter_by(flow_rule_id=flow_rule_ref.id).all() if len(actions_ref)==0: logging.debug("Found flowrule without actions") for action_ref in actions_ref: output_to_port = None # Retrieve endpoint data if action_ref.output_type == 'endpoint': end_point_ref = session.query(EndpointModel).filter_by(id = action_ref.output_to_port).first() output_to_port = action_ref.output_type+':'+end_point_ref.graph_endpoint_id # Add action to this flow rule action = Action(output=output_to_port, controller=action_ref.output_to_controller, drop=action_ref._drop, set_vlan_id=action_ref.set_vlan_id, set_vlan_priority=action_ref.set_vlan_priority, push_vlan=action_ref.push_vlan, pop_vlan=action_ref.pop_vlan, set_ethernet_src_address=action_ref.set_ethernet_src_address, set_ethernet_dst_address=action_ref.set_ethernet_dst_address, set_ip_src_address=action_ref.set_ip_src_address, set_ip_dst_address=action_ref.set_ip_dst_address, set_ip_tos=action_ref.set_ip_tos, set_l4_src_port=action_ref.set_l4_src_port, set_l4_dst_port=action_ref.set_l4_dst_port, output_to_queue=action_ref.output_to_queue, db_id=action_ref.id) flow_rule.actions.append(action) return nffg
''' Created on Oct 26, 2015 @author: fabiomignini ''' from nffg_library.nffg import NF_FG nffg_dict_1 = {"forwarding-graph":{"id":"00000001","name":"Protected access to the internet","VNFs":[{"vnf_template":"switch.json","id":"00000001","name":"switch-data","ports":[{"id":"L2Port:0","name":"data-lan"},{"id":"L2Port:1","name":"data-lan"},{"id":"L2Port:2","name":"data-lan"}],"groups":["isp-function"]},{"vnf_template":"dhcp.json","ports":[{"id":"inout:0","name":"data-port"}],"name":"dhcp","id":"00000002","groups":["isp-function"]},{"vnf_template":"cisco_firewall.json","ports":[{"id":"WAN:0"},{"id":"User:0"}],"name":"firewall","id":"00000003"},{"vnf_template":"nat.json","ports":[{"id":"WAN:0"},{"id":"User:0"}],"name":"router-nat","id":"00000004","groups":["isp-function"]}],"end-points":[{"id":"00000001","name":"ingress","type":"interface","interface":{"node":"130.192.225.193","interface":"to-br-usr"}},{"id":"00000002","name":"egress","type":"interface-out","interface-out":{"node":"130.192.225.193","interface":"eth2"}}],"big-switch":{"flow-rules":[{"id":"000000001","priority":1,"match":{"port_in":"endpoint:00000001"},"actions":[{"output":"vnf:00000001:L2Port:0"}]},{"id":"000000002","priority":1,"match":{"port_in":"vnf:00000001:L2Port:0"},"actions":[{"output":"endpoint:00000001"}]},{"id":"000000003","priority":1,"match":{"port_in":"vnf:00000002:inout:0"},"actions":[{"output":"vnf:00000001:L2Port:1"}]},{"id":"000000004","priority":1,"match":{"port_in":"vnf:00000001:L2Port:1"},"actions":[{"output":"vnf:00000002:inout:0"}]},{"id":"000000005","priority":1,"match":{"port_in":"vnf:00000003:User:0"},"actions":[{"output":"vnf:00000001:L2Port:2"}]},{"id":"000000006","priority":1,"match":{"port_in":"vnf:00000001:L2Port:2"},"actions":[{"output":"vnf:00000003:User:0"}]},{"id":"000000007","priority":1,"match":{"port_in":"vnf:00000003:WAN:0"},"actions":[{"output":"vnf:00000004:User:0"}]},{"id":"000000008","priority":1,"match":{"port_in":"vnf:00000004:User:0"},"actions":[{"output":"vnf:00000003:WAN:0"}]},{"id":"000000009","priority":1,"match":{"port_in":"endpoint:00000002"},"actions":[{"output":"vnf:00000004:WAN:0"}]},{"id":"000000010","priority":1,"match":{"port_in":"vnf:00000004:WAN:0"},"actions":[{"output":"endpoint:00000002"}]}]}}} nffg_dict_2 = {"forwarding-graph":{"VNFs":[{"ports":[{"id":"L2Port:0","name":"data-lan"},{"id":"L2Port:1","name":"data-lan"},{"id":"L2Port:2","name":"data-lan"},{"id":"L2Port:3","name":"data-lan"}],"vnf_template":"switch.json","id":"00000001","groups":["isp-function"],"name":"switch-data"},{"ports":[{"id":"inout:0","name":"data-port"}],"vnf_template":"dhcp.json","id":"00000002","groups":["isp-function"],"name":"dhcp"},{"ports":[{"id":"inout:0","name":"data-port"}],"vnf_template":"dhcp.json","id":"00000005","groups":["isp-function"],"name":"dhcp"},{"ports":[{"id":"L2Port:0"},{"id":"L2Port:1"}],"vnf_template":"switch.json","id":"00000006","name":"firewall"},{"ports":[{"id":"User:0"}],"vnf_template":"nat.json","id":"00000004","groups":["isp-function"],"name":"router-nat"}],"end-points":[{"interface":{"node":"130.192.225.193","interface":"to-br-usr"},"type":"interface","id":"00000001","name":"ingress"}],"big-switch":{"flow-rules":[{"priority":1,"actions":[{"output":"vnf:00000001:L2Port:0"}],"id":"000000001","match":{"port_in":"endpoint:00000001"}},{"priority":1,"actions":[{"output":"endpoint:00000001"}],"id":"000000002","match":{"port_in":"vnf:00000001:L2Port:0"}},{"priority":1,"actions":[{"output":"vnf:00000001:L2Port:1"}],"id":"000000003","match":{"port_in":"vnf:00000002:inout:0"}},{"priority":1,"actions":[{"output":"vnf:00000002:inout:0"}],"id":"000000004","match":{"port_in":"vnf:00000001:L2Port:1"}},{"priority":1,"actions":[{"output":"vnf:00000001:L2Port:2"}],"id":"000000005","match":{"port_in":"vnf:00000006:L2Port:0"}},{"priority":1,"actions":[{"output":"vnf:00000006:L2Port:0"}],"id":"000000006","match":{"port_in":"vnf:00000001:L2Port:2"}},{"priority":1,"actions":[{"output":"vnf:00000004:User:0"}],"id":"000000007","match":{"port_in":"vnf:00000006:L2Port:1"}},{"priority":1,"actions":[{"output":"vnf:00000006:L2Port:1"}],"id":"000000008","match":{"port_in":"vnf:00000004:User:0"}},{"priority":1,"actions":[{"output":"vnf:00000001:L2Port:3"}],"id":"000000011","match":{"port_in":"vnf:00000005:inout:0"}},{"priority":1,"actions":[{"output":"vnf:00000005:inout:0"}],"id":"000000012","match":{"port_in":"vnf:00000001:L2Port:3"}}]},"id":"00000001","name":"Protected access to the internet"}} nffg_1 = NF_FG() nffg_1.parseDict(nffg_dict_1) nffg_2 = NF_FG() nffg_2.parseDict(nffg_dict_2) nffg_diff = nffg_1.diff(nffg_2) print(nffg_diff.getDict(True))
def analyzeLinksOLD(self, graph, nf_fg, vnf, port, flowrule, counter_id, update = None): nf_fg_obj = NF_FG(copy.deepcopy(nf_fg)) # Action != output not supported now if flowrule["action"]["type"] == "output": # IF ingress --> we have to set the ingress port with the actual port where the user is connected if "VNF" not in flowrule["action"]: if nf_fg_obj.getEndpointMap()[flowrule["action"]["endpoint"]["id"]].port is not None and nf_fg_obj.getEndpointMap()[flowrule["action"]["endpoint"]["id"]].port.find(":") != -1: # External endpoint action = {"endpoint_id": nf_fg_obj.getEndpointMap()[flowrule["action"]["endpoint"]["id"]].port} elif 'id' in flowrule["action"]["endpoint"] and nf_fg_obj.getEndpointMap()[flowrule["action"]["endpoint"]["id"]].type == "physical": # Endpoint Characterized action = {"port": nf_fg_obj.getEndpointMap()[flowrule["action"]["endpoint"]["id"]].interface} else: endpoint = nf_fg['profile']['id']+":"+ str(flowrule["action"]["endpoint"]["id"]) action = {"endpoint_id": endpoint} else: # Normal flowrule translation port_id = int(self.VNFs[flowrule["action"]["VNF"]["id"]].ports_label[flowrule["action"]["VNF"]["port"].split(":")[0]]) + int(flowrule["action"]["VNF"]["port"].split(":")[1]) action = {"VNF_id": self.VNFs_name[flowrule["action"]["VNF"]["id"]] + ":" + str(port_id+1)} if "ingress_endpoint" in flowrule["flowspec"]: physical_port = False if nf_fg_obj.getEndpointMap()[flowrule["flowspec"]["ingress_endpoint"]].port is not None and nf_fg_obj.getEndpointMap()[flowrule["flowspec"]["ingress_endpoint"]].port.find(":") != -1: # External endpoint new_port = nf_fg_obj.getEndpointMap()[flowrule["flowspec"]["ingress_endpoint"]].port elif 'ingress_endpoint' in flowrule["flowspec"] and nf_fg_obj.getEndpointMap()[flowrule["flowspec"]["ingress_endpoint"]].type == "physical": # Endpoint Characterized new_port = nf_fg_obj.getEndpointMap()[flowrule["flowspec"]["ingress_endpoint"]].interface physical_port = True else: # port = profile['session_param']["port"] #port = flowrule["flowspec"]["ingressPort"] new_port = nf_fg['profile']['id']+ ":" +flowrule["flowspec"]['ingress_endpoint'] edge = True else: port_id = int(self.VNFs[vnf["id"]].ports_label[port["id"].split(":")[0]]) + int(port["id"].split(":")[1]) new_port = self.VNFs_name[vnf["id"]] + ":" + str(port_id+1) edge = False for match in flowrule["flowspec"]["matches"]: link = {} """ if update is True: link["id"] = uuid.uuid4().hex else: link["id"] = match["id"] """ link["id"] = match["id"] link["action"] = action #link["id"] = str(counter_id) counter_id = counter_id + 1 linkMatch = {} if not edge: linkMatch["VNF_id"] = new_port else: if physical_port is True: linkMatch["port"] = new_port else: linkMatch["endpoint_id"] = new_port protocol = None sourcePort = -1 destPort = -1 for rule in match.keys(): if rule == "id" or rule == "hardTimeout" or rule == "vlanPriority" or rule == "tosBits": continue if rule == "etherType": linkMatch["ethertype"] = match[rule] elif rule == "vlanId": linkMatch["vlan_id"] = match[rule] elif rule == "sourceMAC": linkMatch["eth_src"] = match[rule] elif rule == "destMAC": linkMatch["eth_dst"] = match[rule] elif rule == "sourceIP": linkMatch["ipv4_src"] = match[rule] elif rule == "destIP": linkMatch["ipv4_dst"] = match[rule] elif rule == "protocol": protocol = match[rule] if protocol == "tcp": linkMatch["ip_proto"] = "6" if sourcePort != -1: if protocol == "tcp": linkMatch["tcp_src"] = str(sourcePort) elif protocol == "udp": linkMatch["udp_src"] = str(sourcePort) if destPort != -1: if protocol == "tcp": linkMatch["tcp_dst"] = str(destPort) elif protocol == "udp": linkMatch["udp_dst"] = str(destPort) elif rule == "sourcePort": if protocol == "tcp": linkMatch["tcp_src"] = str(match[rule]) elif protocol == "udp": linkMatch["udp_src"] = str(match[rule]) elif protocol == None: sourcePort = int(match[rule]) elif rule == "destPort": if protocol == "tcp": linkMatch["tcp_dst"] = str(match[rule]) elif protocol == "udp": linkMatch["udp_dst"] = str(match[rule]) elif protocol == None: destPort = int(match[rule]) else: # Fields that don't change will be copied without any modification linkMatch[rule] = match[rule] # Dirty workaround to remove priority from match --> to be fixed!!!! linkMatch.pop("priority") link["match"] = linkMatch link["priority"] = match["priority"] graph["flow-graph"]["flow-rules"].append(link)
def updateProfile(self, new_nf_fg, old_nf_fg, node_endpoint): ''' Compute a diff between new nf-fg and old nf-fg, then send the changes to Unified node ''' #updated_nffg = NFFG_Management().diff(old_nf_fg, new_nf_fg) updated_nffg = None logging.debug("diff: " + updated_nffg.getJSON()) # initialize data-structures for the UN-NODE graph = {} graph["flow-graph"] = {} graph["flow-graph"]["VNFs"] = [] graph["flow-graph"]["flow-rules"] = [] endpoint = Endpoint(self, copy.deepcopy(new_nf_fg)) new_nf_fg = endpoint.nf_fg self.reconciliateName(new_nf_fg, graph) nf_fg = NF_FG(copy.deepcopy(new_nf_fg)) endpoint = Endpoint(self, copy.deepcopy(old_nf_fg)) old_nf_fg = endpoint.nf_fg self.reconciliateName(old_nf_fg, graph) for vnf in new_nf_fg['profile']['VNFs']: self.VNFs[vnf["id"]] = VNFTemplate(vnf) logging.debug("Unify CA - Update - new_nf_fg : "+json.dumps(new_nf_fg)) if delete == False: logging.debug(" Unify CA - Update - new_nf_fg : FALSE") update_flows = self.computeDiff(new_nf_fg, old_nf_fg) else: logging.debug(" Unify CA - Update - new_nf_fg : TRUE") update_flows = self.computeDiff(old_nf_fg, new_nf_fg) update_flows_str = nf_fg.getIngoingFlowruleJson(update_flows) logging.debug("Unify CA - Update - flowrule : "+update_flows_str) for update_flow in update_flows: for match in update_flow.flowspec['matches']: logging.debug("Unify CA - Update - update_flows - delete flow :"+str(match._id)) Unify().deleteFlow(self.URI, nf_fg_id, match._id ) return for update_flow in update_flows: logging.debug("Unify CA - Update - update_flows - ingress endpoint :"+str(update_flow.flowspec['ingress_endpoint'])) logging.debug("Unify CA - Update - update_flows - action :"+str(self.VNFs_name[update_flow.action.vnf['id']])) for match in update_flow.matches: if 'sourceMAC' in match.of_field: logging.debug("Unify CA - Update - update_flows - match :"+str(match.of_field['sourceMAC'])) update_flows = nf_fg.getIngoingFlowruleJson(update_flows) logging.debug("Unify CA - Update - flowrule : "+update_flows) for flowrule in json.loads(update_flows): self.analyzeLinks(graph, new_nf_fg, vnf, None, flowrule, 0, True) logging.debug("Unify - updateProfile - nf-fg") # Insert list of VNFs with link modified logging.debug("\n"+json.dumps(graph)) new_vnfs = [] for flowrule in graph["flow-graph"]["flow-rules"]: # Action if "VNF_id" in flowrule["action"]: vnf = flowrule["action"]["VNF_id"].split(":")[0] find = False for new_vnf in new_vnfs: if vnf["id"] == new_vnf["id"]: find = True if find is False: new_vnfs.append(vnf) # Match if "VNF_id" in flowrule["match"]: vnf = flowrule["match"]["VNF_id"].split(":")[0] find = False for new_vnf in new_vnfs: if vnf["id"] == new_vnf["id"]: find = True if find is False: new_vnfs.append(vnf) del graph["flow-graph"]["VNFs"] graph["flow-graph"]["VNFs"] = [] for new_vnf in new_vnfs: id_vnf = {} id_vnf['id'] = new_vnf graph["flow-graph"]["VNFs"].append(id_vnf) #graph["flow-graph"]["VNFs"] = vnfs logging.debug("\n"+json.dumps(graph)) if DEBUG_MODE is not True: Unify().updateGraph(self.URI, nf_fg_id, graph)
def __init__(self): self.counter = 1 self.nffg_id = "1" self.nffg_name = "test_nffg_nat" self.tenant_id = "2" self.nat_mac = "02:01:02:03:04:05" self.nat_lan = {"ip": "192.168.10.1", "netmask": "255.255.255.0"} self.lan = u'192.168.10.0/24' self.random_str = '' + random.choice(string.ascii_uppercase + string.digits) \ + random.choice(string.ascii_uppercase + string.digits)\ + random.choice(string.ascii_uppercase + string.digits) datastore_url = "http://selforch.name29.net:8081" datastore_username = "******" datastore_password = "******" controller_url = "http://selforch.name29.net:8080" controller_username = "******" controller_password = "******" configuration_url = "http://selforch.name29.net:8082" configuration_username = "******" configuration_password = "******" self.ip_pool = IpPool() self.ip_pool.add_ip_in_pool('WAN', '192.168.11.100', '255.255.255.0') self.ip_pool.add_ip_in_pool('WAN', '192.168.11.101', '255.255.255.0') self.ip_pool.add_ip_in_pool('WAN', '192.168.11.102', '255.255.255.0') self.ip_pool.add_ip_in_pool('WAN', '192.168.11.103', '255.255.255.0') self.ip_pool.add_ip_in_pool('WAN', '192.168.11.104', '255.255.255.0') self.ip_pool.add_ip_in_pool('WAN', '192.168.11.105', '255.255.255.0') self.ip_pool.add_ip_in_pool('WAN', '192.168.11.106', '255.255.255.0') self.ip_pool.add_ip_in_pool('WAN', '192.168.11.107', '255.255.255.0') self.ip_pool.add_ip_in_pool('WAN', '192.168.11.108', '255.255.255.0') self.ip_pool.add_ip_in_pool('WAN', '192.168.11.109', '255.255.255.0') logging.debug("Service Orchestrator Starting(Log)") # start the dd client to receive information about domains # base_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile(inspect.currentframe()))[0])) # dd_client = DDClient(conf.DD_NAME, conf.BROKER_ADDRESS, conf.DD_CUSTOMER, conf.DD_KEYFILE) # thread = Thread(target=dd_client.start) # thread.start() logging.info("Connecting to the datastore") self.datastore = DatastoreClient(username=datastore_username, password=datastore_password, base_url=datastore_url) logging.info("Connecting to the configuration service") self.configuration_service = ConfigurationService(username=configuration_username, password=configuration_password, base_url=configuration_url, timeout=10) logging.info("Connecting to the infrastructure orchestrator") self.orchestrator = InfrastructureOrchestrator(username=controller_username, password=controller_password, base_url=controller_url, timeout=30000) logging.info("Removing old NFFG with name '%s' " % self.nffg_name) try: self.orchestrator.removeNFFG(self.nffg_name) except Exception: pass logging.debug("Getting template from the datastore") self.template_nat = self.datastore.getTemplate("nat") template_switch = self.datastore.getTemplate("switch") # template_orch = self.datastore.getTemplate("serviceorch") template_dhcpserver = self.datastore.getTemplate("dhcpserver") template_dhcpserver_man = self.datastore.getTemplate("dhcpserverman") logging.debug("Building the VNFs") nat_vnf =self.buildVNF(self.template_nat,"NAT"+self.random_str, "NAT"+self.random_str) dhcpserver_vnf =self.buildVNF(template_dhcpserver,"DHCPLAN", "DHCPLAN") dhcpserver_man_vnf =self.buildVNF(template_dhcpserver_man,"DHCPMAN", "DHCPMAN") self.switch_man_vnf =self.buildVNF(template_switch,"SWITCH_MAN", "SWITCH_MAN") self.switch_lan_vnf =self.buildVNF(template_switch,"SWITCH_LAN", "SWITCH_LAN") self.switch_wan_vnf =self.buildVNF(template_switch,"SWITCH_WAN", "SWITCH_WAN") # orch_vnf =self.buildVNF(template_orch,"SELFORCH","serviceorch") management_endpoint = EndPoint("MANAGEMENT_ENDPOINT", "MANAGEMENT_ENDPOINT", "host-stack", configuration="static", ipv4="192.168.40.1/24") internet_endpoint = EndPoint("INTERNET_ENDPOINT", "INTERNET_ENDPOINT", "host-stack", configuration="static", ipv4="192.168.11.1/24") logging.debug("Creating the NFFG") deploy_nffg = NF_FG(self.nffg_id, self.nffg_name) logging.debug("Adding VNF to NFFG") # deploy_nffg.addVNF(orch_vnf) deploy_nffg.addVNF(nat_vnf) deploy_nffg.addVNF(dhcpserver_vnf) deploy_nffg.addVNF(dhcpserver_man_vnf) deploy_nffg.addVNF(self.switch_man_vnf) deploy_nffg.addVNF(self.switch_lan_vnf) deploy_nffg.addVNF(self.switch_wan_vnf) deploy_nffg.addEndPoint(management_endpoint) deploy_nffg.addEndPoint(internet_endpoint) logging.debug("Creating link between VNF") # Connect SWITCH_MAN to DHCP MAN self.link_ports(deploy_nffg, "DHCP_SWITCH_MAN", "SWITCH_MAN_DHCP", dhcpserver_man_vnf.getFullnamePortByLabel("inout"), self.switch_man_vnf.getFullnamePortByLabel(self.switch_man_vnf.getFreePort(deploy_nffg, "port"))) # Connect SWITCH_LAN to DHCP self.link_ports(deploy_nffg, "DHCP_SWITCH_LAN", "SWITCH_LAN_DHCP", dhcpserver_vnf.getFullnamePortByLabel("inout"), self.switch_lan_vnf.getFullnamePortByLabel( self.switch_lan_vnf.getFreePort(deploy_nffg, "port"))) # Connect Switch_WAN to NAT self.link_ports(deploy_nffg, "NAT_SWITCH_WAN", "SWITCH_WAN_NAT", nat_vnf.getFullnamePortByLabel("WAN"), self.switch_wan_vnf.getFullnamePortByLabel(self.switch_wan_vnf.getFreePort(deploy_nffg, "port"))) # Connect Switch_WAN to INTERNET ENDPOINT self.link_ports(deploy_nffg, "INTERNET_SWITCH_WAN", "SWITCH_WAN_INTERNET", "endpoint:INTERNET_ENDPOINT", self.switch_wan_vnf.getFullnamePortByLabel(self.switch_wan_vnf.getFreePort(deploy_nffg, "port"))) # Connect Endpoint management to Switch_MAN self.link_ports(deploy_nffg, "SWITCH_MAN_ENDPOINT", "ENDPOINT_SWITCH_MAN", self.switch_man_vnf.getFullnamePortByLabel(self.switch_man_vnf.getFreePort(deploy_nffg, "port")), "endpoint:MANAGEMENT_ENDPOINT") # Connect management port of NAT to Switch_MAN self.link_ports(deploy_nffg, "SWITCH_MAN_NAT", "NAT_SWITCH_MAN", self.switch_man_vnf.getFullnamePortByLabel(self.switch_man_vnf.getFreePort(deploy_nffg, "port")), nat_vnf.getFullnamePortByLabel("management")) # Connect management port of SELFORCH to Switch_MAN # linkPorts(deploy_nffg,"SWITCH_MAN_SELFORCH","SELFORCH_SWITCH_MAN",SWITCH_MAN_vnf.getFullnamePortByLabel(SWITCH_MAN_vnf.getFreePort(deploy_nffg,"port")),orch_vnf.getFullnamePortByLabel("inout")) logging.debug("Creating LoadBalancer L2") self.load_balancer = LoadBalancerL2(nffg=deploy_nffg, mac=self.nat_mac, port_in=self.switch_lan_vnf.getFullnamePortByLabel("port2"), default_port=nat_vnf.getFullnamePortByLabel("User")) logging.info("Sending initial NFFG") try: self.orchestrator.addNFFG(deploy_nffg) except Exception as ex: logging.error("Error during the add of the NFFG with name %s" % ex) exit(1) nat_cfg = ConfigurationSDN(self.tenant_id, self.nffg_id, nat_vnf.id) logging.debug("Trying to get one ip for the WAN interface from the Pool") nat_wan = self.ip_pool.get('WAN') if nat_wan is None: logging.error("Error during the get of an ip from the pool '%s' : Pool is empty" % nat_wan) exit(1) logging.info("WAN IP For the NAT '%s' is '%s'" % (nat_vnf.id,nat_wan["ip"])) logging.debug("Configuring the nat VNF") nat_cfg.setIP(port="User", ip=self.nat_lan['ip'], netmask=self.nat_lan['netmask'], mac_address=self.nat_mac) nat_cfg.setIP(port="WAN", ip=nat_wan['ip'], netmask=nat_wan['netmask'], gateway="192.168.11.1") logging.info("Trying to put the configuration for the VNF '%s'" % nat_vnf.id) try: self.configuration_service.waitUntilStarted(self.tenant_id, self.nffg_id, nat_cfg.vnf_id) self.configuration_service.setConfiguration(nat_cfg) except Exception as ex: logging.error("Error during the put of the configuration for '%s' : '%s'" % (nat_vnf.id, ex)) exit(1) logging.debug("Configuring the NatMonitor") self.nat_monitor = NatMonitor(self.configuration_service, self.on_nat_fault, self.on_host_new, self.on_host_left) logging.debug("Adding the NAT %s in the NatMonitor" % nat_cfg.vnf_id) self.nat_monitor.addNat(self.tenant_id, self.nffg_id, nat_cfg.vnf_id) logging.info("Waiting for one host")
nffg_dict = {"forwarding-graph":{"VNFs":[{"ports":[{"id":"L2Port:0","name":"data-lan"},{"id":"L2Port:1","name":"data-lan"},{"id":"L2Port:2","name":"data-lan"}],"vnf_template":"switch.json","id":"00000001","name":"switch-data"},{"ports":[{"id":"inout:0","name":"data-port"}],"vnf_template":"isp_dhcp.json","id":"00000002","name":"dhcp-isp"},{"ports":[{"id":"inout:0"},{"id":"inout:1"},{"id":"control:0","name":"Control port"}],"vnf_template":"iptraf.json","id":"00000003","name":"iptraf-isp"},{"ports":[{"id":"User:0","name":"data-port"},{"id":"WAN:0","name":"data-port"}],"vnf_template":"isp_nat.json","id":"00000004","name":"nat-isp"},{"ports":[{"id":"L2Port:0","name":"auto-generated-port"},{"id":"L2Port:1","name":"auto-generated-port"},{"id":"L2Port:2","name":"auto-generated-port"}],"vnf_template":"switch.json","id":"b66276124280488193d5efbb9aadfb36","name":"Control_Switch"}],"end-points":[{"type":"internal","id":"00000001","name":"ISP_INGRESS"},{"interface-out":{"node":"130.192.225.193","interface":"em1"},"type":"interface-out","id":"00000002","name":"EGRESS"},{"interface-out":{"node":"130.192.225.193","interface":"em1"},"type":"interface-out","id":"810fc3dc88774973aa80c2d00639431a","name":"EGRESS"},{"type":"internal","id":"9941e6c1ac134dae9113ac93b8d613b2","name":"USER_CONTROL_INGRESS"}],"big-switch":{"flow-rules":[{"priority":1,"actions":[{"output":"vnf:00000001:L2Port:0"}],"id":"000000001","match":{"port_in":"endpoint:00000001"}},{"priority":1,"actions":[{"output":"endpoint:00000001"}],"id":"000000002","match":{"port_in":"vnf:00000001:L2Port:0"}},{"priority":1,"actions":[{"output":"vnf:00000004:WAN:0"}],"id":"000000003","match":{"port_in":"endpoint:00000002"}},{"priority":1,"actions":[{"output":"endpoint:00000002"}],"id":"000000004","match":{"port_in":"vnf:00000004:WAN:0"}},{"priority":1,"actions":[{"output":"vnf:00000002:inout:0"}],"id":"000000005","match":{"port_in":"vnf:00000001:L2Port:1"}},{"priority":1,"actions":[{"output":"vnf:00000001:L2Port:1"}],"id":"000000006","match":{"port_in":"vnf:00000002:inout:0"}},{"priority":1,"actions":[{"output":"vnf:00000003:inout:0"}],"id":"000000007","match":{"port_in":"vnf:00000001:L2Port:2"}},{"priority":1,"actions":[{"output":"vnf:00000001:L2Port:2"}],"id":"000000008","match":{"port_in":"vnf:00000003:inout:0"}},{"priority":1,"actions":[{"output":"vnf:00000004:User:0"}],"id":"000000009","match":{"port_in":"vnf:00000003:inout:1"}},{"priority":1,"actions":[{"output":"vnf:00000003:inout:1"}],"id":"000000010","match":{"port_in":"vnf:00000004:User:0"}},{"priority":200,"actions":[{"output":"vnf:b66276124280488193d5efbb9aadfb36:L2Port:0"}],"id":"9c37f6e7ff8c457aae1f6f0cedc85911","match":{"port_in":"endpoint:810fc3dc88774973aa80c2d00639431a"}},{"priority":200,"actions":[{"output":"endpoint:810fc3dc88774973aa80c2d00639431a"}],"id":"c4b4f43a862940878863f2b719d6d2a2","match":{"port_in":"vnf:b66276124280488193d5efbb9aadfb36:L2Port:0"}},{"priority":200,"actions":[{"output":"vnf:b66276124280488193d5efbb9aadfb36:L2Port:1"}],"id":"178746d675d94b9cbd1bd9186e6a9b0b","match":{"port_in":"vnf:00000003:control:0"}},{"priority":200,"actions":[{"output":"vnf:00000003:control:0"}],"id":"0e63b3aba8e24e02b4092f627a3db21f","match":{"port_in":"vnf:b66276124280488193d5efbb9aadfb36:L2Port:1"}},{"priority":200,"actions":[{"output":"vnf:b66276124280488193d5efbb9aadfb36:L2Port:2"}],"id":"503bc4eeb57b40e3a4d1d7a07463b655","match":{"port_in":"endpoint:9941e6c1ac134dae9113ac93b8d613b2"}},{"priority":200,"actions":[{"output":"endpoint:9941e6c1ac134dae9113ac93b8d613b2"}],"id":"13b506ad2c5d49c8a02c765fa2eed557","match":{"port_in":"vnf:b66276124280488193d5efbb9aadfb36:L2Port:2"}}]},"id":"isp-00000001","name":"ISP_graph"}} username = '******' password = '******' tenant = 'isp' logging.basicConfig(level=logging.DEBUG) requests_log = logging.getLogger("requests") requests_log.setLevel(logging.WARNING) sqlalchemy_log = logging.getLogger('sqlalchemy.engine') sqlalchemy_log.setLevel(logging.WARNING) ValidateNF_FG().validate(nffg_dict) old_nffg = NF_FG() old_nffg.parseDict(nffg_dict) controller = UpperLayerOrchestratorController(user_data=UserData(username, password, tenant)) controller.put(old_nffg) ''' nffg_dict2 = {"forwarding-graph":{"VNFs":[{"ports":[{"id":"L2Port:0","name":"data-lan"},{"id":"L2Port:1","name":"data-lan"},{"id":"L2Port:2","name":"data-lan"}],"vnf_template":"switch.json","id":"00000001","name":"switch-data"},{"ports":[{"id":"inout:0","name":"data-port"}],"vnf_template":"isp_dhcp.json","id":"00000002","name":"dhcp-isp"},{"ports":[{"id":"inout:0"},{"id":"inout:1"},{"id":"control:0","name":"Control port"}],"vnf_template":"iptraf.json","id":"00000003","name":"iptraf-isp"},{"ports":[{"id":"User:0","name":"data-port"},{"id":"WAN:0","name":"data-port"}],"vnf_template":"isp_nat.json","id":"00000004","name":"nat-isp"},{"ports":[{"id":"L2Port:0","name":"auto-generated-port"},{"id":"L2Port:1","name":"auto-generated-port"},{"id":"L2Port:2","name":"auto-generated-port"}],"vnf_template":"switch.json","id":"b66276124280488193d5efbb9aadfb36","name":"Control_Switch"}],"end-points":[{"type":"internal","id":"00000001","name":"ISP_INGRESS","prepare_connection_to_remote_endpoint_ids":["1:00000002"]},{"interface-out":{"node":"130.192.225.193","interface":"em1"},"type":"interface-out","id":"00000002","name":"EGRESS"},{"interface-out":{"node":"130.192.225.193","interface":"em1"},"type":"interface-out","id":"810fc3dc88774973aa80c2d00639431a","name":"EGRESS"},{"type":"internal","id":"9941e6c1ac134dae9113ac93b8d613b2","name":"USER_CONTROL_INGRESS","prepare_connection_to_remote_endpoint_ids":["1:c29d730b2f49432e82b5d6cbae14923b"]}],"big-switch":{"flow-rules":[{"priority":1,"actions":[{"output":"vnf:00000001:L2Port:0"}],"id":"000000001","match":{"port_in":"endpoint:00000001"}},{"priority":1,"actions":[{"output":"endpoint:00000001"}],"id":"000000002","match":{"port_in":"vnf:00000001:L2Port:0"}},{"priority":1,"actions":[{"output":"vnf:00000004:WAN:0"}],"id":"000000003","match":{"port_in":"endpoint:00000002"}},{"priority":1,"actions":[{"output":"endpoint:00000002"}],"id":"000000004","match":{"port_in":"vnf:00000004:WAN:0"}},{"priority":1,"actions":[{"output":"vnf:00000002:inout:0"}],"id":"000000005","match":{"port_in":"vnf:00000001:L2Port:1"}},{"priority":1,"actions":[{"output":"vnf:00000001:L2Port:1"}],"id":"000000006","match":{"port_in":"vnf:00000002:inout:0"}},{"priority":1,"actions":[{"output":"vnf:00000003:inout:0"}],"id":"000000007","match":{"port_in":"vnf:00000001:L2Port:2"}},{"priority":1,"actions":[{"output":"vnf:00000001:L2Port:2"}],"id":"000000008","match":{"port_in":"vnf:00000003:inout:0"}},{"priority":1,"actions":[{"output":"vnf:00000004:User:0"}],"id":"000000009","match":{"port_in":"vnf:00000003:inout:1"}},{"priority":1,"actions":[{"output":"vnf:00000003:inout:1"}],"id":"000000010","match":{"port_in":"vnf:00000004:User:0"}},{"priority":200,"actions":[{"output":"vnf:b66276124280488193d5efbb9aadfb36:L2Port:0"}],"id":"9c37f6e7ff8c457aae1f6f0cedc85911","match":{"port_in":"endpoint:810fc3dc88774973aa80c2d00639431a"}},{"priority":200,"actions":[{"output":"endpoint:810fc3dc88774973aa80c2d00639431a"}],"id":"c4b4f43a862940878863f2b719d6d2a2","match":{"port_in":"vnf:b66276124280488193d5efbb9aadfb36:L2Port:0"}},{"priority":200,"actions":[{"output":"vnf:b66276124280488193d5efbb9aadfb36:L2Port:1"}],"id":"178746d675d94b9cbd1bd9186e6a9b0b","match":{"port_in":"vnf:00000003:control:0"}},{"priority":200,"actions":[{"output":"vnf:00000003:control:0"}],"id":"0e63b3aba8e24e02b4092f627a3db21f","match":{"port_in":"vnf:b66276124280488193d5efbb9aadfb36:L2Port:1"}},{"priority":200,"actions":[{"output":"vnf:b66276124280488193d5efbb9aadfb36:L2Port:2"}],"id":"503bc4eeb57b40e3a4d1d7a07463b655","match":{"port_in":"endpoint:9941e6c1ac134dae9113ac93b8d613b2"}},{"priority":200,"actions":[{"output":"endpoint:9941e6c1ac134dae9113ac93b8d613b2"}],"id":"13b506ad2c5d49c8a02c765fa2eed557","match":{"port_in":"vnf:b66276124280488193d5efbb9aadfb36:L2Port:2"}}]},"id":"isp-00000001","name":"ISP_graph"}} ValidateNF_FG().validate(nffg_dict2) new_nffg = NF_FG() new_nffg.parseDict(nffg_dict2) controller = OpenStackPlusOrchestrator(graph_id = 0, userdata=UserData(username, password, tenant)) controller.updateProfile(new_nf_fg=new_nffg, old_nf_fg=old_nffg, node=Node().getNodeFromDomainID('130.192.225.193')) print Graph().get_nffg(0).getJSON()
def put(self, mac_address): # Get user network function forwarding graph service_graph_dict = json.loads(User().getServiceGraph(self.user_data.username)) nffg = NF_FG() nffg.parseDict(service_graph_dict) # Check if the user have an active session if UserSession(self.user_data.getUserID(), self.user_data).checkSession(nffg.id, self.orchestrator) is True: # Existent session for this user logging.debug('The FG for this user is already instantiated, the FG will be update if it has been modified') session = Session().get_active_user_session_by_nf_fg_id(nffg.id, error_aware=True) session_id = session.id Session().updateStatus(session_id, 'updating') # Manage new device if Session().checkDeviceSession(self.user_data.getUserID(), mac_address) is True: """ A rule for this mac address is already implemented, only an update of the graph is needed (This update is necessary only if the graph is different from the last instantiated, but in this moment the graph is always re-instantiated, will be the orchestrator accountable for a smart update of the FG). """ mac_address = None self.addDeviceToNF_FG(mac_address, nffg) # Call orchestrator to update NF-FG logging.debug('Call orchestrator sending the following NF-FG: '+nffg.getJSON()) if DEBUG_MODE is False: try: self.orchestrator.put(nffg) except: Session().set_error(session_id) if mac_address is not None: logging.debug('Added device "'+mac_address+'" of user "'+self.user_data.username+'"') print 'Added device "'+mac_address+'" of user "'+self.user_data.username+'"' else: logging.debug('User profile updated "'+self.user_data.username+'"') print 'User profile updated "'+self.user_data.username+'"' else: # New session for this user logging.debug('Instantiate profile') session_id = uuid.uuid4().hex Session().inizializeSession(session_id, self.user_data.getUserID(), nffg.id, nffg.name) # Manage profile logging.debug("User service graph: "+nffg.getJSON()) self.prepareProfile(mac_address, nffg) # Call orchestrator to instantiate NF-FG logging.debug('Calling orchestrator sending NF-FG: '+nffg.getJSON()) print nffg.getJSON() if DEBUG_MODE is False: try: self.orchestrator.put(nffg) except: Session().set_error(session_id) logging.debug('Profile instantiated for user "'+self.user_data.username+'"') print 'Profile instantiated for user "'+self.user_data.username+'"' # Set mac address in the session if mac_address is not None: Session().add_mac_address_in_the_session(mac_address, session_id) Session().updateStatus(session_id, 'complete')
from orchestrator_core.controller import UpperLayerOrchestratorController from orchestrator_core.scheduler import Scheduler from nffg_library.nffg import NF_FG from nffg_library.validator import ValidateNF_FG #in_file = open("/home/stack/Documents/LiClipse Workspace/frog4/grafo0.json","r") #in_file = open("/home/stack/Documents/LiClipse Workspace/frog4/grafo0_AR.json","r") #in_file = open("/home/stack/Documents/LiClipse Workspace/frog4/grafo1.json","r") in_file = open("/home/stack/Documents/LiClipse Workspace/frog4/grafo2.json","r") #in_file = open("/home/stack/Documents/LiClipse Workspace/frog4/grafo3_4vnf.json","r") nf_fg_file = json.loads(in_file.read()) ValidateNF_FG().validate(nf_fg_file) nffg = NF_FG() nffg.parseDict(nf_fg_file) nffg1, nffg2 = nffg.split(nffg.end_points, nffg.vnfs) # for graph 0,2 # 3 """ left = [] left.append(nffg.end_points[0]) nffg1, nffg2 = nffg.split(left, nffg.vnfs) # for graph 3 """ """ left = [] left.append(nffg.vnfs[0]) left.append(nffg.vnfs[1]) right= []
def searchMatchesBetweenDomains(self, domains_info, domain_id_1, domain_id_2, number_of_links): matches_found = 0 characterization = [] middle_nffg = None domain_1 = domains_info[domain_id_1] # Directly linked domains # Vlan for interface in domain_1.interfaces: for neighbor in interface.neighbors: if neighbor.domain_name != "internet" and neighbor.interface is not None: # Search for direct connections try: remote_domain = Domain().getDomainFromName(neighbor.domain_name) except DomainNotFound: # Remote_domain not found, continue continue remote_node = neighbor.node remote_interface_name = neighbor.interface if remote_domain.id == domain_id_2 and remote_domain.id in domains_info: remote_interface = domains_info[remote_domain.id].getInterface( remote_node, remote_interface_name ) if ( remote_interface is not None and self.isNeighbor(remote_interface, Domain().getDomain(domain_id_1).name, interface) is True ): if interface.vlan is True and remote_interface.vlan is True: while matches_found < number_of_links: vlan_id = self.findFreeVlanId(interface.vlans_free, remote_interface.vlans_free) if vlan_id is not None: print("vlan match found") matches_found = matches_found + 1 characterization.append( Vlan( interface.node, interface.name, domain_1.type, remote_node, remote_interface_name, remote_domain.type, vlan_id, ) ) else: logging.debug("vlan id free not found") break if matches_found == number_of_links: break if matches_found == number_of_links: break # Direct links if matches_found < number_of_links: for interface in domain_1.interfaces: for neighbor in interface.neighbors: if neighbor.domain_name != "internet" and neighbor.interface is not None: # Search for direct connections try: remote_domain = Domain().getDomainFromName(neighbor.domain_name) except DomainNotFound: # Remote_domain not found, continue continue remote_node = neighbor.node remote_interface_name = neighbor.interface if remote_domain.id == domain_id_2 and remote_domain.id in domains_info: remote_interface = domains_info[remote_domain.id].getInterface( remote_node, remote_interface_name ) if ( remote_interface is not None and self.isNeighbor(remote_interface, Domain().getDomain(domain_id_1).name, interface) is True ): print("direct link match found") matches_found = matches_found + 1 characterization.append( DirectLink( interface.node, interface.name, domain_1.type, remote_node, remote_interface_name, remote_domain.type, ) ) if matches_found == number_of_links: break if matches_found == number_of_links: break # Domains not directly linked if matches_found < number_of_links: for interface in domain_1.interfaces: result = self.searchConnectionThroughADomain(domains_info, interface, domain_id_1, domain_id_2) if result is not None: middle_domain = result[0] middle_interface_1 = result[1] middle_interface_2 = result[2] remote_interface = result[3] # TODO: Direct links support? if ( interface.vlan is True and middle_interface_1.vlan is True and middle_interface_2.vlan is True and remote_interface.vlan is True ): middle_nffg = NF_FG() middle_nffg.name = "Passthrough" middle_nffg.domain = middle_domain.name nffg_manager = NFFG_Manager(middle_nffg) while matches_found < number_of_links: vlan_id_1 = self.findFreeVlanId(interface.vlans_free, middle_interface_1.vlans_free) vlan_id_2 = self.findFreeVlanId(middle_interface_2.vlans_free, remote_interface.vlans_free) if vlan_id_1 is not None and vlan_id_2 is not None: print("vlan match through an external domain found") nffg_manager.addEndpointsCoupleAndFlowrules(matches_found) matches_found = matches_found + 1 characterization.append( Vlan( interface.node, interface.name, domain_1.type, middle_interface_1.node, middle_interface_1.name, middle_domain.type, vlan_id_1, partial=1, ) ) characterization.append( Vlan( middle_interface_2.node, middle_interface_2.name, middle_domain.type, remote_interface.node, remote_interface.name, Domain().getDomain(domain_id_2).type, vlan_id_2, partial=2, ) ) else: logging.debug("vlan id free not found") break if matches_found == number_of_links: break # Domains connected through an IP domain # GRE if matches_found < number_of_links: # Search for internet connections for interface in domain_1.interfaces: if self.isConnectedToIPDomain(interface) is True and interface.gre is True: # if self.checkActiveTunnels(interface, node_id_2) is True: domain_2 = domains_info[domain_id_2] for remote_interface in domain_2.interfaces: if self.isConnectedToIPDomain(remote_interface) is True and remote_interface.gre is True: # Gre_tunnel endpoints found # If local and/or remote interfaces are Openstack compute nodes we need to set the local/remote GRE IP addresses accordingly if interface.node is not None: local_ip = interface.node else: local_ip = Domain().getDomainIP(domain_id_1) if remote_interface.node is not None: remote_ip = remote_interface.node else: remote_ip = Domain().getDomainIP(domain_id_2) while matches_found < number_of_links: print("gre match found") matches_found = matches_found + 1 characterization.append(Gre(local_ip, remote_ip)) break if matches_found == number_of_links: break if matches_found == number_of_links: print("Characterization found") return characterization, middle_nffg else: return None