Exemple #1
0
    def _update_subnet_host_routes(self, context, id, s):
        def _combine(ht):
            return ht['destination'] + "_" + ht['nexthop']

        old_route_list = self._get_route_by_subnet(context, id)

        new_route_set = set([_combine(route) for route in s['host_routes']])

        old_route_set = set([_combine(route) for route in old_route_list])

        for route_str in old_route_set - new_route_set:
            for route in old_route_list:
                if _combine(route) == route_str:
                    context.session.delete(route)
        for route_str in new_route_set - old_route_set:
            route = models_v2.SubnetRoute(
                destination=route_str.partition("_")[0],
                nexthop=route_str.partition("_")[2],
                subnet_id=id)
            context.session.add(route)

        # Gather host routes for result
        new_routes = []
        for route_str in new_route_set:
            new_routes.append({
                'destination': route_str.partition("_")[0],
                'nexthop': route_str.partition("_")[2]
            })
        del s["host_routes"]
        return new_routes
Exemple #2
0
def handle_port_metadata_access(plugin, context, port, is_delete=False):
    if (cfg.CONF.NSX.metadata_mode == config.MetadataModes.INDIRECT
            and port.get('device_owner') == const.DEVICE_OWNER_DHCP):
        if port.get('fixed_ips', []) or is_delete:
            fixed_ip = port['fixed_ips'][0]
            query = context.session.query(models_v2.Subnet)
            subnet = query.filter(
                models_v2.Subnet.id == fixed_ip['subnet_id']).one()
            # If subnet does not have a gateway do not create metadata
            # route. This is done via the enable_isolated_metadata
            # option if desired.
            if not subnet.get('gateway_ip'):
                LOG.info(
                    _('Subnet %s does not have a gateway, the metadata '
                      'route will not be created'), subnet['id'])
                return
            metadata_routes = [
                r for r in subnet.routes
                if r['destination'] == METADATA_DHCP_ROUTE
            ]
            if metadata_routes:
                # We should have only a single metadata route at any time
                # because the route logic forbids two routes with the same
                # destination. Update next hop with the provided IP address
                if not is_delete:
                    metadata_routes[0].nexthop = fixed_ip['ip_address']
                else:
                    context.session.delete(metadata_routes[0])
            else:
                # add the metadata route
                route = models_v2.SubnetRoute(subnet_id=subnet.id,
                                              destination=METADATA_DHCP_ROUTE,
                                              nexthop=fixed_ip['ip_address'])
                context.session.add(route)
Exemple #3
0
    def _save_subnet(self, context, network, subnet_args, dns_nameservers,
                     host_routes, allocation_pools):
        allocation_pools = self._prepare_allocation_pools(
            context, allocation_pools, subnet_args)
        self._validate_subnet_cidr(context, network, subnet_args['cidr'])
        self._validate_network_subnetpools(network,
                                           subnet_args['subnetpool_id'],
                                           subnet_args['ip_version'])

        subnet = models_v2.Subnet(**subnet_args)
        context.session.add(subnet)
        if attributes.is_attr_set(dns_nameservers):
            for addr in dns_nameservers:
                ns = models_v2.DNSNameServer(address=addr, subnet_id=subnet.id)
                context.session.add(ns)

        if attributes.is_attr_set(host_routes):
            for rt in host_routes:
                route = models_v2.SubnetRoute(subnet_id=subnet.id,
                                              destination=rt['destination'],
                                              nexthop=rt['nexthop'])
                context.session.add(route)

        self._save_allocation_pools(context, subnet, allocation_pools)

        return subnet
Exemple #4
0
    def _save_subnet(self, context,
                     network,
                     subnet_args,
                     dns_nameservers,
                     host_routes,
                     subnet_request):
        self._validate_subnet_cidr(context, network, subnet_args['cidr'])
        self._validate_network_subnetpools(network,
                                           subnet_args['subnetpool_id'],
                                           subnet_args['ip_version'])

        subnet = models_v2.Subnet(**subnet_args)
        context.session.add(subnet)
        # NOTE(changzhi) Store DNS nameservers with order into DB one
        # by one when create subnet with DNS nameservers
        if attributes.is_attr_set(dns_nameservers):
            for order, server in enumerate(dns_nameservers):
                dns = models_v2.DNSNameServer(
                    address=server,
                    order=order,
                    subnet_id=subnet.id)
                context.session.add(dns)

        if attributes.is_attr_set(host_routes):
            for rt in host_routes:
                route = models_v2.SubnetRoute(
                    subnet_id=subnet.id,
                    destination=rt['destination'],
                    nexthop=rt['nexthop'])
                context.session.add(route)

        self.save_allocation_pools(context, subnet,
                                   subnet_request.allocation_pools)

        return subnet
Exemple #5
0
    def _ensure_metadata_host_route(self, context, fixed_ip_data,
                                    is_delete=False):
        subnet = self._get_subnet(context, fixed_ip_data['subnet_id'])
        # If subnet does not have a gateway do not create metadata route. This
        # is done via the enable_isolated_metadata option if desired.
        if not subnet.get('gateway_ip'):
            return
        metadata_routes = [r for r in subnet.routes
                           if r['destination'] == METADATA_DHCP_ROUTE]

        if metadata_routes:
            # We should have only a single metadata route at any time
            # because the route logic forbids two routes with the same
            # destination. Update next hop with the provided IP address
            if not is_delete:
                metadata_routes[0].nexthop = fixed_ip_data['ip_address']
            else:
                context.session.delete(metadata_routes[0])
        else:
            # add the metadata route
            route = models_v2.SubnetRoute(subnet_id=subnet.id,
                                          destination=METADATA_DHCP_ROUTE,
                                          nexthop=fixed_ip_data['ip_address'])
            context.session.add(route)
        return cfg.CONF.dhcp_agent_notification
    def _save_subnet(self, context,
                     network,
                     subnet_args,
                     dns_nameservers,
                     host_routes,
                     subnet_request):
        self._validate_subnet_cidr(context, network, subnet_args['cidr'])
        self._validate_network_subnetpools(network,
                                           subnet_args['subnetpool_id'],
                                           subnet_args['ip_version'])

        service_types = subnet_args.pop('service_types', [])

        subnet = models_v2.Subnet(**subnet_args)
        segment_id = subnet_args.get('segment_id')
        try:
            context.session.add(subnet)
            context.session.flush()
        except db_exc.DBReferenceError:
            raise segment_exc.SegmentNotFound(segment_id=segment_id)
        self._validate_segment(context, network['id'], segment_id)

        # NOTE(changzhi) Store DNS nameservers with order into DB one
        # by one when create subnet with DNS nameservers
        if validators.is_attr_set(dns_nameservers):
            for order, server in enumerate(dns_nameservers):
                dns = subnet_obj.DNSNameServer(context,
                                               address=server,
                                               order=order,
                                               subnet_id=subnet.id)
                dns.create()

        if validators.is_attr_set(host_routes):
            for rt in host_routes:
                route = models_v2.SubnetRoute(
                    subnet_id=subnet.id,
                    destination=rt['destination'],
                    nexthop=rt['nexthop'])
                context.session.add(route)

        if validators.is_attr_set(service_types):
            for service_type in service_types:
                service_type_entry = sst_model.SubnetServiceType(
                    subnet_id=subnet.id,
                    service_type=service_type)
                context.session.add(service_type_entry)

        self.save_allocation_pools(context, subnet,
                                   subnet_request.allocation_pools)

        return subnet
Exemple #7
0
def handle_port_metadata_access(plugin, context, port, is_delete=False):
    # For instances supporting DHCP option 121 and created in a
    # DHCP-enabled but isolated network. This method is useful
    # only when no network namespace support.
    plugin_cfg = getattr(cfg.CONF, plugin.cfg_group)
    if (plugin_cfg.metadata_mode == config.MetadataModes.INDIRECT and
        port.get('device_owner') == const.DEVICE_OWNER_DHCP):
        if not port.get('fixed_ips'):
            # If port does not have an IP, the associated subnet is in
            # deleting state.
            LOG.info('Port %s has no IP due to subnet in deleting state',
                     port['id'])
            return
        fixed_ip = port['fixed_ips'][0]
        query = context.session.query(models_v2.Subnet)
        subnet = query.filter(
            models_v2.Subnet.id == fixed_ip['subnet_id']).one()
        # If subnet does not have a gateway, do not create metadata
        # route. This is done via the enable_isolated_metadata
        # option if desired.
        if not subnet.get('gateway_ip'):
            LOG.info('Subnet %s does not have a gateway, the '
                     'metadata route will not be created',
                     subnet['id'])
            return
        metadata_routes = [r for r in subnet.routes
                           if r['destination'] == METADATA_DHCP_ROUTE]
        if metadata_routes:
            # We should have only a single metadata route at any time
            # because the route logic forbids two routes with the same
            # destination. Update next hop with the provided IP address
            if not is_delete:
                metadata_routes[0].nexthop = fixed_ip['ip_address']
            else:
                context.session.delete(metadata_routes[0])
        else:
            # add the metadata route
            route = models_v2.SubnetRoute(
                subnet_id=subnet.id,
                destination=METADATA_DHCP_ROUTE,
                nexthop=fixed_ip['ip_address'])
            context.session.add(route)