class SvcChain(object): def __init__(self, controller): self.controller = controller self.dbSvc = DbServices() self.flowSvc = OFManager(controller) self.base_flow_id = 1000 self.rscSvc = ODLRscGetter(controller) def _generate_name(self, prefix, model): modle_list = self.dbSvc._list_rsc(self.session, model) count = "0" if modle_list: count = str(len(modle_list)) return prefix+count def define_sc_tplt(self, pipeline, tpltName=None, tpltID=None): if not tpltName: tplt_name = self._generate_name(SC_TPLT_NAME_PREFIX, SCTemplate) else: tplt_name = tpltName sc_tplt = SCTemplate() sc_tplt.set_attributes(tpltName= tplt_name,tpltPipe= pipeline, tpltId=tpltID) self.dbSvc.add_sctplt(sc_tplt) return sc_tplt def define_sc_inst(self, tpltId, proto, dst_port, instId): sc_inst = SCInstance() sc_inst.set_attributes(protocol=proto, port=dst_port, template=tpltId,id=instId) self.dbSvc.add_scinstance(sc_inst) return sc_inst def define_sc_app(self,node_name, inst_id): of_node = self.dbSvc.get_ofnode_by_name(node_name) node_id = of_node.nodeid return self.define_sc_app_by_id(node_id, inst_id) def define_sc_app_by_id(self, node_id, inst_id): sc_app = SCApp() app_id = "/".join([node_id,inst_id]) sc_app.set_attributes(node_id, inst_id, app_id) self.dbSvc.add_scapp(sc_app) self.write_flow(node_id, inst_id) return sc_app def _generate_flow_id(self): self.base_flow_id +=1 return self.base_flow_id def calculate_outpute_port(self, srcNode, dstNode): of_link = self.dbSvc.get_oflink_by_srcdst(srcNode.nodeid, dstNode.nodeid) src_port = of_link.srcPort of_port_no = int(src_port.split(":")[-1]) return of_port_no def is_nfv_node(self, nodetype): return nodetype in const.available_nfv_types def calculate_inport(self, from_node, to_node): of_link = self.dbSvc.get_oflink_by_srcdst(from_node.nodeid, to_node.nodeid) dst_port = of_link.dstPort of_port_no = int(dst_port.split(":")[-1]) return of_port_no def get_app_match_fields(self, host_node,sc_instance): sc_proto = sc_instance.proto sc_port = sc_instance.port src_mac = host_node.mac return { "src_mac":src_mac, "protocol":sc_proto, "dst_port":sc_port } def construct_sw_flow(self, sw_node, priority, from_node, to_node , **match_fields): in_port = self.calculate_inport(from_node, sw_node) outputPort = self.calculate_outpute_port(sw_node, to_node) match_fields.update({"in_port":in_port}) flow_node_id = sw_node.nodeid table_id = 0 flow_id = self._generate_flow_id() self.flowSvc.construct_flow(flow_node_id, table_id, flow_id, priority, output_port=outputPort, return_pts = False, **match_fields) def construct_vnf_flow(self, vnf, sw_node, priority, **match_fields): flow_node_id = vnf.nodeid flow_id = self._generate_flow_id() table_id = const.TABLE_ID_VNF self.flowSvc.construct_flow(flow_node_id, table_id, flow_id, priority, ret_pkt=True, **match_fields) def write_flow(self, host_node_id, inst_id): host_node = self.dbSvc.get_ofnode(host_node_id) sc_instance = self.dbSvc.get_scinstance(inst_id) sc_template = self.dbSvc.get_sctplt(sc_instance.tpltID) sw_node = self.dbSvc.get_ofnode_by_type(const.SWITCH) match_fields = self.get_app_match_fields(host_node,sc_instance) from_node = host_node sw_priority = const.PRIORITY_SW_FLOW vnf_priority = const.PRIORITY_VNF_FLOW for node_type in sc_template.getPipleLine(): if not self.is_nfv_node(node_type): continue vnf = self.dbSvc.get_ofnode_by_type(node_type) self.construct_sw_flow(sw_node, sw_priority, from_node, vnf, **match_fields) self.construct_vnf_flow(vnf, sw_node, vnf_priority, **match_fields) from_node = vnf def is_node_exists(self, ofnode): node = self.dbSvc.get_ofnode_by_mac(ofnode.mac) if node: return True return False def is_link_exist(self, link): link = self.dbSvc.get_oflink(link.linkid) if link: return True return False def sync_ofnodes(self): ofnode_configs = self.rscSvc.getOFNodes() for key in ofnode_configs.keys(): switch_node = ofnode_configs[key][const.SWITCH] if not self.is_node_exists(switch_node): self.dbSvc.add_ofnode(switch_node) host_nodes = ofnode_configs[key][const.HOST] for host in host_nodes: if not self.is_node_exists(host): self.dbSvc.add_ofnode(host) self.sync_oflinks() return ofnode_configs def sync_oflinks(self): expect_count = self.rscSvc.countSw() - 1 expect_count = expect_count if expect_count> 0 else 0 of_links = self.rscSvc.getOFLinks(expect_count) for lnk in of_links: if not self.is_link_exist(lnk): self.dbSvc.add_oflink(lnk) return of_links def set_vnf_type_by_name(self, sw_name, type): ofnode = self.dbSvc.get_ofnode_by_name(sw_name) self.dbSvc.mod_ofnode_type(ofnode.nodeid, type) def get_all_ofnods(self): self.sync_ofnodes() nodes_list = self.dbSvc.list_ofnodes() return nodes_list def get_tpltid_by_name(self, name): tplt = self.dbSvc.get_tplt_by_name(name) if tplt: return tplt.tpltid def get_all_templates(self): return self.dbSvc.list_sctplt() def get_all_instances(self): return self.dbSvc.list_scinstance() def get_all_apps(self): return self.dbSvc.list_scapp() def update_node_type(self, node_id, type): self.dbSvc.mod_ofnode_type(node_id, type)