Пример #1
0
 def free_ip(self, res_id):
     neutron = clients.get_neutron_client()
     try:
         neutron.delete_floatingip(res_id)
     except n_exc.NeutronClientException as ex:
         LOG.error("Failed to delete floating_ip_id =%s !", res_id)
         raise ex
Пример #2
0
    def release_vif(self, pod, vif):
        neutron = clients.get_neutron_client()
        try:
            container_port = neutron.list_ports(
                True, device_owner=pod['deviceOnwer']).get('ports')[0]
        except IndexError:
            LOG.error("Unable to find port with mac %s.", pod['macAddr'])
            return

        port_id = container_port.get('id')
        container_mac = container_port['mac_address']
        container_ips = frozenset(entry['ip_address']
                                  for entry in container_port['fixed_ips'])
        parent_port_ip = container_port['binding:host_id']

        with self.lock:
            vm_port = self._get_parent_port_for_release(
                neutron, parent_port_ip)
            self._remove_from_allowed_address_pairs(neutron, vm_port,
                                                    container_ips,
                                                    container_mac)

        try:
            neutron.delete_port(port_id)
        except n_exc.PortNotFoundClient:
            LOG.warning("Unable to release port %s as it no longer exists.",
                        port_id)
Пример #3
0
    def request_vifs(self, pod, project_id, subnets, security_groups,
                     num_ports):
        neutron = clients.get_neutron_client()

        rq = self._get_port_request(pod,
                                    project_id,
                                    subnets,
                                    security_groups,
                                    unbound=True)

        bulk_port_rq = {'ports': [rq for _ in range(num_ports)]}
        try:
            ports = neutron.create_port(bulk_port_rq).get('ports')
        except n_exc.NeutronClientException as ex:
            LOG.error("Error creating bulk ports: %s", bulk_port_rq)
            raise ex

        vif_plugin = self._get_vif_plugin(ports[0])

        # NOTE(ltomasbo): Due to the bug (1696051) on neutron bulk port
        # creation request returning the port objects without binding
        # information, an additional (non-bulk) port creation is performed to
        # get the right vif binding information
        if vif_plugin == 'unbound':
            single_port = neutron.create_port(rq).get('port')
            vif_plugin = self._get_vif_plugin(single_port)
            ports.append(single_port)

        vifs = []
        for port in ports:
            vif = ovu.neutron_to_osvif_vif(vif_plugin, port, subnets)
            vifs.append(vif)
        return vifs
Пример #4
0
    def release_vif(self, pod, vif):
        neutron = clients.get_neutron_client()

        try:
            neutron.delete_port(vif.id)
        except n_exc.PortNotFoundClient:
            LOG.debug('Unable to release port %s as it no longer exists.',
                      vif.id)
Пример #5
0
    def request_vif(self, pod, project_id, subnets, security_groups):
        neutron = clients.get_neutron_client()

        rq = self._get_port_request(pod, project_id, subnets, security_groups)
        port = neutron.create_port(rq).get('port')
        vif_plugin = self._get_vif_plugin(port)

        return ovu.neutron_to_osvif_vif(vif_plugin, port, subnets)
Пример #6
0
    def _get_in_use_vlan_ids_set(self, trunk_id):
        vlan_ids = set()
        neutron = clients.get_neutron_client()
        trunk = neutron.show_trunk(trunk_id)
        for port in trunk['trunk']['sub_ports']:
            vlan_ids.add(port['segmentation_id'])

        return vlan_ids
Пример #7
0
    def _return_ports_to_pool(self):
        """Recycle ports to be reused by future pods.

        For each port in the recyclable_ports dict it reaplies
        security group if they have been changed and it changes the port
        name to available_port if the port_debug option is enabled.
        Then the port_id is included in the dict with the available_ports.

        If a maximun number of port per pool is set, the port will be
        deleted if the maximun has been already reached.
        """
        neutron = clients.get_neutron_client()
        while True:
            sg_current = {}
            if not config.CONF.rancher.port_debug:
                kuryr_ports = self._get_ports_by_attrs(
                    device_owner=kl_const.DEVICE_OWNER)
                for port in kuryr_ports:
                    if port['id'] in self._recyclable_ports.keys():
                        sg_current[port['id']] = port['security_groups']

            for port_id, pool_key in self._recyclable_ports.copy().items():
                if (not oslo_cfg.CONF.vif_pool.ports_pool_max
                        or self._get_pool_size(pool_key) <
                        oslo_cfg.CONF.vif_pool.ports_pool_max):
                    port_name = (constants.KURYR_PORT_NAME
                                 if config.CONF.rancher.port_debug else '')
                    if (config.CONF.rancher.port_debug
                            or list(pool_key[2]) != sg_current.get(port_id)):
                        try:
                            neutron.update_port(
                                port_id, {
                                    "port": {
                                        'name': port_name,
                                        'device_id': '',
                                        'security_groups': list(pool_key[2])
                                    }
                                })
                        except n_exc.NeutronClientException:
                            LOG.warning(
                                "Error preparing port %s to be "
                                "reused, put back on the cleanable "
                                "pool.", port_id)
                            continue
                    self._available_ports_pools.setdefault(pool_key,
                                                           []).append(port_id)
                else:
                    try:
                        del self._existing_vifs[port_id]
                        neutron.delete_port(port_id)
                    except n_exc.PortNotFoundClient:
                        LOG.debug(
                            'Unable to release port %s as it no longer '
                            'exists.', port_id)
                    except KeyError:
                        LOG.debug('Port %s is not in the ports list.', port_id)
                del self._recyclable_ports[port_id]
            eventlet.sleep(oslo_cfg.CONF.vif_pool.ports_pool_update_frequency)
Пример #8
0
    def request_vif(self, pod, project_id, subnets, security_groups):
        neutron = clients.get_neutron_client()
        parent_port = self._get_parent_port(neutron, pod)
        trunk_id = self._get_trunk_id(parent_port)

        rq = self._get_port_request(pod, project_id, subnets, security_groups)
        port = neutron.create_port(rq).get('port')
        vlan_id = self._add_subport(neutron, trunk_id, port['id'])

        return ovu.neutron_to_osvif_vif_nested_vlan(port, subnets, vlan_id)
Пример #9
0
 def _create_listener(self, listener):
     neutron = clients.get_neutron_client()
     response = neutron.create_listener({'listener': {
         'name': listener.name,
         'project_id': listener.project_id,
         'tenant_id': listener.project_id,
         'loadbalancer_id': listener.loadbalancer_id,
         'protocol': listener.protocol,
         'protocol_port': listener.port}})
     listener.id = response['listener']['id']
     return listener
Пример #10
0
 def release_vif(self, pod, vif):
     neutron = clients.get_neutron_client()
     parent_port = self._get_parent_port(neutron, pod)
     trunk_id = self._get_trunk_id(parent_port)
     self._remove_subport(neutron, trunk_id, vif.id)
     self._release_vlan_id(vif.vlan_id)
     try:
         neutron.delete_port(vif.id)
     except n_exc.PortNotFoundClient:
         LOG.debug('Unable to release port %s as it no longer exists.',
                   vif.id)
Пример #11
0
 def _create_loadbalancer(self, loadbalancer):
     neutron = clients.get_neutron_client()
     response = neutron.create_loadbalancer({'loadbalancer': {
         'name': loadbalancer.name,
         'project_id': loadbalancer.project_id,
         'tenant_id': loadbalancer.project_id,
         'vip_address': str(loadbalancer.ip),
         'vip_subnet_id': loadbalancer.subnet_id}})
     loadbalancer.id = response['loadbalancer']['id']
     loadbalancer.port_id = self._get_vip_port_id(loadbalancer)
     return loadbalancer
Пример #12
0
 def _create_member(self, member):
     neutron = clients.get_neutron_client()
     response = neutron.create_lbaas_member(member.pool_id, {'member': {
         'name': member.name,
         'project_id': member.project_id,
         'tenant_id': member.project_id,
         'subnet_id': member.subnet_id,
         'address': str(member.ip),
         'protocol_port': member.port}})
     member.id = response['member']['id']
     return member
Пример #13
0
    def activate_vif(self, pod, vif):
        if vif.active:
            return

        neutron = clients.get_neutron_client()
        port = neutron.show_port(vif.id).get('port')

        if port['status'] != kl_const.PORT_STATUS_ACTIVE:
            raise k_exc.ResourceNotReady(vif)

        vif.active = True
Пример #14
0
def _get_subnet(subnet_id):
    # TODO(ivc): add caching (e.g. oslo.cache with dict backend)
    neutron = clients.get_neutron_client()

    n_subnet = neutron.show_subnet(subnet_id).get('subnet')
    network_id = n_subnet['network_id']
    n_network = neutron.show_network(network_id).get('network')

    subnet = os_vif_util.neutron_to_osvif_subnet(n_subnet)
    network = os_vif_util.neutron_to_osvif_network(n_network)
    network.subnets.objects.append(subnet)

    return network
Пример #15
0
 def _update(self, res_id, vip_port_id):
     response = None
     neutron = clients.get_neutron_client()
     try:
         response = neutron.update_floatingip(
             res_id, {'floatingip': {
                 'port_id': vip_port_id,
             }})
     except n_exc.NeutronClientException as ex:
         LOG.error(
             "Failed to update_floatingip ,floating_ip_id=%s,"
             "response=%s!", res_id, response)
         raise ex
Пример #16
0
    def _get_vip_port_id(self, loadbalancer):
        neutron = clients.get_neutron_client()
        try:
            fixed_ips = ['subnet_id=%s' % str(loadbalancer.subnet_id),
                         'ip_address=%s' % str(loadbalancer.ip)]
            ports = neutron.list_ports(fixed_ips=fixed_ips)
        except n_exc.NeutronClientException as ex:
            LOG.error("Port with fixed ips %s not found!", fixed_ips)
            raise ex

        if ports['ports']:
            return ports['ports'][0].get("id")

        return None
Пример #17
0
    def request_vif(self, pod, project_id, subnets, security_groups):
        neutron = clients.get_neutron_client()
        req = self._get_port_request(pod, project_id, subnets, security_groups)
        container_port = neutron.create_port(req).get('port')

        container_mac = container_port['mac_address']
        container_ips = frozenset(entry['ip_address']
                                  for entry in container_port['fixed_ips'])

        with self.lock:
            vm_port = self._get_parent_port_for_request(neutron, pod)
            self._add_to_allowed_address_pairs(neutron, vm_port, container_ips,
                                               container_mac)

        return ovu.neutron_to_osvif_vif_nested_macvlan(container_port, subnets)
Пример #18
0
    def test_setup_clients(self, m_neutron, m_k8s, m_cfg):
        k8s_api_root = 'http://127.0.0.1:1234'

        neutron_dummy = object()
        k8s_dummy = object()

        m_cfg.kubernetes.api_root = k8s_api_root
        m_neutron.return_value = neutron_dummy
        m_k8s.return_value = k8s_dummy

        clients.setup_clients()

        m_k8s.assert_called_with(k8s_api_root)
        self.assertIs(k8s_dummy, clients.get_kubernetes_client())
        self.assertIs(neutron_dummy, clients.get_neutron_client())
Пример #19
0
 def _get_port_from_pool(self, pool_key, pod, subnets):
     try:
         port_id = self._available_ports_pools[pool_key].pop()
     except IndexError:
         raise exceptions.ResourceNotReady(pod)
     if config.CONF.rancher.port_debug:
         neutron = clients.get_neutron_client()
         neutron.update_port(port_id, {"port": {
             'name': pod['name'],
         }})
     # check if the pool needs to be populated
     if (self._get_pool_size(pool_key) <
             oslo_cfg.CONF.vif_pool.ports_pool_min):
         eventlet.spawn(self._populate_pool, pool_key, pod, subnets)
     return self._existing_vifs[port_id]
Пример #20
0
    def acquire_service_pub_ip_info(self, spec_type, spec_lb_ip, project_id):

        if spec_type != 'LoadBalancer':
            return None

        if spec_lb_ip:
            user_specified_ip = spec_lb_ip.format()
            res_id = self._drv_pub_ip.is_ip_available(user_specified_ip)
            if res_id:
                service_pub_ip_info = (obj_lbaas.LBaaSPubIp(
                                       ip_id=res_id,
                                       ip_addr=str(user_specified_ip),
                                       alloc_method='user'))

                return service_pub_ip_info
            else:
                # user specified IP is not valid
                LOG.error("IP=%s is not available", user_specified_ip)
                return None
        else:
            LOG.debug("Trying to allocate public ip from pool")

        # get public subnet id from kuryr.conf
        external_svc_subnet = config.CONF.neutron_defaults.external_svc_subnet
        if not external_svc_subnet:
            raise cfg.RequiredOptError('external_svc_subnet',
                                       cfg.OptGroup('neutron_defaults'))

        neutron = clients.get_neutron_client()
        n_subnet = neutron.show_subnet(external_svc_subnet).get('subnet')
        if not n_subnet:
            LOG.error(
                "No subnet found for external_svc_subnet=%s",
                external_svc_subnet)
            raise kl_exc.NoResourceException

        public_network_id = n_subnet['network_id']

        res_id, alloc_ip_addr = (self._drv_pub_ip.allocate_ip
                                 (public_network_id,
                                  external_svc_subnet,
                                  project_id,
                                  'kuryr_lb'))
        service_pub_ip_info = obj_lbaas.LBaaSPubIp(ip_id=res_id,
                                                   ip_addr=alloc_ip_addr,
                                                   alloc_method='pool')

        return service_pub_ip_info
Пример #21
0
 def is_ip_available(self, ip_addr):
     if ip_addr:
         neutron = clients.get_neutron_client()
         floating_ips_list = neutron.list_floatingips(
             floating_ip_address=ip_addr)
         for entry in floating_ips_list['floatingips']:
             if not entry:
                 continue
             if (entry['floating_ip_address'] == ip_addr
                     and not entry['port_id']):
                 return entry['id']
         # floating IP not available
         LOG.error("Floating IP=%s not available", ip_addr)
     else:
         LOG.error("Invalid parameter ip_addr=%s", ip_addr)
     return None
Пример #22
0
    def _find_loadbalancer(self, loadbalancer):
        neutron = clients.get_neutron_client()
        response = neutron.list_loadbalancers(
            name=loadbalancer.name,
            project_id=loadbalancer.project_id,
            tenant_id=loadbalancer.project_id,
            vip_address=str(loadbalancer.ip),
            vip_subnet_id=loadbalancer.subnet_id)

        try:
            loadbalancer.id = response['loadbalancers'][0]['id']
            loadbalancer.port_id = self._get_vip_port_id(loadbalancer)
        except (KeyError, IndexError):
            return None

        return loadbalancer
Пример #23
0
    def _find_listener(self, listener):
        neutron = clients.get_neutron_client()
        response = neutron.list_listeners(
            name=listener.name,
            project_id=listener.project_id,
            tenant_id=listener.project_id,
            loadbalancer_id=listener.loadbalancer_id,
            protocol=listener.protocol,
            protocol_port=listener.port)

        try:
            listener.id = response['listeners'][0]['id']
        except (KeyError, IndexError):
            return None

        return listener
Пример #24
0
    def _find_pool(self, pool):
        neutron = clients.get_neutron_client()
        response = neutron.list_lbaas_pools(
            name=pool.name,
            project_id=pool.project_id,
            tenant_id=pool.project_id,
            loadbalancer_id=pool.loadbalancer_id,
            protocol=pool.protocol)

        try:
            pools = [p for p in response['pools']
                     if pool.listener_id in {l['id'] for l in p['listeners']}]
            pool.id = pools[0]['id']
        except (KeyError, IndexError):
            return None

        return pool
Пример #25
0
    def _find_member(self, member):
        neutron = clients.get_neutron_client()
        response = neutron.list_lbaas_members(
            member.pool_id,
            name=member.name,
            project_id=member.project_id,
            tenant_id=member.project_id,
            subnet_id=member.subnet_id,
            address=member.ip,
            protocol_port=member.port)

        try:
            member.id = response['members'][0]['id']
        except (KeyError, IndexError):
            return None

        return member
Пример #26
0
    def _wait_for_provisioning(self, loadbalancer, timeout):
        neutron = clients.get_neutron_client()

        for remaining in self._provisioning_timer(timeout):
            response = neutron.show_loadbalancer(loadbalancer.id)
            status = response['loadbalancer']['provisioning_status']
            if status == 'ACTIVE':
                LOG.debug("Provisioning complete for %(lb)s", {
                    'lb': loadbalancer})
                return
            else:
                LOG.debug("Provisioning status %(status)s for %(lb)s, "
                          "%(rem).3gs remaining until timeout",
                          {'status': status, 'lb': loadbalancer,
                           'rem': remaining})

        raise k_exc.ResourceNotReady(loadbalancer)
Пример #27
0
 def _create_pool(self, pool):
     # TODO(ivc): make lb_algorithm configurable
     lb_algorithm = 'ROUND_ROBIN'
     neutron = clients.get_neutron_client()
     try:
         response = neutron.create_lbaas_pool({'pool': {
             'name': pool.name,
             'project_id': pool.project_id,
             'tenant_id': pool.project_id,
             'listener_id': pool.listener_id,
             'loadbalancer_id': pool.loadbalancer_id,
             'protocol': pool.protocol,
             'lb_algorithm': lb_algorithm}})
         pool.id = response['pool']['id']
         return pool
     except n_exc.StateInvalidClient:
         with excutils.save_and_reraise_exception():
             self._cleanup_bogus_pool(neutron, pool, lb_algorithm)
Пример #28
0
    def allocate_ip(self, pub_net_id, pub_subnet_id, project_id, description):

        neutron = clients.get_neutron_client()
        try:
            response = neutron.create_floatingip({
                'floatingip': {
                    'tenant_id': project_id,
                    'project_id': project_id,
                    'floating_network_id': pub_net_id,
                    'subnet_id': pub_subnet_id,
                    'description': description
                }
            })
        except n_exc.NeutronClientException as ex:
            LOG.error("Failed to create floating IP - subnetid=%s ",
                      pub_subnet_id)
            raise ex
        return response['floatingip']['id'], response['floatingip'][
            'floating_ip_address']
Пример #29
0
    def request_vifs(self,
                     pod,
                     project_id,
                     subnets,
                     security_groups,
                     num_ports,
                     trunk_ip=None):
        """This method creates subports and returns a list with their vifs.

        It creates up to num_ports subports and attaches them to the trunk
        port.

        If not enough vlan ids are available for all the subports to create,
        it creates as much as available vlan ids.

        Note the neutron trunk_add_subports is an atomic operation that will
        either attach all or none of the subports. Therefore, if there is a
        vlan id collision, all the created ports will be deleted and the
        exception is raised.
        """
        neutron = clients.get_neutron_client()
        if trunk_ip:
            parent_port = self._get_parent_port_by_host_ip(neutron, trunk_ip)
        else:
            parent_port = self._get_parent_port(neutron, pod)
        trunk_id = self._get_trunk_id(parent_port)

        port_rq, subports_info = self._create_subports_info(pod,
                                                            project_id,
                                                            subnets,
                                                            security_groups,
                                                            trunk_id,
                                                            num_ports,
                                                            unbound=True)

        if not subports_info:
            LOG.error("There are no vlan ids available to create subports")
            return []

        bulk_port_rq = {'ports': [port_rq for _ in range(len(subports_info))]}
        try:
            ports = neutron.create_port(bulk_port_rq).get('ports')
        except n_exc.NeutronClientException as ex:
            LOG.error("Error creating bulk ports: %s", bulk_port_rq)
            raise ex
        for index, port in enumerate(ports):
            subports_info[index]['port_id'] = port['id']

        try:
            try:
                neutron.trunk_add_subports(trunk_id,
                                           {'sub_ports': subports_info})
            except n_exc.Conflict as ex:
                LOG.error("vlan ids already in use on trunk")
                for port in ports:
                    neutron.delete_port(port['id'])
                raise ex
        except n_exc.NeutronClientException as ex:
            LOG.error("Error happened during subport addition to trunk")
            raise ex

        vifs = []
        for index, port in enumerate(ports):
            vlan_id = subports_info[index]['segmentation_id']
            vif = ovu.neutron_to_osvif_vif_nested_vlan(port, subnets, vlan_id)
            vifs.append(vif)
        return vifs
Пример #30
0
    def _precreated_ports(self, action, trunk_ips=None):
        """Removes or recovers pre-created subports at given pools

        This function handles the pre-created ports based on the given action:
        - If action is `free` it will remove all the subport from the given
        trunk ports, or from all the trunk ports if no trunk_ips are passed.
        - If action is `recover` it will discover the existing subports in the
        given trunk ports (or in all of them if none are passed) and will add
        them (and the needed information) to the respective pools.
        """
        neutron = clients.get_neutron_client()
        # Note(ltomasbo): ML2/OVS changes the device_owner to trunk:subport
        # when a port is attached to a trunk. However, that is not the case
        # for other ML2 drivers, such as ODL. So we also need to look for
        # compute:kuryr
        if config.CONF.rancher.port_debug:
            available_ports = self._get_ports_by_attrs(
                name=constants.KURYR_PORT_NAME,
                device_owner=['trunk:subport', kl_const.DEVICE_OWNER])
        else:
            kuryr_subports = self._get_ports_by_attrs(
                device_owner=['trunk:subport', kl_const.DEVICE_OWNER])
            in_use_ports = self._get_in_use_ports()
            available_ports = [
                subport for subport in kuryr_subports
                if subport['id'] not in in_use_ports
            ]

        if not available_ports:
            return

        trunk_ports = neutron.list_trunks().get('trunks')
        for trunk in trunk_ports:
            try:
                host_addr = self._get_parent_port_ip(trunk['port_id'])
            except n_exc.PortNotFoundClient:
                LOG.debug('Unable to find parent port for trunk port %s.',
                          trunk['port_id'])
                continue

            if trunk_ips and host_addr not in trunk_ips:
                continue

            for subport in trunk.get('sub_ports'):
                kuryr_subport = None
                for port in available_ports:
                    if port['id'] == subport['port_id']:
                        kuryr_subport = port
                        break

                if kuryr_subport:
                    pool_key = (host_addr, kuryr_subport['project_id'],
                                tuple(kuryr_subport['security_groups']))

                    if action == 'recover':
                        subnet_id = kuryr_subport['fixed_ips'][0]['subnet_id']
                        subnet = {
                            subnet_id: default_subnet._get_subnet(subnet_id)
                        }
                        vif = ovu.neutron_to_osvif_vif_nested_vlan(
                            kuryr_subport, subnet, subport['segmentation_id'])

                        self._existing_vifs[subport['port_id']] = vif
                        self._available_ports_pools.setdefault(
                            pool_key, []).append(subport['port_id'])
                    elif action == 'free':
                        try:
                            self._drv_vif._remove_subport(
                                neutron, trunk['id'], subport['port_id'])
                            neutron.delete_port(subport['port_id'])
                            self._drv_vif._release_vlan_id(
                                subport['segmentation_id'])
                            del self._existing_vifs[subport['port_id']]
                            self._available_ports_pools[pool_key].remove(
                                subport['port_id'])
                        except n_exc.PortNotFoundClient:
                            LOG.debug(
                                'Unable to release port %s as it no '
                                'longer exists.', subport['port_id'])
                        except KeyError:
                            LOG.debug('Port %s is not in the ports list.',
                                      subport['port_id'])
                        except n_exc.NeutronClientException:
                            LOG.warning('Error removing the subport %s',
                                        subport['port_id'])
                        except ValueError:
                            LOG.debug(
                                'Port %s is not in the available ports '
                                'pool.', subport['port_id'])