コード例 #1
0
ファイル: management.py プロジェクト: NajibOdhah/5gr-rl
    def post(self):
        data = flask.request.get_json()
        LOG.info("network_request:" + json.dumps(data, indent=4))
        config = flask.current_app.osloconfig
        neutron = OpenStackClients(config).neutron()

        name = data['networkResourceName']

        network = {
            'name': name,
            'admin_state_up': True,
        }
        # id = data['reservationId']
        if data['networkResourceType'] == 'network':
            if 'metadata' in data:
                metadata = convert_metadata_array_to_dict(data['metadata'])
                if "interpop_vlan" in metadata and metadata[
                        'interpop_vlan'] != "":
                    physical_network = conf.cfg.CONF.nfvi_pop.inter_pop_physical_network
                    network.update({"provider:network_type": "vlan"})
                    network.update(
                        {"provider:physical_network": physical_network})
                    network.update({
                        "provider:segmentation_id":
                        metadata['interpop_vlan']
                    })
            is_network_exists = check_if_network_exists(neutron, name)
            if is_network_exists is None:
                network = neutron.create_network({'network': network})
            else:
                network['network'] = is_network_exists
            data = NetworkResource(network['network'], 'network',
                                   neutron).export()

        elif data['networkResourceType'] == 'subnet':
            subnet_data = data.get('typeSubnetData', None)
            if 'metadata' in subnet_data:
                metadata = convert_metadata_array_to_dict(
                    subnet_data['metadata'])
                if 'dns' in metadata.keys():
                    meta_dns = metadata['dns']
                    meta_dns = meta_dns.replace("[", "")
                    meta_dns = meta_dns.replace("]", "")
                    meta_dns = meta_dns.replace("\"", "")
                    meta_dns = meta_dns.split(",")
                elif 'subnet_type' in metadata.keys(
                ) and metadata['subnet_type'] == 'admin':
                    meta_dns = conf.cfg.CONF.vtep.vtep_dns
                else:  # we are not supposed to reach this case, but just in case
                    meta_dns = []
            else:
                meta_dns = []

            #import ipdb; ipdb.set_trace()
            cidr = subnet_data['cidr']
            cttcAddressPool = subnet_data.get('addressPool', None)
            if self.isCttcFormat(cttcAddressPool):
                addressPool = self.indexesToAddrPools(cidr, cttcAddressPool)
                cttcFormat = True
            else:
                addressPool = cttcAddressPool
                cttcFormat = False

            ip_versions = {'IPv4': 4, 'IPv6': 6}

            if 'gatewayIp' not in subnet_data.keys(
            ) or subnet_data['gatewayIp'] == "null":
                subnet_data['gatewayIp'] = None
            body_create_subnet = {
                'subnet': {
                    'name': name,
                    'enable_dhcp': subnet_data['isDhcpEnabled'],
                    'network_id': subnet_data['networkId'],
                    # 'segment_id': None,
                    # 'project_id': '4fd44f30292945e481c7b8a0c8908869',
                    # 'tenant_id': '4fd44f30292945e481c7b8a0c8908869',
                    'dns_nameservers': meta_dns,
                    'allocation_pools': addressPool,
                    'host_routes': [],
                    'ip_version': ip_versions[subnet_data['ipVersion']],
                    'gateway_ip': subnet_data['gatewayIp'],
                    'cidr': cidr,
                    # 'id': '3b80198d-4f7b-4f77-9ef5-774d54e17126',
                    # 'created_at': '2016-10-10T14:35:47Z',
                    'description': '',
                    # 'ipv6_address_mode': None,
                    # 'ipv6_ra_mode': None,
                    # 'revision_number': 1,
                    # 'service_types': [],
                    'subnetpool_id': None,
                    # 'tags': ['tag1,tag2'],
                    # 'updated_at': '2016-10-10T14:35:47Z'
                }
            }

            # network_name = name.replace("subnet-", "")
            # is_network_exists = check_if_network_exists(neutron, network_name)
            # if is_network_exists is None:
            #     network = neutron.create_network({'network': network})
            # else:
            #     network['network'] = is_network_exists
            subnets = neutron.list_subnets(network_id=subnet_data['networkId'],
                                           name=name)
            if len(subnets['subnets']) != 0:
                data = NetworkResource(subnets['subnets'][0], 'subnet',
                                       neutron, cttcFormat).export()
                if cttcFormat == True:
                    data['subnetData']['addressPool'] = cttcAddressPool
            else:
                subnet = neutron.create_subnet(body=body_create_subnet)
                data = NetworkResource(subnet['subnet'], 'subnet', neutron,
                                       cttcFormat).export()
                if cttcFormat == True:
                    data['subnetData']['addressPool'] = cttcAddressPool

                if metadata and 'router_id' in metadata.keys():
                    router_id = metadata['router_id']
                    subnet_object = {
                        'subnet_id': data['subnetData']['resourceId']
                    }
                    neutron.add_interface_router(router_id, subnet_object)

                if metadata and 'ip-floating-required' in metadata.keys():
                    floating_required = metadata['ip-floating-required']
                    if floating_required == "True":
                        router_body = {
                            'router': {
                                'name': "router_" + name,
                                'admin_state_up': True
                            }
                        }
                        router = neutron.create_router(router_body)
                        router_id = router['router']['id']

                        subnet_object = {
                            'subnet_id': data['subnetData']['resourceId']
                        }
                        neutron.add_interface_router(router_id, subnet_object)

                        if "external_network" in metadata.keys():
                            external_network_name = metadata[
                                'external_network']
                        else:
                            external_network_name = conf.cfg.CONF.nfvi_pop.floating_network

                        networks = neutron.list_networks(
                            name=external_network_name)['networks']
                        if len(networks) > 1:
                            message = "More then one networks with name:" + external_network_name
                            raise Exception(message)
                        if len(networks) == 0:
                            message = "No networks with name:" + external_network_name
                            print(message)
                            raise Exception(message)

                        router_id = router['router']['id']
                        network_id = networks[0]['id']

                        router_dict = {
                            'network_id': network_id,
                            'enable_snat': True
                        }
                        neutron.add_gateway_router(router_id, router_dict)

        elif data['networkResourceType'] == 'network-port':
            port_data = data.get('typeNetworkPortData', None)

            if 'metadata' in port_data:  # floating_ip or vtep
                metadata = convert_metadata_array_to_dict(
                    port_data['metadata'])
                if metadata['type'] == "floating_ip":
                    body_create_floatingip = {
                        "floatingip": {
                            "floating_network_id":
                            port_data['networkId']  # external network
                        }
                    }
                    # request a floatingip for this project (on the network external)
                    # this address won't be bind to any interface, it's done when the vm is created
                    floating = neutron.create_floatingip(
                        body=body_create_floatingip)
                    data = NetworkResource(floating['floatingip'], 'float',
                                           neutron).export()

                    # add the subnet of the admin network to the project's router
                    body_add_inerface_router = {
                        "subnet_id": metadata['subnet_id']
                    }

                    # If there is no gateway interface for this subnet, it means that we need to add
                    # this subnet to the router
                    if not subnet_has_gateway_interface(
                            neutron, metadata['subnet_id']):
                        # If there is more than one router for a project, we can ad the name= of the router
                        # in the config file
                        router = neutron.list_routers(
                            project_id=conf.cfg.CONF.DEFAULT.project_id)
                        # TODO store the router_id in the config file ?
                        router_id = router['routers'][0]['id']
                        neutron.add_interface_router(router_id,
                                                     body_add_inerface_router)

                elif metadata['type'] == "vtep":
                    port_data = data.get('typeNetworkPortData', None)
                    nova = OpenStackClients(config).nova()

                    vtep_name = conf.cfg.CONF.vtep.vtep_name
                    vtep_image = conf.cfg.CONF.vtep.vtep_image
                    vtep_flavor = conf.cfg.CONF.vtep.vtep_flavor

                    admin_network_id = metadata['admin_network_id']
                    internal_ipaddr = metadata['internal_ip']
                    internal_network_id = metadata['internal_network_id']

                    # add the network interfaces
                    _nics = []
                    _nics.append({'net-id': admin_network_id})
                    _nics.append({
                        'net-id': internal_network_id,
                        'v4-fixed-ip': internal_ipaddr
                    })

                    # the connection to the vm is done with ssh key and user ubuntu
                    # ssh -i vim-manager-key ubuntu@floating_ip
                    key_name = 'vim-manager-key'

                    # param for cloudinit user_data
                    vlan_id = port_data['segmentId']
                    remote_floating_ip = metadata['remote_floating_ip']

                    kwargs = dict(
                        meta=None,
                        files={},
                        reservation_id=None,
                        min_count=1,
                        max_count=1,
                        security_groups=[],
                        userdata=generate_cloudinit_string(
                            vlan_id, remote_floating_ip, internal_ipaddr),
                        key_name=key_name,
                        availability_zone=None,
                        block_device_mapping_v2=[],
                        nics=_nics,
                        scheduler_hints={},
                        config_drive=None,
                    )
                    # create the vm
                    server = nova.servers.create(vtep_name, vtep_image,
                                                 vtep_flavor, **kwargs)

                    # TODO not the best way, but we need to have the vm up and running to look for the port
                    max_retry = 0
                    while server.status == 'BUILD':
                        time.sleep(6)  # to avoid to access openstack to often
                        # the try is to avoid crash if the server doesn't yet exist just wait
                        try:
                            server = nova.servers.find(name=vtep_name)
                        except Exception:
                            pass
                        max_retry = max_retry + 1
                        if max_retry > 10:
                            break

                    # get the local admin ip address to bound the floating ip address
                    if data['networkResourceName'] in server.networks.keys():
                        # the local ip address is always index 0 hence the hardcoded value [0]
                        admin_ipaddr = server.networks[
                            data['networkResourceName']][0]
                    else:
                        # TODO if we stop we probably need to delete the vtep vm because if we try another time
                        # it won't work as the vm will already exist so we have to think of a way to clean up if
                        # ther is a problem
                        return flask.jsonify(
                            'Error wrong networkResourceName, expecting: ' +
                            str(server.networks.keys())), OK

                    # get the port_id of the vm_vtp admin interface ip for floating ip mapping
                    ports = neutron.list_ports(
                        network_id=admin_network_id)['ports']
                    for port in ports:
                        for fixed_ip in port['fixed_ips']:
                            if (fixed_ip['ip_address'] == admin_ipaddr):
                                port_id = port['id']
                                break

                    body_update_floatingip = {
                        "floatingip": {
                            "port_id": port_id
                        }
                    }
                    # get the id of the floating ip that we want to bind to the the vtep_vm
                    floatingip_id = neutron.list_floatingips(
                        floating_ip_address=metadata['local_floating_ip']
                    )['floatingips'][0]['id']
                    # attach the floating ip to the interface of the vm
                    float_update = neutron.update_floatingip(
                        floatingip_id, body=body_update_floatingip)

                    # disable port security for internal port (the MAC address of the the bridge interface
                    # br_vtp is not known by openstack so if the port security is true, the traffic is blocked)

                    # get the internal interface port id
                    ports = neutron.list_ports(
                        network_id=internal_network_id)['ports']
                    for port in ports:
                        for fixed_ip in port['fixed_ips']:
                            if (fixed_ip['ip_address'] == internal_ipaddr):
                                port_id = port['id']
                                break

                    body_update_security_port = {
                        "port": {
                            "security_groups": [],  # no security group
                            "port_security_enabled": False
                        }
                    }
                    # update port with security disable
                    port_update = neutron.update_port(
                        port_id, body=body_update_security_port)
                    print(port_update)
                    # import ipdb; ipdb.set_trace()
                    data = NetworkResource(float_update['floatingip'], 'float',
                                           neutron).export()

            else:  # regular port creation
                body_create_port = {
                    "port": {
                        'name': name,
                        "admin_state_up": True,
                        "network_id": port_data['networkId'],
                    }
                }
                port = neutron.create_port(body=body_create_port)
                data = NetworkResource(port['port'], 'port', neutron).export()

        elif data['networkResourceType'] == 'router':
            body_router_create = {
                'router': {
                    'name': name,
                    'admin_state_up': True
                }
            }
            router = neutron.create_router(body_router_create)

            if 'metadata' in data:
                metadata = convert_metadata_array_to_dict(data['metadata'])
                if 'external_network' in metadata.keys():
                    network_name = metadata['external_network']
                    networks = neutron.list_networks(
                        name=network_name)['networks']
                    if len(networks) > 1:
                        message = "More then one networks with name:" + network_name
                        raise Exception(message)
                    if len(networks) == 0:
                        message = "No networks with name:" + network_name
                        print(message)
                        raise Exception(message)

                    router_id = router['router']['id']
                    network_id = networks[0]['id']

                    router_dict = {
                        'network_id': network_id,
                        'enable_snat': True
                    }
                    neutron.add_gateway_router(router_id, router_dict)
            data = NetworkResource(router['router'], 'router',
                                   neutron).export()
        return flask.jsonify(data), CREATED
コード例 #2
0
    def post(self):
        data = flask.request.get_json()

        config = flask.current_app.osloconfig
        neutron = OpenStackClients(config).neutron()

        name = data['networkResourceName']
        # id = data['reservationId']
        if data['networkResourceType'] == 'network':
            # network_data = data.get('typeNetworkData', None)
            network = {'name': name, 'admin_state_up': True}
            network = neutron.create_network({'network': network})
            data = NetworkResource(network['network'], 'network',
                                   neutron).export()
        elif data['networkResourceType'] == 'subnet':
            subnet_data = data.get('typeSubnetData', None)
            if 'metadata' in subnet_data:
                if 'dns' in subnet_data['metadata']:
                    meta_dns = subnet_data['metadata']['dns']
                elif 'subnet_type' in subnet_data['metadata'] and subnet_data[
                        'metadata']['subnet_type'] == 'admin':
                    meta_dns = conf.cfg.CONF.vtep.vtep_dns
                else:  # we are not supposed to reach this case, but just in case
                    meta_dns = []
            else:
                meta_dns = []

            ip_versions = {'IPv4': 4, 'IPv6': 6}
            body_create_subnet = {
                'subnet': {
                    'name': name,
                    'enable_dhcp': subnet_data['isDhcpEnabled'],
                    'network_id': subnet_data['networkId'],
                    # 'segment_id': None,
                    # 'project_id': '4fd44f30292945e481c7b8a0c8908869',
                    # 'tenant_id': '4fd44f30292945e481c7b8a0c8908869',
                    'dns_nameservers': meta_dns,
                    # 'allocation_pools': [
                    #     {
                    #         'start': '192.168.199.2',
                    #         'end': '192.168.199.254'
                    #         }
                    #     ],
                    'host_routes': [],
                    'ip_version': ip_versions[subnet_data['ipVersion']],
                    'gateway_ip': subnet_data['gatewayIp'],
                    'cidr': subnet_data['cidr'],
                    # 'id': '3b80198d-4f7b-4f77-9ef5-774d54e17126',
                    # 'created_at': '2016-10-10T14:35:47Z',
                    'description': '',
                    # 'ipv6_address_mode': None,
                    # 'ipv6_ra_mode': None,
                    # 'revision_number': 1,
                    # 'service_types': [],
                    'subnetpool_id': None,
                    # 'tags': ['tag1,tag2'],
                    # 'updated_at': '2016-10-10T14:35:47Z'
                }
            }

            subnet = neutron.create_subnet(body=body_create_subnet)
            data = NetworkResource(subnet['subnet'], 'subnet',
                                   neutron).export()
        elif data['networkResourceType'] == 'network-port':
            port_data = data.get('typeNetworkPortData', None)

            if 'metadata' in port_data:  # floating_ip or vtep
                if port_data['metadata']['type'] == "floating_ip":
                    body_create_floatingip = {
                        "floatingip": {
                            "floating_network_id":
                            port_data['networkId']  # external network
                        }
                    }
                    # request a floatingip for this project (on the network external)
                    # this address won't be bind to any interface, it's done when the vm is created
                    floating = neutron.create_floatingip(
                        body=body_create_floatingip)
                    data = NetworkResource(floating['floatingip'], 'float',
                                           neutron).export()

                    # add the subnet of the admin network to the project's router
                    body_add_inerface_router = {
                        "subnet_id": port_data['metadata']['subnet_id']
                    }

                    # If there is no gateway interface for this subnet, it means that we need to add
                    # this subnet to the router
                    if not subnet_has_gateway_interface(
                            neutron, port_data['metadata']['subnet_id']):
                        # If there is more than one router for a project, we can ad the name= of the router
                        # in the config file
                        router = neutron.list_routers(
                            project_id=conf.cfg.CONF.DEFAULT.project_id)
                        # TODO store the router_id in the config file ?
                        router_id = router['routers'][0]['id']
                        neutron.add_interface_router(router_id,
                                                     body_add_inerface_router)

                elif port_data['metadata']['type'] == "vtep":
                    port_data = data.get('typeNetworkPortData', None)
                    nova = OpenStackClients(config).nova()

                    vtep_name = conf.cfg.CONF.vtep.vtep_name
                    vtep_image = conf.cfg.CONF.vtep.vtep_image
                    vtep_flavor = conf.cfg.CONF.vtep.vtep_flavor

                    admin_network_id = port_data['metadata'][
                        'admin_interface']['network_id']
                    internal_ipaddr = port_data['metadata'][
                        'internal_interface']['fixed_ip']
                    internal_network_id = port_data['metadata'][
                        'internal_interface']['network_id']

                    # add the network interfaces
                    _nics = []
                    _nics.append({'net-id': admin_network_id})
                    _nics.append({
                        'net-id': internal_network_id,
                        'v4-fixed-ip': internal_ipaddr
                    })

                    # the connection to the vm is done with ssh key and user ubuntu
                    # ssh -i vim-manager-key ubuntu@floating_ip
                    key_name = 'vim-manager-key'

                    # param for cloudinit user_data
                    vlan_id = port_data['segmentId']
                    remote_floating_ip = port_data['metadata'][
                        'remote_floating_ip']

                    kwargs = dict(
                        meta=None,
                        files={},
                        reservation_id=None,
                        min_count=1,
                        max_count=1,
                        security_groups=[],
                        userdata=generate_cloudinit_string(
                            vlan_id, remote_floating_ip, internal_ipaddr),
                        key_name=key_name,
                        availability_zone=None,
                        block_device_mapping_v2=[],
                        nics=_nics,
                        scheduler_hints={},
                        config_drive=None,
                    )
                    # create the vm
                    server = nova.servers.create(vtep_name, vtep_image,
                                                 vtep_flavor, **kwargs)

                    # TODO not the best way, but we need to have the vm up and running to look for the port
                    max_retry = 0
                    while server.status == 'BUILD':
                        time.sleep(6)  # to avoid to access openstack to often
                        # the try is to avoid crash if the server doesn't yet exist just wait
                        try:
                            server = nova.servers.find(name=vtep_name)
                        except Exception:
                            pass
                        max_retry = max_retry + 1
                        if max_retry > 10:
                            break

                    # get the local admin ip address to bound the floating ip address
                    if data['networkResourceName'] in server.networks.keys():
                        # the local ip address is always index 0 hence the hardcoded value [0]
                        admin_ipaddr = server.networks[
                            data['networkResourceName']][0]
                    else:
                        # TODO if we stop we probably need to delete the vtep vm because if we try another time
                        # it won't work as the vm will already exist so we have to think of a way to clean up if
                        # ther is a problem
                        return flask.jsonify(
                            'Error wrong networkResourceName, expecting: ' +
                            str(server.networks.keys())), OK

                    # get the port_id of the vm_vtp admin interface ip for floating ip mapping
                    ports = neutron.list_ports(
                        network_id=admin_network_id)['ports']
                    for port in ports:
                        for fixed_ip in port['fixed_ips']:
                            if (fixed_ip['ip_address'] == admin_ipaddr):
                                port_id = port['id']
                                break

                    body_update_floatingip = {
                        "floatingip": {
                            "port_id": port_id
                        }
                    }
                    # get the id of the floating ip that we want to bind to the the vtep_vm
                    floatingip_id = neutron.list_floatingips(
                        floating_ip_address=port_data['metadata']
                        ['local_floating_ip'])['floatingips'][0]['id']
                    # attach the floating ip to the interface of the vm
                    float_update = neutron.update_floatingip(
                        floatingip_id, body=body_update_floatingip)

                    # disable port security for internal port (the MAC address of the the bridge interface
                    # br_vtp is not known by openstack so if the port security is true, the traffic is blocked)

                    # get the internal interface port id
                    ports = neutron.list_ports(
                        network_id=internal_network_id)['ports']
                    for port in ports:
                        for fixed_ip in port['fixed_ips']:
                            if (fixed_ip['ip_address'] == internal_ipaddr):
                                port_id = port['id']
                                break

                    body_update_security_port = {
                        "port": {
                            "security_groups": [],  # no security group
                            "port_security_enabled": False
                        }
                    }
                    # update port with security disable
                    port_update = neutron.update_port(
                        port_id, body=body_update_security_port)
                    print(port_update)
                    # import ipdb; ipdb.set_trace()
                    data = NetworkResource(float_update['floatingip'], 'float',
                                           neutron).export()

            else:  # regular port creation
                body_create_port = {
                    "port": {
                        'name': name,
                        "admin_state_up": True,
                        "network_id": port_data['networkId'],
                    }
                }
                port = neutron.create_port(body=body_create_port)
                data = NetworkResource(port['port'], 'port', neutron).export()

        return flask.jsonify(data), CREATED