def get_subnet(context, id, fields=None): """Retrieve a subnet. : param context: neutron api request context : param id: UUID representing the subnet to fetch. : param fields: a list of strings that are valid keys in a subnet dictionary as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. Only these fields will be returned. """ LOG.info("get_subnet %s for tenant %s with fields %s" % (id, context.tenant_id, fields)) subnet = db_api.subnet_find(context, None, None, None, False, id=id, join_dns=True, join_routes=True, scope=db_api.ONE) if not subnet: raise exceptions.SubnetNotFound(subnet_id=id) cache = subnet.get("_allocation_pool_cache") if not cache: new_cache = subnet.allocation_pools db_api.subnet_update_set_alloc_pool_cache(context, subnet, new_cache) return v._make_subnet_dict(subnet)
def get_subnet(context, id, fields=None): """Retrieve a subnet. : param context: neutron api request context : param id: UUID representing the subnet to fetch. : param fields: a list of strings that are valid keys in a subnet dictionary as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. Only these fields will be returned. """ LOG.info("get_subnet %s for tenant %s with fields %s" % (id, context.tenant_id, fields)) subnet = db_api.subnet_find(context, id=id, join_dns=True, join_routes=True, scope=db_api.ONE) if not subnet: raise exceptions.SubnetNotFound(subnet_id=id) # Check the network_id against the strategies net_id = subnet["network_id"] net_id = STRATEGY.get_parent_network(net_id) subnet["network_id"] = net_id return v._make_subnet_dict(subnet)
def create_ip_policy(context, ip_policy): LOG.info("create_ip_policy for tenant %s" % context.tenant_id) ipp = ip_policy["ip_policy"] if not ipp.get("exclude"): raise exceptions.BadRequest(resource="ip_policy", msg="Empty ip_policy.exclude regions") ipp["exclude"] = netaddr.IPSet(ipp["exclude"]) network_id = ipp.get("network_id") subnet_id = ipp.get("subnet_id") model = None if subnet_id: model = db_api.subnet_find(context, id=subnet_id, scope=db_api.ONE) if not model: raise exceptions.SubnetNotFound(id=subnet_id) elif network_id: model = db_api.network_find(context, id=network_id, scope=db_api.ONE) if not model: raise exceptions.NetworkNotFound(id=network_id) else: raise exceptions.BadRequest(resource="ip_policy", msg="network_id or subnet_id unspecified") if model["ip_policy"]: raise quark_exceptions.IPPolicyAlreadyExists( id=model["ip_policy"]["id"], n_id=model["id"]) model["ip_policy"] = db_api.ip_policy_create(context, **ipp) return v._make_ip_policy_dict(model["ip_policy"])
def load(cls, neutron_subnet_id, ctx): """Load an IPAM subnet from the database given its neutron ID. :param neutron_subnet_id: neutron subnet identifier. """ ipam_subnet = ipam_db_api.IpamSubnetManager.load_by_neutron_subnet_id( ctx.session, neutron_subnet_id) if not ipam_subnet: LOG.error( _LE("IPAM subnet referenced to " "Neutron subnet %s does not exist"), neutron_subnet_id) raise n_exc.SubnetNotFound(subnet_id=neutron_subnet_id) pools = [] for pool in ipam_subnet.allocation_pools: pools.append(netaddr.IPRange(pool['first_ip'], pool['last_ip'])) neutron_subnet = cls._fetch_subnet(ctx, neutron_subnet_id) return cls(ipam_subnet['id'], ctx, cidr=neutron_subnet['cidr'], allocation_pools=pools, gateway_ip=neutron_subnet['gateway_ip'], tenant_id=neutron_subnet['tenant_id'], subnet_id=neutron_subnet_id)
def update_subnet(context, id, subnet): """Update values of a subnet. : param context: neutron api request context : param id: UUID representing the subnet to update. : param subnet: dictionary with keys indicating fields to update. valid keys are those that have a value of True for 'allow_put' as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. """ LOG.info("update_subnet %s for tenant %s" % (id, context.tenant_id)) subnet_db = db_api.subnet_find(context, id=id, scope=db_api.ONE) if not subnet_db: raise exceptions.SubnetNotFound(id=id) s = subnet["subnet"] dns_ips = s.pop("dns_nameservers", []) host_routes = s.pop("host_routes", []) gateway_ip = s.pop("gateway_ip", None) if gateway_ip: default_route = None for route in host_routes: netaddr_route = netaddr.IPNetwork(route["destination"]) if netaddr_route.value == routes.DEFAULT_ROUTE.value: default_route = route break if default_route is None: route_model = db_api.route_find(context, cidr=str(routes.DEFAULT_ROUTE), subnet_id=id, scope=db_api.ONE) if route_model: db_api.route_update(context, route_model, gateway=gateway_ip) else: db_api.route_create(context, cidr=str(routes.DEFAULT_ROUTE), gateway=gateway_ip, subnet_id=id) if dns_ips: subnet_db["dns_nameservers"] = [] for dns_ip in dns_ips: subnet_db["dns_nameservers"].append( db_api.dns_create(context, ip=netaddr.IPAddress(dns_ip))) if host_routes: subnet_db["routes"] = [] for route in host_routes: subnet_db["routes"].append( db_api.route_create(context, cidr=route["destination"], gateway=route["nexthop"])) subnet = db_api.subnet_update(context, subnet_db, **s) return v._make_subnet_dict(subnet, default_route=routes.DEFAULT_ROUTE)
def delete_subnet(context, id): """Delete a subnet. : param context: neutron api request context : param id: UUID representing the subnet to delete. """ LOG.info("delete_subnet %s for tenant %s" % (id, context.tenant_id)) subnet = db_api.subnet_find(context, id=id, scope=db_api.ONE) if not subnet: raise exceptions.SubnetNotFound(subnet_id=id) _delete_subnet(context, subnet)
def test_unknown_subnet_in_endpoint_group(self): subnet_id = _uuid() self.core_plugin.get_subnet.side_effect = nexception.SubnetNotFound( subnet_id=subnet_id) endpoint_group = { 'type': v_constants.SUBNET_ENDPOINT, 'endpoints': [subnet_id] } self.assertRaises(vpnaas.NonExistingSubnetInEndpointGroup, self.validator.validate_endpoint_group, self.context, endpoint_group)
def create_ip_policy(context, ip_policy): LOG.info("create_ip_policy for tenant %s" % context.tenant_id) ipp = ip_policy['ip_policy'] if not ipp.get("exclude"): raise exceptions.BadRequest(resource="ip_policy", msg="Empty ip_policy.exclude") network_ids = ipp.get("network_ids") subnet_ids = ipp.get("subnet_ids") if subnet_ids and network_ids: raise exceptions.BadRequest( resource="ip_policy", msg="network_ids and subnet_ids specified. only one allowed") if not subnet_ids and not network_ids: raise exceptions.BadRequest( resource="ip_policy", msg="network_ids or subnet_ids not specified") with context.session.begin(): if subnet_ids: subnets = db_api.subnet_find(context, id=subnet_ids, scope=db_api.ALL) if not subnets: raise exceptions.SubnetNotFound(id=subnet_ids) _check_for_pre_existing_policies_in(subnets) ensure_default_policy(ipp["exclude"], subnets) _validate_cidrs_fit_into_subnets(ipp["exclude"], subnets) ipp.pop("subnet_ids") ipp["subnets"] = subnets if network_ids: nets = db_api.network_find(context, id=network_ids, scope=db_api.ALL) if not nets: raise exceptions.NetworkNotFound(net_id=network_ids) _check_for_pre_existing_policies_in(nets) subnets = [ subnet for net in nets for subnet in net.get("subnets", []) ] ensure_default_policy(ipp["exclude"], subnets) _validate_cidrs_fit_into_subnets(ipp["exclude"], subnets) ipp.pop("network_ids") ipp["networks"] = nets ip_policy = db_api.ip_policy_create(context, **ipp) return v._make_ip_policy_dict(ip_policy)
def remove_subnet(self, subnet_id): """Remove data structures for a given subnet. IPAM-related data has no foreign key relationships to neutron subnet, so removing ipam subnet manually """ count = ipam_db_api.IpamSubnetManager.delete(self._context.session, subnet_id) if count < 1: LOG.error( _LE("IPAM subnet referenced to " "Neutron subnet %s does not exist"), subnet_id) raise n_exc.SubnetNotFound(subnet_id=subnet_id)
def create_floatingip(self, context, floatingip): try: floatingip_port = None with context.session.begin(subtransactions=True): floatingip_dict = super(DFPlugin, self).create_floatingip( context, floatingip, initial_status=const.FLOATINGIP_STATUS_DOWN) floatingip_port = self._get_floatingip_port( context, floatingip_dict['id']) if not floatingip_port: raise n_exc.DeviceNotFoundError( device_name=floatingip_dict['id']) subnet_id = floatingip_port['fixed_ips'][0]['subnet_id'] floatingip_subnet = self._get_floatingip_subnet( context, subnet_id) if floatingip_subnet is None: raise n_exc.SubnetNotFound(subnet_id=subnet_id) fip_version = version_db._create_db_version_row( context.session, floatingip_dict['id']) except Exception: with excutils.save_and_reraise_exception() as ctxt: ctxt.reraise = True # delete the stale floatingip port try: if floatingip_port: self.nb_api.delete_lport(floatingip_port['id'], floatingip_port['tenant_id']) except df_exceptions.DBKeyNotFound: pass self.nb_api.create_floatingip( id=floatingip_dict['id'], topic=floatingip_dict['tenant_id'], name=floatingip_dict.get('name', df_const.DF_FIP_DEFAULT_NAME), floating_ip_address=floatingip_dict['floating_ip_address'], floating_network_id=floatingip_dict['floating_network_id'], router_id=floatingip_dict['router_id'], port_id=floatingip_dict['port_id'], fixed_ip_address=floatingip_dict['fixed_ip_address'], status=floatingip_dict['status'], floating_port_id=floatingip_port['id'], floating_mac_address=floatingip_port['mac_address'], external_gateway_ip=floatingip_subnet['gateway_ip'], version=fip_version, external_cidr=floatingip_subnet['cidr']) return floatingip_dict
def delete_subnet(context, id): """Delete a subnet. : param context: neutron api request context : param id: UUID representing the subnet to delete. """ LOG.info("delete_subnet %s for tenant %s" % (id, context.tenant_id)) with context.session.begin(): subnet = db_api.subnet_find(context, id=id, scope=db_api.ONE) if not subnet: raise exceptions.SubnetNotFound(subnet_id=id) payload = dict(tenant_id=subnet["tenant_id"], ip_block_id=subnet["id"], created_at=subnet["created_at"], deleted_at=timeutils.utcnow()) _delete_subnet(context, subnet) n_rpc.get_notifier("network").info(context, "ip_block.delete", payload)
def create_route(context, route): LOG.info("create_route for tenant %s" % context.tenant_id) route = route["route"] for key in ["gateway", "cidr", "subnet_id"]: if key not in route: raise exceptions.BadRequest(resource="routes", msg="%s is required" % key) subnet_id = route["subnet_id"] with context.session.begin(): subnet = db_api.subnet_find(context, id=subnet_id, scope=db_api.ONE) if not subnet: raise exceptions.SubnetNotFound(subnet_id=subnet_id) policies = db_models.IPPolicy.get_ip_policy_cidrs(subnet) alloc_pools = allocation_pool.AllocationPools(subnet["cidr"], policies=policies) alloc_pools.validate_gateway_excluded(route["gateway"]) # TODO(anyone): May want to denormalize the cidr values into columns # to achieve single db lookup on conflict check route_cidr = netaddr.IPNetwork(route["cidr"]) subnet_routes = db_api.route_find(context, subnet_id=subnet_id, scope=db_api.ALL) quota.QUOTAS.limit_check(context, context.tenant_id, routes_per_subnet=len(subnet_routes) + 1) for sub_route in subnet_routes: sub_route_cidr = netaddr.IPNetwork(sub_route["cidr"]) if sub_route_cidr.value == DEFAULT_ROUTE.value: continue if route_cidr in sub_route_cidr or sub_route_cidr in route_cidr: raise quark_exceptions.RouteConflict(route_id=sub_route["id"], cidr=str(route_cidr)) new_route = db_api.route_create(context, **route) return v._make_route_dict(new_route)
def create_route(context, route): LOG.info("create_route for tenant %s" % context.tenant_id) route = route["route"] subnet_id = route["subnet_id"] subnet = db_api.subnet_find(context, id=subnet_id, scope=db_api.ONE) if not subnet: raise exceptions.SubnetNotFound(subnet_id=subnet_id) # TODO(anyone): May want to denormalize the cidr values into columns # to achieve single db lookup on conflict check route_cidr = netaddr.IPNetwork(route["cidr"]) subnet_routes = db_api.route_find(context, subnet_id=subnet_id, scope=db_api.ALL) for sub_route in subnet_routes: sub_route_cidr = netaddr.IPNetwork(sub_route["cidr"]) if sub_route_cidr.value == DEFAULT_ROUTE.value: continue if route_cidr in sub_route_cidr or sub_route_cidr in route_cidr: raise quark_exceptions.RouteConflict(route_id=sub_route["id"], cidr=str(route_cidr)) new_route = db_api.route_create(context, **route) return v._make_route_dict(new_route)
def test_create_port_catch_subnet_not_found(self): self._test__port_action_with_failures( exc=n_exc.SubnetNotFound(subnet_id='foo_subnet_id'), action='create_port')
def test_get_dhcp_port_catch_subnet_not_found_on_create_port(self): self._test_get_dhcp_port_with_failures( raise_create_port=n_exc.SubnetNotFound(subnet_id='b'))
def update_ip_policy(context, id, ip_policy): LOG.info("update_ip_policy for tenant %s" % context.tenant_id) ipp = ip_policy["ip_policy"] with context.session.begin(): ipp_db = db_api.ip_policy_find(context, id=id, scope=db_api.ONE) if not ipp_db: raise quark_exceptions.IPPolicyNotFound(id=id) ip_policy_cidrs = ipp.get("exclude") network_ids = ipp.get("network_ids") subnet_ids = ipp.get("subnet_ids") if subnet_ids and network_ids: raise exceptions.BadRequest( resource="ip_policy", msg="network_ids and subnet_ids specified. only one allowed") models = [] all_subnets = [] if subnet_ids: for subnet in ipp_db["subnets"]: subnet["ip_policy"] = None subnets = db_api.subnet_find(context, id=subnet_ids, scope=db_api.ALL) if len(subnets) != len(subnet_ids): raise exceptions.SubnetNotFound(id=subnet_ids) if ip_policy_cidrs is not None: ensure_default_policy(ip_policy_cidrs, subnets) _validate_cidrs_fit_into_subnets(ip_policy_cidrs, subnets) all_subnets.extend(subnets) models.extend(subnets) if network_ids: for network in ipp_db["networks"]: network["ip_policy"] = None nets = db_api.network_find(context, id=network_ids, scope=db_api.ALL) if len(nets) != len(network_ids): raise exceptions.NetworkNotFound(net_id=network_ids) subnets = [ subnet for net in nets for subnet in net.get("subnets", []) ] if ip_policy_cidrs is not None: ensure_default_policy(ip_policy_cidrs, subnets) _validate_cidrs_fit_into_subnets(ip_policy_cidrs, subnets) all_subnets.extend(subnets) models.extend(nets) if not subnet_ids and not network_ids and ip_policy_cidrs is not None: ensure_default_policy(ip_policy_cidrs, ipp_db["subnets"]) _validate_cidrs_fit_into_subnets(ip_policy_cidrs, ipp_db["subnets"]) for model in models: if model["ip_policy"]: raise quark_exceptions.IPPolicyAlreadyExists( id=model["ip_policy"]["id"], n_id=model["id"]) model["ip_policy"] = ipp_db if ip_policy_cidrs: _validate_policy_with_routes(context, ip_policy_cidrs, all_subnets) ipp_db = db_api.ip_policy_update(context, ipp_db, **ipp) return v._make_ip_policy_dict(ipp_db)
def get_subnet_cidr(client, subnet_id): try: kv_pair = client.kv_retrieve(subnet_id) except vnc_exc.NoIdError: raise n_exc.SubnetNotFound(subnet_id=subnet_id) return kv_pair.split()[1]
def update_subnet(context, id, subnet): """Update values of a subnet. : param context: neutron api request context : param id: UUID representing the subnet to update. : param subnet: dictionary with keys indicating fields to update. valid keys are those that have a value of True for 'allow_put' as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. """ LOG.info("update_subnet %s for tenant %s" % (id, context.tenant_id)) with context.session.begin(): subnet_db = db_api.subnet_find(context, None, None, None, False, id=id, scope=db_api.ONE) if not subnet_db: raise exceptions.SubnetNotFound(id=id) s = subnet["subnet"] always_pop = [ "_cidr", "cidr", "first_ip", "last_ip", "ip_version", "segment_id", "network_id" ] admin_only = [ "do_not_use", "created_at", "tenant_id", "next_auto_assign_ip", "enable_dhcp" ] utils.filter_body(context, s, admin_only, always_pop) dns_ips = utils.pop_param(s, "dns_nameservers", []) host_routes = utils.pop_param(s, "host_routes", []) gateway_ip = utils.pop_param(s, "gateway_ip", None) allocation_pools = utils.pop_param(s, "allocation_pools", None) if not CONF.QUARK.allow_allocation_pool_update: if allocation_pools: raise exceptions.BadRequest( resource="subnets", msg="Allocation pools cannot be updated.") alloc_pools = allocation_pool.AllocationPools( subnet_db["cidr"], policies=models.IPPolicy.get_ip_policy_cidrs(subnet_db)) else: alloc_pools = allocation_pool.AllocationPools( subnet_db["cidr"], allocation_pools) quota.QUOTAS.limit_check(context, context.tenant_id, alloc_pools_per_subnet=len(alloc_pools)) if gateway_ip: alloc_pools.validate_gateway_excluded(gateway_ip) default_route = None for route in host_routes: netaddr_route = netaddr.IPNetwork(route["destination"]) if netaddr_route.value == routes.DEFAULT_ROUTE.value: default_route = route break if default_route is None: route_model = db_api.route_find(context, cidr=str(routes.DEFAULT_ROUTE), subnet_id=id, scope=db_api.ONE) if route_model: db_api.route_update(context, route_model, gateway=gateway_ip) else: db_api.route_create(context, cidr=str(routes.DEFAULT_ROUTE), gateway=gateway_ip, subnet_id=id) if dns_ips: subnet_db["dns_nameservers"] = [] quota.QUOTAS.limit_check(context, context.tenant_id, dns_nameservers_per_subnet=len(dns_ips)) for dns_ip in dns_ips: subnet_db["dns_nameservers"].append( db_api.dns_create(context, ip=netaddr.IPAddress(dns_ip))) if host_routes: subnet_db["routes"] = [] quota.QUOTAS.limit_check(context, context.tenant_id, routes_per_subnet=len(host_routes)) for route in host_routes: subnet_db["routes"].append( db_api.route_create(context, cidr=route["destination"], gateway=route["nexthop"])) if CONF.QUARK.allow_allocation_pool_update: if isinstance(allocation_pools, list): cidrs = alloc_pools.get_policy_cidrs() ip_policies.ensure_default_policy(cidrs, [subnet_db]) subnet_db["ip_policy"] = db_api.ip_policy_update( context, subnet_db["ip_policy"], exclude=cidrs) # invalidate the cache db_api.subnet_update_set_alloc_pool_cache(context, subnet_db) subnet = db_api.subnet_update(context, subnet_db, **s) return v._make_subnet_dict(subnet)
def _get_subnet(self, context, id): try: subnet = self._get_by_id(context, models_v2.Subnet, id) except exc.NoResultFound: raise n_exc.SubnetNotFound(subnet_id=id) return subnet
def get_subnet_network_id(client, subnet_id): try: kv_pair = client.kv_retrieve(subnet_id) except NoIdError: raise n_exc.SubnetNotFound(subnet_id=subnet_id) return kv_pair.split()[0]
def test_create_port_catch_and_handle_ip_generation_failure(self): self.plugin.get_subnet.side_effect = ( n_exc.SubnetNotFound(subnet_id='foo_subnet_id')) self._test__port_action_with_failures( exc=n_exc.IpAddressGenerationFailure(net_id='foo_network_id'), action='create_port')
def test_subnet_delete_helper_tolerates_failure(self): plugin = manager.NeutronManager.get_plugin() with mock.patch.object(plugin, "delete_subnet", side_effect=exc.SubnetNotFound(subnet_id="1")): plugin._delete_subnets(None, [mock.MagicMock()])