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
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)
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
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
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
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)