Support IP protocol Numbers in GBP
Change-Id: I5ad04fe00e1466b8b054f3b107bc81b4e9df2334 Closes-Bug: #1499916
This commit is contained in:
parent
0777b6836e
commit
346a760f51
|
@ -12,7 +12,6 @@
|
|||
|
||||
import netaddr
|
||||
from neutron.api.v2 import attributes as attr
|
||||
from neutron.common import constants
|
||||
from neutron.common import log
|
||||
from neutron import context
|
||||
from neutron.db import common_db_mixin
|
||||
|
@ -244,11 +243,7 @@ class PolicyClassifier(gquota.GBPQuotaBase, model_base.BASEV2, models_v2.HasId,
|
|||
__tablename__ = 'gp_policy_classifiers'
|
||||
name = sa.Column(sa.String(50))
|
||||
description = sa.Column(sa.String(255))
|
||||
protocol = sa.Column(sa.Enum(constants.PROTO_NAME_TCP,
|
||||
constants.PROTO_NAME_UDP,
|
||||
constants.PROTO_NAME_ICMP,
|
||||
name="protocol_type"),
|
||||
nullable=True)
|
||||
protocol = sa.Column(sa.String(50), nullable=True)
|
||||
port_range_min = sa.Column(sa.Integer)
|
||||
port_range_max = sa.Column(sa.Integer)
|
||||
direction = sa.Column(sa.Enum(gp_constants.GP_DIRECTION_IN,
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
# Copyright 2014 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
"""gp_classifier_protocol_string
|
||||
|
||||
Revision ID: 5a24894af57c
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '5a24894af57c'
|
||||
down_revision = '4121adfbac30'
|
||||
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
|
||||
op.alter_column('gp_policy_classifiers', 'protocol',
|
||||
existing_type=sa.Enum('tcp', 'udp', 'icmp'),
|
||||
type_=sa.String(length=50))
|
||||
|
||||
|
||||
def downgrade():
|
||||
pass
|
|
@ -1 +1 @@
|
|||
4121adfbac30
|
||||
5a24894af57c
|
|
@ -541,8 +541,7 @@ RESOURCE_ATTRIBUTE_MAP = {
|
|||
'is_visible': True},
|
||||
'protocol': {'allow_post': True, 'allow_put': True,
|
||||
'is_visible': True, 'default': None,
|
||||
'convert_to': convert_protocol,
|
||||
'validate': {'type:values': gp_supported_protocols}},
|
||||
'convert_to': convert_protocol},
|
||||
'port_range': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:gbp_port_range': None},
|
||||
'convert_to': convert_port_to_string,
|
||||
|
|
|
@ -819,6 +819,28 @@ class TestGroupResources(GroupPolicyDbTestCase):
|
|||
self._test_show_resource('policy_classifier',
|
||||
pc['policy_classifier']['id'], attrs)
|
||||
|
||||
def test_classifier_with_protocol_number(self):
|
||||
name = 'pc1'
|
||||
protocol = '55'
|
||||
|
||||
attrs = cm.get_create_policy_classifier_default_attrs(
|
||||
name=name, protocol=protocol)
|
||||
pc = self.create_policy_classifier(name=name, protocol=protocol)
|
||||
|
||||
for k, v in attrs.iteritems():
|
||||
self.assertEqual(pc['policy_classifier'][k], v)
|
||||
|
||||
req = self.new_show_request('policy_classifiers',
|
||||
pc['policy_classifier']['id'],
|
||||
fmt=self.fmt)
|
||||
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
|
||||
|
||||
for k, v in attrs.iteritems():
|
||||
self.assertEqual(res['policy_classifier'][k], v)
|
||||
|
||||
self._test_show_resource('policy_classifier',
|
||||
pc['policy_classifier']['id'], attrs)
|
||||
|
||||
def test_list_policy_classifiers(self):
|
||||
policy_classifiers = [
|
||||
self.create_policy_classifier(name='pc1', description='pc'),
|
||||
|
@ -852,6 +874,31 @@ class TestGroupResources(GroupPolicyDbTestCase):
|
|||
self._test_show_resource('policy_classifier',
|
||||
pc['policy_classifier']['id'], attrs)
|
||||
|
||||
def test_update_policy_classifier_with_protocol_number(self):
|
||||
name = "new_policy_classifier"
|
||||
description = 'new desc'
|
||||
protocol = '50'
|
||||
port_range = '100:200'
|
||||
direction = 'in'
|
||||
attrs = cm.get_create_policy_classifier_default_attrs(
|
||||
name=name, description=description, protocol=protocol,
|
||||
port_range=port_range, direction=direction)
|
||||
|
||||
pc = self.create_policy_classifier()
|
||||
data = {'policy_classifier': {'name': name, 'description': description,
|
||||
'protocol': protocol, 'port_range':
|
||||
port_range, 'direction': direction}}
|
||||
|
||||
req = self.new_update_request('policy_classifiers', data,
|
||||
pc['policy_classifier']['id'])
|
||||
res = self.deserialize(self.fmt, req.get_response(self.ext_api))
|
||||
|
||||
for k, v in attrs.iteritems():
|
||||
self.assertEqual(res['policy_classifier'][k], v)
|
||||
|
||||
self._test_show_resource('policy_classifier',
|
||||
pc['policy_classifier']['id'], attrs)
|
||||
|
||||
def test_delete_policy_classifier(self):
|
||||
ctx = context.get_admin_context()
|
||||
|
||||
|
|
|
@ -326,18 +326,22 @@ class ResourceMappingTestCase(test_plugin.GroupPolicyPluginTestCase):
|
|||
attrs = {'security_group_id': [provided_sg],
|
||||
'direction': ['ingress'],
|
||||
'protocol': [protocol],
|
||||
'port_range_min': [port_min],
|
||||
'port_range_max': [port_max],
|
||||
'remote_ip_prefix': [cidr]}
|
||||
if port_min is not None:
|
||||
attrs['port_range_min'] = [port_min]
|
||||
if port_max is not None:
|
||||
attrs['port_range_max'] = [port_max]
|
||||
expected_rules.append(attrs)
|
||||
# And consumer SG have egress allowed
|
||||
for cidr in providers:
|
||||
attrs = {'security_group_id': [consumed_sg],
|
||||
'direction': ['egress'],
|
||||
'protocol': [protocol],
|
||||
'port_range_min': [port_min],
|
||||
'port_range_max': [port_max],
|
||||
'remote_ip_prefix': [cidr]}
|
||||
if port_min is not None:
|
||||
attrs['port_range_min'] = [port_min]
|
||||
if port_max is not None:
|
||||
attrs['port_range_max'] = [port_max]
|
||||
expected_rules.append(attrs)
|
||||
if classifier['direction'] in out_bi:
|
||||
# If direction OUT/BI, provider CIDRs go into consumer SG
|
||||
|
@ -345,18 +349,22 @@ class ResourceMappingTestCase(test_plugin.GroupPolicyPluginTestCase):
|
|||
attrs = {'security_group_id': [consumed_sg],
|
||||
'direction': ['ingress'],
|
||||
'protocol': [protocol],
|
||||
'port_range_min': [port_min],
|
||||
'port_range_max': [port_max],
|
||||
'remote_ip_prefix': [cidr]}
|
||||
if port_min is not None:
|
||||
attrs['port_range_min'] = [port_min]
|
||||
if port_max is not None:
|
||||
attrs['port_range_max'] = [port_max]
|
||||
expected_rules.append(attrs)
|
||||
# And provider SG have egress allowed
|
||||
for cidr in consumers:
|
||||
attrs = {'security_group_id': [provided_sg],
|
||||
'direction': ['egress'],
|
||||
'protocol': [protocol],
|
||||
'port_range_min': [port_min],
|
||||
'port_range_max': [port_max],
|
||||
'remote_ip_prefix': [cidr]}
|
||||
if port_min is not None:
|
||||
attrs['port_range_min'] = [port_min]
|
||||
if port_max is not None:
|
||||
attrs['port_range_max'] = [port_max]
|
||||
expected_rules.append(attrs)
|
||||
return expected_rules
|
||||
|
||||
|
@ -373,11 +381,12 @@ class ResourceMappingTestCase(test_plugin.GroupPolicyPluginTestCase):
|
|||
# Verify the rule exists
|
||||
r = self._get_sg_rule(**rule)
|
||||
self.assertTrue(len(r) == 1,
|
||||
"Rule not found, expected:\n%s\n\nfound:%s\n" %
|
||||
(rule, existing_copy))
|
||||
"Rule not found, expected:\n%s\n\nfound:%s\n"
|
||||
"Missing:%s\n" % (expected, existing_copy, rule))
|
||||
existing.remove(r[0])
|
||||
self.assertTrue(len(existing) == 0,
|
||||
"Some rules still exist:\n%s" % str(existing))
|
||||
"Unexpected additional rules are configured:\n%s"
|
||||
% str(existing))
|
||||
return expected
|
||||
|
||||
def _get_nsp_ptg_fip_mapping(self, ptg_id):
|
||||
|
@ -1896,6 +1905,38 @@ class TestPolicyRuleSet(ResourceMappingTestCase):
|
|||
|
||||
self._verify_prs_rules(policy_rule_set_id)
|
||||
|
||||
def test_policy_classifier_update_using_protocol_number(self):
|
||||
classifier = self.create_policy_classifier(
|
||||
name="class1", protocol="tcp", direction="bi")
|
||||
classifier_id = classifier['policy_classifier']['id']
|
||||
action = self.create_policy_action(name="action1",
|
||||
action_type=gconst.GP_ACTION_ALLOW)
|
||||
action_id = action['policy_action']['id']
|
||||
action_id_list = [action_id]
|
||||
policy_rule = self.create_policy_rule(
|
||||
name='pr1', policy_classifier_id=classifier_id,
|
||||
policy_actions=action_id_list)
|
||||
policy_rule_id = policy_rule['policy_rule']['id']
|
||||
policy_rule_list = [policy_rule_id]
|
||||
policy_rule_set = self.create_policy_rule_set(
|
||||
name="c1", policy_rules=policy_rule_list)
|
||||
policy_rule_set_id = policy_rule_set['policy_rule_set']['id']
|
||||
self.create_policy_target_group(
|
||||
name="ptg1", provided_policy_rule_sets={policy_rule_set_id: None})
|
||||
self.create_policy_target_group(
|
||||
name="ptg2", consumed_policy_rule_sets={policy_rule_set_id: None})
|
||||
self._verify_prs_rules(policy_rule_set_id)
|
||||
|
||||
# now updates the policy classifier with new protocol field
|
||||
data = {'policy_classifier':
|
||||
{'protocol': '50', 'direction': 'bi'}}
|
||||
req = self.new_update_request('policy_classifiers', data,
|
||||
classifier_id)
|
||||
res = req.get_response(self.ext_api)
|
||||
self.assertEqual(res.status_int, webob.exc.HTTPOk.code)
|
||||
|
||||
self._verify_prs_rules(policy_rule_set_id)
|
||||
|
||||
def test_shared_policy_rule_set_create_negative(self):
|
||||
self.create_policy_rule_set(shared=True,
|
||||
expected_res_status=400)
|
||||
|
|
Loading…
Reference in New Issue