Files
quark/quark/plugin_modules/ip_policies.py
Amir Sadoughi 30d4da4a37 Fix oslo imports
sed -i 's/oslo\./oslo_/g' $f
2015-07-01 00:38:14 -05:00

225 lines
8.6 KiB
Python

# Copyright 2013 Openstack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import netaddr
from neutron.common import exceptions
from oslo_config import cfg
from oslo_log import log as logging
from quark import allocation_pool
from quark.db import api as db_api
from quark import exceptions as quark_exceptions
from quark import plugin_views as v
CONF = cfg.CONF
LOG = logging.getLogger(__name__)
def _validate_policy_with_routes(context, policies, subnets):
pools = {}
policy_networks = [netaddr.IPNetwork(p) for p in policies]
for subnet in subnets:
pool = allocation_pool.AllocationPools(subnet["cidr"],
policies=policy_networks)
pools[subnet["id"]] = pool
subnet_ids = [subnet["id"] for subnet in subnets]
routes = db_api.route_find(context, subnet_id=subnet_ids)
for route in routes:
subnet_pool = pools[route["subnet_id"]]
subnet_pool.validate_gateway_excluded(route["gateway"])
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 _check_for_pre_existing_policies_in(models):
models_with_existing_policies = [model for model in models
if model.get('ip_policy', None)]
if models_with_existing_policies:
first_model = models_with_existing_policies[0]
raise quark_exceptions.IPPolicyAlreadyExists(
id=first_model['ip_policy']['id'],
n_id=first_model['id'])
def get_ip_policy(context, id):
LOG.info("get_ip_policy %s for tenant %s" % (id, context.tenant_id))
ipp = db_api.ip_policy_find(context, id=id, scope=db_api.ONE)
if not ipp:
raise quark_exceptions.IPPolicyNotFound(id=id)
return v._make_ip_policy_dict(ipp)
def get_ip_policies(context, **filters):
LOG.info("get_ip_policies for tenant %s" % (context.tenant_id))
ipps = db_api.ip_policy_find(context, scope=db_api.ALL, **filters)
return [v._make_ip_policy_dict(ipp) for ipp in ipps]
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 delete_ip_policy(context, id):
LOG.info("delete_ip_policy %s for tenant %s" % (id, context.tenant_id))
with context.session.begin():
ipp = db_api.ip_policy_find(context, id=id, scope=db_api.ONE)
if not ipp:
raise quark_exceptions.IPPolicyNotFound(id=id)
if ipp["networks"] or ipp["subnets"]:
raise quark_exceptions.IPPolicyInUse(id=id)
db_api.ip_policy_delete(context, ipp)
def _validate_cidrs_fit_into_subnets(cidrs, subnets):
LOG.info("validate_cidrs_all_fit_into_subnets with CIDRs (%s) "
"and subnets (%s)" % (cidrs, subnets))
for cidr in cidrs:
cidr = netaddr.IPNetwork(cidr)
for subnet in subnets:
subnet_cidr = netaddr.IPNetwork(subnet["cidr"])
if cidr.version == subnet_cidr.version and cidr not in subnet_cidr:
raise exceptions.BadRequest(
resource="ip_policy",
msg="CIDR %s not in subnet CIDR %s"
% (cidr, subnet_cidr))
def ensure_default_policy(cidrs, subnets):
policy_cidrs = netaddr.IPSet(cidrs)
for subnet in subnets:
subnet_cidr = netaddr.IPNetwork(subnet["cidr"])
network_ip = subnet_cidr.network
broadcast_ip = subnet_cidr.broadcast
prefix_len = '32' if subnet_cidr.version == 4 else '128'
default_policy_cidrs = ["%s/%s" % (network_ip, prefix_len),
"%s/%s" % (broadcast_ip, prefix_len)]
for cidr in default_policy_cidrs:
if (netaddr.IPNetwork(cidr) not in policy_cidrs
and cidr not in cidrs):
cidrs.append(cidr)