X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=src%2Femuvim%2Fapi%2Fsonata%2Fdummygatekeeper.py;h=5936d94ab3f7fd0db697410d89a028ec275ca390;hb=7062cee83ca95f51b9f43987e61a434e9e5e32f4;hp=eb31c0acf564bcbae6154e8a07972b20b1eb3bb5;hpb=9c4fd11a22412782565a33fb6936fdf0b7ef31f7;p=osm%2Fvim-emu.git diff --git a/src/emuvim/api/sonata/dummygatekeeper.py b/src/emuvim/api/sonata/dummygatekeeper.py index eb31c0a..5936d94 100755 --- a/src/emuvim/api/sonata/dummygatekeeper.py +++ b/src/emuvim/api/sonata/dummygatekeeper.py @@ -75,6 +75,7 @@ class Gatekeeper(object): def __init__(self): self.services = dict() self.dcs = dict() + self.net = None self.vnf_counter = 0 # used to generate short names for VNFs (Mininet limitation) LOG.info("Create SONATA dummy gatekeeper.") @@ -180,6 +181,9 @@ class Service(object): eline_fwd_links = [l for l in vlinks if (l["id"] in fwd_links) and (l["connectivity_type"] == "E-Line")] elan_fwd_links = [l for l in vlinks if (l["id"] in fwd_links) and (l["connectivity_type"] == "E-LAN")] + GK.net.deployed_elines.extend(eline_fwd_links) + GK.net.deployed_elans.extend(elan_fwd_links) + # 4a. deploy E-Line links # cookie is used as identifier for the flowrules installed by the dummygatekeeper # eg. different services get a unique cookie for their flowrules @@ -227,6 +231,9 @@ class Service(object): # 4b. deploy E-LAN links base = 10 for link in elan_fwd_links: + + elan_vnf_list=[] + # generate lan ip address ip = 1 for intf in link["connection_points_reference"]: @@ -235,6 +242,8 @@ class Service(object): if vnf_id in self.sap_identifiers: src_docker_name = "{0}_{1}".format(vnf_id, intf_name) vnf_id = src_docker_name + else: + src_docker_name = vnf_id vnf_name = vnf_id2vnf_name[vnf_id] LOG.debug( "Setting up E-LAN link. %s(%s:%s) -> %s" % ( @@ -249,6 +258,14 @@ class Service(object): self._vnf_reconfigure_network(vnfi, intf_name, ip_address) # increase for the next ip address on this E-LAN ip += 1 + + # add this vnf and interface to the E-LAN for tagging + network = self.vnfds[vnf_name].get("dc").net # there should be a cleaner way to find the DCNetwork + elan_vnf_list.append({'name':src_docker_name,'interface':intf_name}) + + + # install the VLAN tags for this E-LAN + network.setLAN(elan_vnf_list) # increase the base ip address for the next E-LAN base += 1 @@ -261,10 +278,10 @@ class Service(object): def stop_service(self, instance_uuid): """ This method stops a running service instance. - It iterates over all VNFDs, stopping them each + It iterates over all VNF instances, stopping them each and removing them from their data center. - :return: + :param instance_uuid: the uuid of the service instance to be stopped """ LOG.info("Stopping service %r" % self.uuid) # get relevant information @@ -272,7 +289,7 @@ class Service(object): vnf_instances = self.instances[instance_uuid]["vnf_instances"] for v in vnf_instances: - self._stop_vnfd(v) + self._stop_vnfi(v) if not GK_STANDALONE_MODE: # remove placement? @@ -282,9 +299,6 @@ class Service(object): # last step: remove the instance from the list of all instances del self.instances[instance_uuid] - - - def _start_vnfd(self, vnfd): """ Start a single VNFD of this service @@ -323,20 +337,17 @@ class Service(object): vnfi = target_dc.startCompute(self.vnf_name2docker_name[vnf_name], network=intfs, image=docker_name, flavor_name="small") return vnfi - def _stop_vnfd(self, vnfi): + def _stop_vnfi(self, vnfi): """ - Stop a VNFD specified by its name. + Stop a VNF instance. - :param vnf_name: Name of the vnf to be stopped - :return: + :param vnfi: vnf instance to be stopped """ -# if vnf_name not in self.vnfds: -# raise Exception("VNFD with name %s not found." % vnf_name) # Find the correct datacenter status = vnfi.getStatus() dc = vnfi.datacenter # stop the vnfi - LOG.info("Stopping the vnf instance contained in %r ind DC %r" % (status["name"], dc)) + LOG.info("Stopping the vnf instance contained in %r in DC %r" % (status["name"], dc)) dc.stopCompute(status["name"]) def _get_vnf_instance(self, instance_uuid, name): @@ -414,6 +425,7 @@ class Service(object): self.package_content_path, make_relative_path(self.manifest.get("entry_service_template"))) self.nsd = load_yaml(nsd_path) + GK.net.deployed_nsds.append(self.nsd) LOG.debug("Loaded NSD: %r" % self.nsd.get("name")) def _load_vnfd(self): @@ -633,7 +645,7 @@ class Instantiations(fr.Resource): if service_uuid in GK.services: # ok, we have a service uuid, lets start the service service_instance_uuid = GK.services.get(service_uuid).start_service() - return {"service_instance_uuid": service_instance_uuid} + return {"service_instance_uuid": service_instance_uuid}, 201 return "Service not found", 404 def get(self): @@ -647,14 +659,12 @@ class Instantiations(fr.Resource): def delete(self): """ - Stops a running service specified by its UUID. - - :return: + Stops a running service specified by its service and instance UUID. """ - # try to extract the service UUID from the request + # try to extract the service and instance UUID from the request json_data = request.get_json(force=True) service_uuid = json_data.get("service_uuid") - instance_uuid = json_data.get("instance_uuid") + instance_uuid = json_data.get("service_instance_uuid") # try to be fuzzy if service_uuid is None and len(GK.services) > 0: @@ -663,28 +673,31 @@ class Instantiations(fr.Resource): if instance_uuid is None and len(GK.services[service_uuid].instances) > 0: instance_uuid = list(GK.services[service_uuid].instances.iterkeys())[0] - if service_uuid in GK.services: - # valid service UUID, stop service + if service_uuid in GK.services and instance_uuid in GK.services[service_uuid].instances: + # valid service and instance UUID, stop service GK.services.get(service_uuid).stop_service(instance_uuid) - return "", 0 + del GK.services.get(service_uuid).instances[instance_uuid] + return return "Service not found", 404 -class Exit(fr.Resource): # name not final +class Exit(fr.Resource): def put(self): """ Stop the running Containernet instance regardless of data transmitted """ - # First, close the mininet CLI + GK.net.stop() + + +def initialize_GK(): + global GK + GK = Gatekeeper() - # Second, stop the network - service = GK.services[GK.services.keys[0]] - network = service.vnfds[service.vnfds.keys[0]].get("dc").net # there should be a cleaner way to find the DCNetwork - network.stop() # create a single, global GK object -GK = Gatekeeper() +GK = None +initialize_GK() # setup Flask app = Flask(__name__) app.config['MAX_CONTENT_LENGTH'] = 512 * 1024 * 1024 # 512 MB max upload @@ -692,11 +705,17 @@ api = fr.Api(app) # define endpoints api.add_resource(Packages, '/packages') api.add_resource(Instantiations, '/instantiations') -api.add_resource(Exit, '/emulator/exit') # name not final TODO change it or remove TODO +api.add_resource(Exit, '/emulator/exit') + + +#def initialize_GK(): +# global GK +# GK = Gatekeeper() def start_rest_api(host, port, datacenters=dict()): GK.dcs = datacenters + GK.net = get_dc_network() # start the Flask server (not the best performance but ok for our use case) app.run(host=host, port=port, @@ -745,6 +764,14 @@ def generate_subnet_strings(n, start=1, subnet_size=24, ip=0): r.append("%d.0.0.%d/%d" % (i, ip, subnet_size)) return r +def get_dc_network(): + """ + retrieve the DCnetwork where this dummygatekeeper (GK) connects to. + Assume at least 1 datacenter is connected to this GK, and that all datacenters belong to the same DCNetwork + :return: + """ + assert (len(GK.dcs) > 0) + return GK.dcs.values()[0].net if __name__ == '__main__': """