def insert_default_ip_policy(self, subnet_db): cidrs = [] ip_policies.ensure_default_policy(cidrs, [subnet_db]) subnet_db["ip_policy"] = db_api.ip_policy_create( self.context, exclude=cidrs) self.context.session.add(subnet_db) self.context.session.flush()
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 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 create_subnet(context, subnet): """Create a subnet. Create a subnet which represents a range of IP addresses that can be allocated to devices : param context: neutron api request context : param subnet: dictionary describing the subnet, with keys as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. All keys will be populated. """ LOG.info("create_subnet for tenant %s" % context.tenant_id) net_id = subnet["subnet"]["network_id"] net = db_api.network_find(context, id=net_id, scope=db_api.ONE) if not net: raise exceptions.NetworkNotFound(net_id=net_id) sub_attrs = subnet["subnet"] _validate_subnet_cidr(context, net_id, sub_attrs["cidr"]) cidr = netaddr.IPNetwork(sub_attrs["cidr"]) gateway_ip = utils.pop_param(sub_attrs, "gateway_ip", str(cidr[1])) dns_ips = utils.pop_param(sub_attrs, "dns_nameservers", []) host_routes = utils.pop_param(sub_attrs, "host_routes", []) allocation_pools = utils.pop_param(sub_attrs, "allocation_pools", []) sub_attrs["network"] = net new_subnet = db_api.subnet_create(context, **sub_attrs) 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 gateway_ip = default_route["nexthop"] new_subnet["routes"].append(db_api.route_create( context, cidr=route["destination"], gateway=route["nexthop"])) if default_route is None: new_subnet["routes"].append(db_api.route_create( context, cidr=str(routes.DEFAULT_ROUTE), gateway=gateway_ip)) for dns_ip in dns_ips: new_subnet["dns_nameservers"].append(db_api.dns_create( context, ip=netaddr.IPAddress(dns_ip))) if allocation_pools: exclude = netaddr.IPSet([cidr]) for p in allocation_pools: x = netaddr.IPSet(netaddr.IPRange(p["start"], p["end"])) exclude = exclude - x new_subnet["ip_policy"] = db_api.ip_policy_create(context, exclude=exclude) subnet_dict = v._make_subnet_dict(new_subnet, default_route=routes.DEFAULT_ROUTE) subnet_dict["gateway_ip"] = gateway_ip return subnet_dict
def test_ip_policies_create(self): exclude_first_last = dict() for cidr in ("192.168.10.0/32", "192.168.10.255/32"): exclude_first_last[cidr] = netaddr.IPNetwork(cidr).ipv6().first ip_policy = db_api.ip_policy_create(self.context, exclude=exclude_first_last) self.assertEqual(len(ip_policy["exclude"]), 2) for ippc in ip_policy["exclude"]: self.assertEqual(exclude_first_last[ippc["cidr"]], ippc["first_ip"]) self.assertEqual(exclude_first_last[ippc["cidr"]], ippc["last_ip"])
def test_ip_policies_update(self): ip_policy_dict = dict(exclude=["192.168.10.0/32", "192.168.10.255/32"]) ip_policy = db_api.ip_policy_create(self.context, **ip_policy_dict) ip_policy_update_dict = dict(exclude=[ "192.168.10.0/32", "192.168.10.13/32", "192.168.10.255/32" ]) updated_ip_policy = db_api.ip_policy_update(self.context, ip_policy, **ip_policy_update_dict) self.assertEqual(updated_ip_policy["size"], 3)
def test_ip_policies_update(self): ip_policy_dict = dict(exclude=["192.168.10.0/32", "192.168.10.255/32"]) ip_policy = db_api.ip_policy_create(self.context, **ip_policy_dict) new_exclude_first_last = dict() for cidr in ("192.168.10.0/32", "192.168.10.13/32", "192.168.10.255/32"): new_exclude_first_last[cidr] = netaddr.IPNetwork(cidr).ipv6().first updated_ip_policy = db_api.ip_policy_update(self.context, ip_policy, exclude=new_exclude_first_last.keys()) self.assertEqual(len(updated_ip_policy["exclude"]), 3) for ippc in updated_ip_policy["exclude"]: self.assertEqual(new_exclude_first_last[ippc["cidr"]], ippc["first_ip"]) self.assertEqual(new_exclude_first_last[ippc["cidr"]], ippc["last_ip"])
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") 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") 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(): models = [] 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) if ip_policy_cidrs: _validate_cidrs_fit_into_subnets(ip_policy_cidrs, subnets) models.extend(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) subnets = [subnet for net in nets for subnet in net.get("subnets", [])] if ip_policy_cidrs and subnets: _validate_cidrs_fit_into_subnets(ip_policy_cidrs, subnets) models.extend(nets) for model in models: 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 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 _fixtures(self, models): self.ipam = quark.ipam.QuarkIpamANY() net = dict(name="public", tenant_id='fake') net_mod = db_api.network_create(self.context, **net) with self.context.session.begin(): for model in models: policy_mod = db_api.ip_policy_create( self.context, **model['ip_policy']) model['subnet']["network"] = net_mod model['subnet']["ip_policy"] = policy_mod db_api.subnet_create(self.context, **model['subnet']) yield net_mod
def _fixtures(self, models): self.ipam = quark.ipam.QuarkIpamANY() net = dict(name="public", tenant_id='fake') net_mod = db_api.network_create(self.context, **net) with self.context.session.begin(): for model in models: policy_mod = db_api.ip_policy_create(self.context, **model['ip_policy']) model['subnet']["network"] = net_mod model['subnet']["ip_policy"] = policy_mod db_api.subnet_create(self.context, **model['subnet']) yield net_mod
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 n_exc.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 n_exc.BadRequest( resource="ip_policy", msg="network_ids and subnet_ids specified. only one allowed") if not subnet_ids and not network_ids: raise n_exc.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 n_exc.SubnetNotFound(subnet_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 n_exc.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 test_ip_policies_update(self): ip_policy_dict = dict(exclude=["192.168.10.0/32", "192.168.10.255/32"]) ip_policy = db_api.ip_policy_create(self.context, **ip_policy_dict) new_exclude_first_last = dict() for cidr in ("192.168.10.0/32", "192.168.10.13/32", "192.168.10.255/32"): new_exclude_first_last[cidr] = netaddr.IPNetwork(cidr).ipv6().first updated_ip_policy = db_api.ip_policy_update( self.context, ip_policy, exclude=new_exclude_first_last.keys()) self.assertEqual(len(updated_ip_policy["exclude"]), 3) for ippc in updated_ip_policy["exclude"]: self.assertEqual(new_exclude_first_last[ippc["cidr"]], ippc["first_ip"]) self.assertEqual(new_exclude_first_last[ippc["cidr"]], ippc["last_ip"])
def _fixtures(self, models): self.ipam = quark.ipam.QuarkIpamANY() net = dict(name="public", tenant_id='fake') net_mod = db_api.network_create(self.context, **net) with self.context.session.begin(): for model in models: policy_mod = db_api.ip_policy_create(self.context, **model['ip_policy']) model['subnet']["network"] = net_mod model['subnet']["ip_policy"] = policy_mod next_ip = model['subnet'].pop("next_auto_assign_ip", 0) sub_mod = db_api.subnet_create(self.context, **model['subnet']) # NOTE(amir): update after cidr constructor has been invoked db_api.subnet_update(self.context, sub_mod, next_auto_assign_ip=next_ip) yield net_mod
def _fixtures(self, models): self.ipam = quark.ipam.QuarkIpamANY() net = dict(name="public", tenant_id='fake') net_mod = db_api.network_create(self.context, **net) with self.context.session.begin(): for model in models: policy_mod = db_api.ip_policy_create( self.context, **model['ip_policy']) model['subnet']["network"] = net_mod model['subnet']["ip_policy"] = policy_mod next_ip = model['subnet'].pop("next_auto_assign_ip", 0) sub_mod = db_api.subnet_create(self.context, **model['subnet']) # NOTE(amir): update after cidr constructor has been invoked db_api.subnet_update(self.context, sub_mod, next_auto_assign_ip=next_ip) yield net_mod
def create_subnet(context, subnet): """Create a subnet. Create a subnet which represents a range of IP addresses that can be allocated to devices : param context: neutron api request context : param subnet: dictionary describing the subnet, with keys as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. All keys will be populated. """ LOG.info("create_subnet for tenant %s" % context.tenant_id) net_id = subnet["subnet"]["network_id"] with context.session.begin(): net = db_api.network_find(context, id=net_id, scope=db_api.ONE) if not net: raise exceptions.NetworkNotFound(net_id=net_id) sub_attrs = subnet["subnet"] _validate_subnet_cidr(context, net_id, sub_attrs["cidr"]) cidr = netaddr.IPNetwork(sub_attrs["cidr"]) err_vals = {'cidr': sub_attrs["cidr"], 'network_id': net_id} err = _("Requested subnet with cidr: %(cidr)s for " "network: %(network_id)s. Prefix is too small, must be a " "larger subnet. A prefix less than /%(prefix)s is required.") if cidr.version == 6 and cidr.prefixlen > 64: err_vals["prefix"] = 65 err_msg = err % err_vals raise exceptions.InvalidInput(error_message=err_msg) elif cidr.version == 4 and cidr.prefixlen > 30: err_vals["prefix"] = 31 err_msg = err % err_vals raise exceptions.InvalidInput(error_message=err_msg) gateway_ip = utils.pop_param(sub_attrs, "gateway_ip", str(cidr[1])) dns_ips = utils.pop_param(sub_attrs, "dns_nameservers", []) host_routes = utils.pop_param(sub_attrs, "host_routes", []) allocation_pools = utils.pop_param(sub_attrs, "allocation_pools", None) if not context.is_admin and "segment_id" in sub_attrs: sub_attrs.pop("segment_id") sub_attrs["network"] = net new_subnet = db_api.subnet_create(context, **sub_attrs) default_route = None for route in host_routes: netaddr_route = netaddr.IPNetwork(route["destination"]) if netaddr_route.value == routes.DEFAULT_ROUTE.value: if default_route: raise q_exc.DuplicateRouteConflict( subnet_id=new_subnet["id"]) default_route = route gateway_ip = default_route["nexthop"] new_subnet["routes"].append(db_api.route_create( context, cidr=route["destination"], gateway=route["nexthop"])) if gateway_ip and default_route is None: new_subnet["routes"].append(db_api.route_create( context, cidr=str(routes.DEFAULT_ROUTE), gateway=gateway_ip)) for dns_ip in dns_ips: new_subnet["dns_nameservers"].append(db_api.dns_create( context, ip=netaddr.IPAddress(dns_ip))) if isinstance(allocation_pools, list) and allocation_pools: subnet_net = netaddr.IPNetwork(new_subnet["cidr"]) cidrset = netaddr.IPSet( netaddr.IPRange( netaddr.IPAddress(subnet_net.first), netaddr.IPAddress(subnet_net.last)).cidrs()) for p in allocation_pools: start = netaddr.IPAddress(p["start"]) end = netaddr.IPAddress(p["end"]) cidrset -= netaddr.IPSet(netaddr.IPRange( netaddr.IPAddress(start), netaddr.IPAddress(end)).cidrs()) default_cidrset = models.IPPolicy.get_ip_policy_cidrs(new_subnet) cidrset.update(default_cidrset) cidrs = [str(x.cidr) for x in cidrset.iter_cidrs()] new_subnet["ip_policy"] = db_api.ip_policy_create(context, exclude=cidrs) subnet_dict = v._make_subnet_dict(new_subnet) subnet_dict["gateway_ip"] = gateway_ip notifier_api.notify(context, notifier_api.publisher_id("network"), "ip_block.create", notifier_api.CONF.default_notification_level, dict(tenant_id=subnet_dict["tenant_id"], ip_block_id=subnet_dict["id"], created_at=new_subnet["created_at"])) return subnet_dict
def create_subnet(context, subnet): """Create a subnet. Create a subnet which represents a range of IP addresses that can be allocated to devices : param context: neutron api request context : param subnet: dictionary describing the subnet, with keys as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. All keys will be populated. """ LOG.info("create_subnet for tenant %s" % context.tenant_id) net_id = subnet["subnet"]["network_id"] with context.session.begin(): net = db_api.network_find(context, None, None, None, False, id=net_id, scope=db_api.ONE) if not net: raise exceptions.NetworkNotFound(net_id=net_id) sub_attrs = subnet["subnet"] always_pop = ["enable_dhcp", "ip_version", "first_ip", "last_ip", "_cidr"] admin_only = ["segment_id", "do_not_use", "created_at", "next_auto_assign_ip"] utils.filter_body(context, sub_attrs, admin_only, always_pop) _validate_subnet_cidr(context, net_id, sub_attrs["cidr"]) cidr = netaddr.IPNetwork(sub_attrs["cidr"]) err_vals = {'cidr': sub_attrs["cidr"], 'network_id': net_id} err = _("Requested subnet with cidr: %(cidr)s for " "network: %(network_id)s. Prefix is too small, must be a " "larger subnet. A prefix less than /%(prefix)s is required.") if cidr.version == 6 and cidr.prefixlen > 64: err_vals["prefix"] = 65 err_msg = err % err_vals raise exceptions.InvalidInput(error_message=err_msg) elif cidr.version == 4 and cidr.prefixlen > 30: err_vals["prefix"] = 31 err_msg = err % err_vals raise exceptions.InvalidInput(error_message=err_msg) # Enforce subnet quotas net_subnets = get_subnets(context, filters=dict(network_id=net_id)) if not context.is_admin: v4_count, v6_count = 0, 0 for subnet in net_subnets: if netaddr.IPNetwork(subnet['cidr']).version == 6: v6_count += 1 else: v4_count += 1 if cidr.version == 6: tenant_quota_v6 = context.session.query(qdv.Quota).filter_by( tenant_id=context.tenant_id, resource='v6_subnets_per_network').first() if tenant_quota_v6 != -1: quota.QUOTAS.limit_check( context, context.tenant_id, v6_subnets_per_network=v6_count + 1) else: tenant_quota_v4 = context.session.query(qdv.Quota).filter_by( tenant_id=context.tenant_id, resource='v4_subnets_per_network').first() if tenant_quota_v4 != -1: quota.QUOTAS.limit_check( context, context.tenant_id, v4_subnets_per_network=v4_count + 1) # See RM981. The default behavior of setting a gateway unless # explicitly asked to not is no longer desirable. gateway_ip = utils.pop_param(sub_attrs, "gateway_ip") dns_ips = utils.pop_param(sub_attrs, "dns_nameservers", []) host_routes = utils.pop_param(sub_attrs, "host_routes", []) allocation_pools = utils.pop_param(sub_attrs, "allocation_pools", None) sub_attrs["network"] = net new_subnet = db_api.subnet_create(context, **sub_attrs) cidrs = [] alloc_pools = allocation_pool.AllocationPools(sub_attrs["cidr"], allocation_pools) if isinstance(allocation_pools, list): cidrs = alloc_pools.get_policy_cidrs() quota.QUOTAS.limit_check( context, context.tenant_id, alloc_pools_per_subnet=len(alloc_pools)) ip_policies.ensure_default_policy(cidrs, [new_subnet]) new_subnet["ip_policy"] = db_api.ip_policy_create(context, exclude=cidrs) quota.QUOTAS.limit_check(context, context.tenant_id, routes_per_subnet=len(host_routes)) default_route = None for route in host_routes: netaddr_route = netaddr.IPNetwork(route["destination"]) if netaddr_route.value == routes.DEFAULT_ROUTE.value: if default_route: raise q_exc.DuplicateRouteConflict( subnet_id=new_subnet["id"]) default_route = route gateway_ip = default_route["nexthop"] alloc_pools.validate_gateway_excluded(gateway_ip) new_subnet["routes"].append(db_api.route_create( context, cidr=route["destination"], gateway=route["nexthop"])) quota.QUOTAS.limit_check(context, context.tenant_id, dns_nameservers_per_subnet=len(dns_ips)) for dns_ip in dns_ips: new_subnet["dns_nameservers"].append(db_api.dns_create( context, ip=netaddr.IPAddress(dns_ip))) # if the gateway_ip is IN the cidr for the subnet and NOT excluded by # policies, we should raise a 409 conflict if gateway_ip and default_route is None: alloc_pools.validate_gateway_excluded(gateway_ip) new_subnet["routes"].append(db_api.route_create( context, cidr=str(routes.DEFAULT_ROUTE), gateway=gateway_ip)) subnet_dict = v._make_subnet_dict(new_subnet) subnet_dict["gateway_ip"] = gateway_ip n_rpc.get_notifier("network").info( context, "ip_block.create", dict(tenant_id=subnet_dict["tenant_id"], ip_block_id=subnet_dict["id"], created_at=new_subnet["created_at"])) return subnet_dict
def create_subnet(context, subnet): """Create a subnet. Create a subnet which represents a range of IP addresses that can be allocated to devices : param context: neutron api request context : param subnet: dictionary describing the subnet, with keys as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. All keys will be populated. """ LOG.info("create_subnet for tenant %s" % context.tenant_id) net_id = subnet["subnet"]["network_id"] with context.session.begin(): net = db_api.network_find(context, None, None, None, False, id=net_id, scope=db_api.ONE) if not net: raise exceptions.NetworkNotFound(net_id=net_id) sub_attrs = subnet["subnet"] always_pop = [ "enable_dhcp", "ip_version", "first_ip", "last_ip", "_cidr" ] admin_only = [ "segment_id", "do_not_use", "created_at", "next_auto_assign_ip" ] utils.filter_body(context, sub_attrs, admin_only, always_pop) _validate_subnet_cidr(context, net_id, sub_attrs["cidr"]) cidr = netaddr.IPNetwork(sub_attrs["cidr"]) err_vals = {'cidr': sub_attrs["cidr"], 'network_id': net_id} err = _("Requested subnet with cidr: %(cidr)s for " "network: %(network_id)s. Prefix is too small, must be a " "larger subnet. A prefix less than /%(prefix)s is required.") if cidr.version == 6 and cidr.prefixlen > 64: err_vals["prefix"] = 65 err_msg = err % err_vals raise exceptions.InvalidInput(error_message=err_msg) elif cidr.version == 4 and cidr.prefixlen > 30: err_vals["prefix"] = 31 err_msg = err % err_vals raise exceptions.InvalidInput(error_message=err_msg) # Enforce subnet quotas net_subnets = get_subnets(context, filters=dict(network_id=net_id)) if not context.is_admin: v4_count, v6_count = 0, 0 for subnet in net_subnets: if netaddr.IPNetwork(subnet['cidr']).version == 6: v6_count += 1 else: v4_count += 1 if cidr.version == 6: tenant_quota_v6 = context.session.query(qdv.Quota).filter_by( tenant_id=context.tenant_id, resource='v6_subnets_per_network').first() if tenant_quota_v6 != -1: quota.QUOTAS.limit_check(context, context.tenant_id, v6_subnets_per_network=v6_count + 1) else: tenant_quota_v4 = context.session.query(qdv.Quota).filter_by( tenant_id=context.tenant_id, resource='v4_subnets_per_network').first() if tenant_quota_v4 != -1: quota.QUOTAS.limit_check(context, context.tenant_id, v4_subnets_per_network=v4_count + 1) # See RM981. The default behavior of setting a gateway unless # explicitly asked to not is no longer desirable. gateway_ip = utils.pop_param(sub_attrs, "gateway_ip") dns_ips = utils.pop_param(sub_attrs, "dns_nameservers", []) host_routes = utils.pop_param(sub_attrs, "host_routes", []) allocation_pools = utils.pop_param(sub_attrs, "allocation_pools", None) sub_attrs["network"] = net new_subnet = db_api.subnet_create(context, **sub_attrs) cidrs = [] alloc_pools = allocation_pool.AllocationPools(sub_attrs["cidr"], allocation_pools) if isinstance(allocation_pools, list): cidrs = alloc_pools.get_policy_cidrs() quota.QUOTAS.limit_check(context, context.tenant_id, alloc_pools_per_subnet=len(alloc_pools)) ip_policies.ensure_default_policy(cidrs, [new_subnet]) new_subnet["ip_policy"] = db_api.ip_policy_create(context, exclude=cidrs) quota.QUOTAS.limit_check(context, context.tenant_id, routes_per_subnet=len(host_routes)) default_route = None for route in host_routes: netaddr_route = netaddr.IPNetwork(route["destination"]) if netaddr_route.value == routes.DEFAULT_ROUTE.value: if default_route: raise q_exc.DuplicateRouteConflict( subnet_id=new_subnet["id"]) default_route = route gateway_ip = default_route["nexthop"] alloc_pools.validate_gateway_excluded(gateway_ip) new_subnet["routes"].append( db_api.route_create(context, cidr=route["destination"], gateway=route["nexthop"])) quota.QUOTAS.limit_check(context, context.tenant_id, dns_nameservers_per_subnet=len(dns_ips)) for dns_ip in dns_ips: new_subnet["dns_nameservers"].append( db_api.dns_create(context, ip=netaddr.IPAddress(dns_ip))) # if the gateway_ip is IN the cidr for the subnet and NOT excluded by # policies, we should raise a 409 conflict if gateway_ip and default_route is None: alloc_pools.validate_gateway_excluded(gateway_ip) new_subnet["routes"].append( db_api.route_create(context, cidr=str(routes.DEFAULT_ROUTE), gateway=gateway_ip)) subnet_dict = v._make_subnet_dict(new_subnet) subnet_dict["gateway_ip"] = gateway_ip n_rpc.get_notifier("network").info( context, "ip_block.create", dict(tenant_id=subnet_dict["tenant_id"], ip_block_id=subnet_dict["id"], created_at=new_subnet["created_at"])) return subnet_dict
def create_subnet(context, subnet): """Create a subnet. Create a subnet which represents a range of IP addresses that can be allocated to devices : param context: neutron api request context : param subnet: dictionary describing the subnet, with keys as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. All keys will be populated. """ LOG.info("create_subnet for tenant %s" % context.tenant_id) net_id = subnet["subnet"]["network_id"] with context.session.begin(): net = db_api.network_find(context, id=net_id, scope=db_api.ONE) if not net: raise exceptions.NetworkNotFound(net_id=net_id) sub_attrs = subnet["subnet"] _validate_subnet_cidr(context, net_id, sub_attrs["cidr"]) cidr = netaddr.IPNetwork(sub_attrs["cidr"]) gateway_ip = utils.pop_param(sub_attrs, "gateway_ip", str(cidr[1])) dns_ips = utils.pop_param(sub_attrs, "dns_nameservers", []) host_routes = utils.pop_param(sub_attrs, "host_routes", []) allocation_pools = utils.pop_param(sub_attrs, "allocation_pools", None) sub_attrs["network"] = net new_subnet = db_api.subnet_create(context, **sub_attrs) 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 gateway_ip = default_route["nexthop"] new_subnet["routes"].append(db_api.route_create( context, cidr=route["destination"], gateway=route["nexthop"])) if default_route is None: new_subnet["routes"].append(db_api.route_create( context, cidr=str(routes.DEFAULT_ROUTE), gateway=gateway_ip)) for dns_ip in dns_ips: new_subnet["dns_nameservers"].append(db_api.dns_create( context, ip=netaddr.IPAddress(dns_ip))) if isinstance(allocation_pools, list): ranges = [] cidrset = netaddr.IPSet([netaddr.IPNetwork(new_subnet["cidr"])]) for p in allocation_pools: cidrset -= netaddr.IPSet(netaddr.IPRange(p["start"], p["end"])) non_allocation_pools = v._pools_from_cidr(cidrset) for p in non_allocation_pools: r = netaddr.IPRange(p["start"], p["end"]) ranges.append(dict( length=len(r), offset=int(r[0]) - int(cidr[0]))) new_subnet["ip_policy"] = db_api.ip_policy_create(context, exclude=ranges) subnet_dict = v._make_subnet_dict(new_subnet, default_route=routes.DEFAULT_ROUTE) subnet_dict["gateway_ip"] = gateway_ip notifier_api.notify(context, notifier_api.publisher_id("network"), "ip_block.create", notifier_api.CONF.default_notification_level, dict(tenant_id=subnet_dict["tenant_id"], ip_block_id=subnet_dict["id"], created_at=new_subnet["created_at"])) return subnet_dict
def create_subnet(context, subnet): """Create a subnet. Create a subnet which represents a range of IP addresses that can be allocated to devices : param context: neutron api request context : param subnet: dictionary describing the subnet, with keys as listed in the RESOURCE_ATTRIBUTE_MAP object in neutron/api/v2/attributes.py. All keys will be populated. """ LOG.info("create_subnet for tenant %s" % context.tenant_id) net_id = subnet["subnet"]["network_id"] net = db_api.network_find(context, id=net_id, scope=db_api.ONE) if not net: raise exceptions.NetworkNotFound(net_id=net_id) sub_attrs = subnet["subnet"] _validate_subnet_cidr(context, net_id, sub_attrs["cidr"]) cidr = netaddr.IPNetwork(sub_attrs["cidr"]) gateway_ip = utils.pop_param(sub_attrs, "gateway_ip", str(cidr[1])) dns_ips = utils.pop_param(sub_attrs, "dns_nameservers", []) host_routes = utils.pop_param(sub_attrs, "host_routes", []) allocation_pools = utils.pop_param(sub_attrs, "allocation_pools", []) sub_attrs["network"] = net new_subnet = db_api.subnet_create(context, **sub_attrs) 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 gateway_ip = default_route["nexthop"] new_subnet["routes"].append( db_api.route_create(context, cidr=route["destination"], gateway=route["nexthop"])) if default_route is None: new_subnet["routes"].append( db_api.route_create(context, cidr=str(routes.DEFAULT_ROUTE), gateway=gateway_ip)) for dns_ip in dns_ips: new_subnet["dns_nameservers"].append( db_api.dns_create(context, ip=netaddr.IPAddress(dns_ip))) if allocation_pools: exclude = netaddr.IPSet([cidr]) for p in allocation_pools: x = netaddr.IPSet(netaddr.IPRange(p["start"], p["end"])) exclude = exclude - x new_subnet["ip_policy"] = db_api.ip_policy_create(context, exclude=exclude) subnet_dict = v._make_subnet_dict(new_subnet, default_route=routes.DEFAULT_ROUTE) subnet_dict["gateway_ip"] = gateway_ip return subnet_dict
def test_ip_policies_create(self): ip_policy_dict = dict(exclude=["192.168.10.0/32", "192.168.10.255/32"]) ip_policy = db_api.ip_policy_create(self.context, **ip_policy_dict) self.assertEqual(ip_policy["size"], 2)