add proxy ip pool to proxy group extension
As part of the proxy group extension, a new proxy_ip_pool attribute is added to the L3Policy object. This attribute defines the pool from which proxy PTG subnets should be generated. Partially implements blueprint node-centric-chain-plugin Change-Id: I65f35457f2cc229999fe197a46e4ee4191f59eeb
This commit is contained in:
parent
090f94a381
commit
a08befaf87
|
@ -36,4 +36,14 @@ class ProxyGatewayMapping(model_base.BASEV2):
|
|||
sa.String(36), sa.ForeignKey('gp_policy_targets.id',
|
||||
ondelete="CASCADE"), primary_key=True)
|
||||
proxy_gateway = sa.Column(sa.Boolean, nullable=False)
|
||||
group_default_gateway = sa.Column(sa.Boolean, nullable=False)
|
||||
group_default_gateway = sa.Column(sa.Boolean, nullable=False)
|
||||
|
||||
|
||||
class ProxyIPPoolMapping(model_base.BASEV2):
|
||||
__tablename__ = 'gp_proxy_ip_pool_mapping'
|
||||
|
||||
l3_policy_id = sa.Column(
|
||||
sa.String(36), sa.ForeignKey('gp_l3_policies.id', ondelete="CASCADE"),
|
||||
primary_key=True)
|
||||
proxy_ip_pool = sa.Column(sa.String(64), nullable=False)
|
||||
proxy_subnet_prefix_length = sa.Column(sa.Integer, nullable=False)
|
||||
|
|
|
@ -1087,11 +1087,14 @@ class GroupPolicyDbPlugin(gpolicy.GroupPolicyPluginBase,
|
|||
@staticmethod
|
||||
def validate_ip_pool(ip_pool, ip_version):
|
||||
attr._validate_subnet(ip_pool)
|
||||
ip_net = netaddr.IPNetwork(ip_pool, version=ip_version)
|
||||
ip_net = netaddr.IPNetwork(ip_pool)
|
||||
if ip_net.version != ip_version:
|
||||
raise gpolicy.InvalidIpPoolVersion(ip_pool=ip_pool,
|
||||
version=ip_version)
|
||||
if (ip_net.size <= 3):
|
||||
err_msg = "Too few available IPs in the pool."
|
||||
raise gpolicy.InvalidIpPoolSize(ip_pool=ip_pool, err_msg=err_msg,
|
||||
size=ip_net.size)
|
||||
size=ip_net.size)
|
||||
|
||||
if (ip_net.prefixlen == 0):
|
||||
err_msg = "Prefix length of 0 is invalid."
|
||||
|
|
|
@ -59,6 +59,18 @@ def upgrade():
|
|||
name='group_proxy_mapping_fk_ptg_id'),
|
||||
)
|
||||
|
||||
op.create_table(
|
||||
'gp_proxy_ip_pool_mapping',
|
||||
sa.Column('l3_policy_id', sa.String(length=36), nullable=False),
|
||||
sa.Column('proxy_ip_pool', sa.String(length=64), nullable=False),
|
||||
sa.Column('proxy_subnet_prefix_length', sa.Integer, nullable=False),
|
||||
|
||||
sa.PrimaryKeyConstraint('l3_policy_id'),
|
||||
sa.ForeignKeyConstraint(['l3_policy_id'], ['gp_l3_policies.id'],
|
||||
ondelete='CASCADE',
|
||||
name='proxy_ip_pool_mapping_fk_l3_policy_id'),
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
pass
|
||||
|
|
|
@ -54,6 +54,20 @@ EXTENDED_ATTRIBUTES_2_0 = {
|
|||
'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid_or_none': None}, 'is_visible': True,
|
||||
'enforce_policy': True},
|
||||
# TODO(ivar): The APIs should allow the creation of a group with a
|
||||
# custom subnet prefix length. It may be useful for both the proxy
|
||||
# groups and traditional ones.
|
||||
},
|
||||
gp.L3_POLICIES: {
|
||||
'proxy_ip_pool': {'allow_post': True, 'allow_put': False,
|
||||
'validate': {'type:subnet': None},
|
||||
'default': '192.168.0.0/16', 'is_visible': True},
|
||||
'proxy_subnet_prefix_length': {'allow_post': True, 'allow_put': True,
|
||||
'convert_to': attr.convert_to_int,
|
||||
# for ipv4 legal values are 2 to 30
|
||||
# for ipv6 legal values are 2 to 127
|
||||
'default': 29, 'is_visible': True},
|
||||
# Proxy IP version is the same as the standard L3 pool ip version
|
||||
},
|
||||
gp.POLICY_TARGETS: {
|
||||
# This policy target will be used to reach the -proxied- PTG
|
||||
|
@ -94,7 +108,7 @@ class Driver_proxy_group(extensions.ExtensionDescriptor):
|
|||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
return "2015-07-31T10:00:00-00:00"
|
||||
return "2015-08-03T10:00:00-00:00"
|
||||
|
||||
def get_extended_resources(self, version):
|
||||
if version == "2.0":
|
||||
|
|
|
@ -92,7 +92,7 @@ class NetworkServicePolicyNotFound(nexc.NotFound):
|
|||
|
||||
|
||||
class InvalidDefaultSubnetPrefixLength(nexc.InvalidInput):
|
||||
message = _("Default subnet prefix length %(length)s is invalid for"
|
||||
message = _("Default subnet prefix length %(length)s is invalid for "
|
||||
"ipv%(protocol)s")
|
||||
|
||||
|
||||
|
@ -111,6 +111,10 @@ class InvalidIpPoolPrefixLength(nexc.InvalidInput):
|
|||
"Prefix Length=%(prefixlen)s")
|
||||
|
||||
|
||||
class InvalidIpPoolVersion(nexc.InvalidInput):
|
||||
message = _("%(ip_pool)s is not a ipv%(version)s address.")
|
||||
|
||||
|
||||
class PolicyClassifierNotFound(nexc.NotFound):
|
||||
message = _("PolicyClassifier %(policy_classifier_id)s could not be found")
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ from neutron.api.v2 import attributes
|
|||
from oslo_log import log as logging
|
||||
|
||||
from gbpservice.neutron.db.grouppolicy.extensions import group_proxy_db as db
|
||||
from gbpservice.neutron.db.grouppolicy import group_policy_db as gp_db
|
||||
from gbpservice.neutron.extensions import driver_proxy_group
|
||||
from gbpservice.neutron.services.grouppolicy import (
|
||||
group_policy_driver_api as api)
|
||||
|
@ -90,4 +91,25 @@ class ProxyGroupDriver(api.ExtensionDriver):
|
|||
if not record:
|
||||
# The group of this PT is not a proxy
|
||||
raise driver_proxy_group.InvalidProxyGatewayGroup(
|
||||
group_id=ptg_id)
|
||||
group_id=ptg_id)
|
||||
|
||||
@api.default_extension_behavior(db.ProxyIPPoolMapping)
|
||||
def process_create_l3_policy(self, session, data, result):
|
||||
data = data['l3_policy']
|
||||
gp_db.GroupPolicyDbPlugin.validate_ip_pool(
|
||||
data['proxy_ip_pool'], data['ip_version'])
|
||||
gp_db.GroupPolicyDbPlugin.validate_subnet_prefix_length(
|
||||
data['ip_version'], data['proxy_subnet_prefix_length'],
|
||||
data['proxy_ip_pool'])
|
||||
|
||||
@api.default_extension_behavior(db.ProxyIPPoolMapping)
|
||||
def process_update_l3_policy(self, session, data, result):
|
||||
data = data['l3_policy']
|
||||
if 'proxy_subnet_prefix_length' in data:
|
||||
gp_db.GroupPolicyDbPlugin.validate_subnet_prefix_length(
|
||||
result['ip_version'], data['proxy_subnet_prefix_length'],
|
||||
result['proxy_ip_pool'])
|
||||
|
||||
@api.default_extension_behavior(db.ProxyIPPoolMapping)
|
||||
def extend_l3_policy_dict(self, session, result):
|
||||
pass
|
||||
|
|
|
@ -72,6 +72,7 @@ class ExtensionManager(stevedore.named.NamedExtensionManager):
|
|||
try:
|
||||
getattr(driver.obj, method_name)(session, data, result)
|
||||
except (gp_exc.GroupPolicyException, n_exc.NeutronException):
|
||||
# This is an exception for the user.
|
||||
raise
|
||||
except Exception:
|
||||
LOG.exception(
|
||||
|
|
|
@ -24,11 +24,22 @@ class ExtensionDriverTestCase(test_ext_base.ExtensionDriverTestBase):
|
|||
_extension_path = None
|
||||
|
||||
def test_proxy_group_extension(self):
|
||||
ptg = self.create_policy_target_group()['policy_target_group']
|
||||
l3p = self.create_l3_policy()['l3_policy']
|
||||
self.assertEqual('192.168.0.0/16', l3p['proxy_ip_pool'])
|
||||
self.assertEqual(29, l3p['proxy_subnet_prefix_length'])
|
||||
|
||||
l2p = self.create_l2_policy(l3_policy_id=l3p['id'])['l2_policy']
|
||||
ptg = self.create_policy_target_group(
|
||||
l2_policy_id=l2p['id'])['policy_target_group']
|
||||
self.assertIsNone(ptg['proxy_group_id'])
|
||||
self.assertIsNone(ptg['proxied_group_id'])
|
||||
self.assertIsNone(ptg['proxy_type'])
|
||||
|
||||
# Verify Default L3P pool mapping on show
|
||||
l3p = self.show_l3_policy(l3p['id'])['l3_policy']
|
||||
self.assertEqual('192.168.0.0/16', l3p['proxy_ip_pool'])
|
||||
self.assertEqual(29, l3p['proxy_subnet_prefix_length'])
|
||||
|
||||
ptg_proxy = self.create_policy_target_group(
|
||||
proxied_group_id=ptg['id'])['policy_target_group']
|
||||
self.assertIsNone(ptg_proxy['proxy_group_id'])
|
||||
|
@ -141,3 +152,27 @@ class ExtensionDriverTestCase(test_ext_base.ExtensionDriverTestBase):
|
|||
expected_res_status=400)
|
||||
self.assertEqual('InvalidProxyGatewayGroup',
|
||||
res['NeutronError']['type'])
|
||||
|
||||
def test_proxy_pool_invalid_prefix_length(self):
|
||||
l3p = self.create_l3_policy(proxy_subnet_prefix_length=29)['l3_policy']
|
||||
res = self.update_l3_policy(l3p['id'], proxy_subnet_prefix_length=32,
|
||||
expected_res_status=400)
|
||||
self.assertEqual('InvalidDefaultSubnetPrefixLength',
|
||||
res['NeutronError']['type'])
|
||||
|
||||
# Verify change didn't persist
|
||||
l3p = self.show_l3_policy(l3p['id'])['l3_policy']
|
||||
self.assertEqual(29, l3p['proxy_subnet_prefix_length'])
|
||||
|
||||
# Verify it fails in creation
|
||||
res = self.create_l3_policy(
|
||||
proxy_subnet_prefix_length=32, expected_res_status=400)
|
||||
self.assertEqual('InvalidDefaultSubnetPrefixLength',
|
||||
res['NeutronError']['type'])
|
||||
|
||||
def test_proxy_pool_invalid_version(self):
|
||||
# proxy_ip_pool is of a different version
|
||||
res = self.create_l3_policy(ip_version=6, ip_pool='1::1/16',
|
||||
proxy_ip_pool='192.168.0.0/16',
|
||||
expected_res_status=400)
|
||||
self.assertEqual('InvalidIpPoolVersion', res['NeutronError']['type'])
|
||||
|
|
Loading…
Reference in New Issue