Group Policy API-1: EP, EPG, L2 Policy, L3 Policy
(Patch series identifier: GP-API-1) This is the first in a series of patches which implement Group Policy. It includes the Resource Model and API for Endpoint, Endpoint Group, L2 Policy, and L3 Policy resources. In the context of the larger Group Policy Model, the Endpoint Group resource references Contracts, which will be introduced in a subsequent patch. The DB and Plugin layers to back these resources will also be introduced in subsequent patches. DocImpact Gerrit Spec: https://review.openstack.org/#/c/89469 Author: Sumit Naiksatam <sumitnaiksatam@gmail.com> Co-Authored-By: Bob Kukura <kukura@noironetworks.com> Co-Authored-By: Stephen Wong <s3wong@midokura.com> Co-Authored-By: Mohammad Banikazemi <mb@us.ibm.com> Co-Authored-By: Mandeep Dhami <dhami@noironetworks.com> Co-Authored-By: Ivar Lazzaro <ivarlazzaro@gmail.com> Change-Id: I4f4cc7e2a899b39947b784ec390c3df599cf01ae
This commit is contained in:
parent
af3cbdfc7f
commit
8ab2b5243b
138
etc/policy.json
Normal file
138
etc/policy.json
Normal file
@ -0,0 +1,138 @@
|
||||
{
|
||||
"context_is_admin": "role:admin",
|
||||
"admin_or_owner": "rule:context_is_admin or tenant_id:%(tenant_id)s",
|
||||
"admin_or_network_owner": "rule:context_is_admin or tenant_id:%(network:tenant_id)s",
|
||||
"admin_only": "rule:context_is_admin",
|
||||
"regular_user": "",
|
||||
"shared": "field:networks:shared=True",
|
||||
"shared_firewalls": "field:firewalls:shared=True",
|
||||
"external": "field:networks:router:external=True",
|
||||
"default": "rule:admin_or_owner",
|
||||
|
||||
"create_subnet": "rule:admin_or_network_owner",
|
||||
"get_subnet": "rule:admin_or_owner or rule:shared",
|
||||
"update_subnet": "rule:admin_or_network_owner",
|
||||
"delete_subnet": "rule:admin_or_network_owner",
|
||||
|
||||
"create_network": "",
|
||||
"get_network": "rule:admin_or_owner or rule:shared or rule:external",
|
||||
"get_network:router:external": "rule:regular_user",
|
||||
"get_network:segments": "rule:admin_only",
|
||||
"get_network:provider:network_type": "rule:admin_only",
|
||||
"get_network:provider:physical_network": "rule:admin_only",
|
||||
"get_network:provider:segmentation_id": "rule:admin_only",
|
||||
"get_network:queue_id": "rule:admin_only",
|
||||
"create_network:shared": "rule:admin_only",
|
||||
"create_network:router:external": "rule:admin_only",
|
||||
"create_network:segments": "rule:admin_only",
|
||||
"create_network:provider:network_type": "rule:admin_only",
|
||||
"create_network:provider:physical_network": "rule:admin_only",
|
||||
"create_network:provider:segmentation_id": "rule:admin_only",
|
||||
"update_network": "rule:admin_or_owner",
|
||||
"update_network:segments": "rule:admin_only",
|
||||
"update_network:shared": "rule:admin_only",
|
||||
"update_network:provider:network_type": "rule:admin_only",
|
||||
"update_network:provider:physical_network": "rule:admin_only",
|
||||
"update_network:provider:segmentation_id": "rule:admin_only",
|
||||
"update_network:router:external": "rule:admin_only",
|
||||
"delete_network": "rule:admin_or_owner",
|
||||
|
||||
"create_port": "",
|
||||
"create_port:mac_address": "rule:admin_or_network_owner",
|
||||
"create_port:fixed_ips": "rule:admin_or_network_owner",
|
||||
"create_port:port_security_enabled": "rule:admin_or_network_owner",
|
||||
"create_port:binding:host_id": "rule:admin_only",
|
||||
"create_port:binding:profile": "rule:admin_only",
|
||||
"create_port:mac_learning_enabled": "rule:admin_or_network_owner",
|
||||
"get_port": "rule:admin_or_owner",
|
||||
"get_port:queue_id": "rule:admin_only",
|
||||
"get_port:binding:vif_type": "rule:admin_only",
|
||||
"get_port:binding:vif_details": "rule:admin_only",
|
||||
"get_port:binding:host_id": "rule:admin_only",
|
||||
"get_port:binding:profile": "rule:admin_only",
|
||||
"update_port": "rule:admin_or_owner",
|
||||
"update_port:fixed_ips": "rule:admin_or_network_owner",
|
||||
"update_port:port_security_enabled": "rule:admin_or_network_owner",
|
||||
"update_port:binding:host_id": "rule:admin_only",
|
||||
"update_port:binding:profile": "rule:admin_only",
|
||||
"update_port:mac_learning_enabled": "rule:admin_or_network_owner",
|
||||
"delete_port": "rule:admin_or_owner",
|
||||
|
||||
"get_router:ha": "rule:admin_only",
|
||||
"create_router": "rule:regular_user",
|
||||
"create_router:external_gateway_info:enable_snat": "rule:admin_only",
|
||||
"create_router:distributed": "rule:admin_only",
|
||||
"create_router:ha": "rule:admin_only",
|
||||
"get_router": "rule:admin_or_owner",
|
||||
"get_router:distributed": "rule:admin_only",
|
||||
"update_router:external_gateway_info:enable_snat": "rule:admin_only",
|
||||
"update_router:distributed": "rule:admin_only",
|
||||
"update_router:ha": "rule:admin_only",
|
||||
"delete_router": "rule:admin_or_owner",
|
||||
|
||||
"add_router_interface": "rule:admin_or_owner",
|
||||
"remove_router_interface": "rule:admin_or_owner",
|
||||
|
||||
"create_firewall": "",
|
||||
"get_firewall": "rule:admin_or_owner",
|
||||
"create_firewall:shared": "rule:admin_only",
|
||||
"get_firewall:shared": "rule:admin_only",
|
||||
"update_firewall": "rule:admin_or_owner",
|
||||
"update_firewall:shared": "rule:admin_only",
|
||||
"delete_firewall": "rule:admin_or_owner",
|
||||
|
||||
"create_firewall_policy": "",
|
||||
"get_firewall_policy": "rule:admin_or_owner or rule:shared_firewalls",
|
||||
"create_firewall_policy:shared": "rule:admin_or_owner",
|
||||
"update_firewall_policy": "rule:admin_or_owner",
|
||||
"delete_firewall_policy": "rule:admin_or_owner",
|
||||
|
||||
"create_firewall_rule": "",
|
||||
"get_firewall_rule": "rule:admin_or_owner or rule:shared_firewalls",
|
||||
"update_firewall_rule": "rule:admin_or_owner",
|
||||
"delete_firewall_rule": "rule:admin_or_owner",
|
||||
|
||||
"create_qos_queue": "rule:admin_only",
|
||||
"get_qos_queue": "rule:admin_only",
|
||||
|
||||
"update_agent": "rule:admin_only",
|
||||
"delete_agent": "rule:admin_only",
|
||||
"get_agent": "rule:admin_only",
|
||||
|
||||
"create_dhcp-network": "rule:admin_only",
|
||||
"delete_dhcp-network": "rule:admin_only",
|
||||
"get_dhcp-networks": "rule:admin_only",
|
||||
"create_l3-router": "rule:admin_only",
|
||||
"delete_l3-router": "rule:admin_only",
|
||||
"get_l3-routers": "rule:admin_only",
|
||||
"get_dhcp-agents": "rule:admin_only",
|
||||
"get_l3-agents": "rule:admin_only",
|
||||
"get_loadbalancer-agent": "rule:admin_only",
|
||||
"get_loadbalancer-pools": "rule:admin_only",
|
||||
|
||||
"create_floatingip": "rule:regular_user",
|
||||
"update_floatingip": "rule:admin_or_owner",
|
||||
"delete_floatingip": "rule:admin_or_owner",
|
||||
"get_floatingip": "rule:admin_or_owner",
|
||||
|
||||
"create_network_profile": "rule:admin_only",
|
||||
"update_network_profile": "rule:admin_only",
|
||||
"delete_network_profile": "rule:admin_only",
|
||||
"get_network_profiles": "",
|
||||
"get_network_profile": "",
|
||||
"update_policy_profiles": "rule:admin_only",
|
||||
"get_policy_profiles": "",
|
||||
"get_policy_profile": "",
|
||||
|
||||
"create_metering_label": "rule:admin_only",
|
||||
"delete_metering_label": "rule:admin_only",
|
||||
"get_metering_label": "rule:admin_only",
|
||||
|
||||
"create_metering_label_rule": "rule:admin_only",
|
||||
"delete_metering_label_rule": "rule:admin_only",
|
||||
"get_metering_label_rule": "rule:admin_only",
|
||||
|
||||
"get_service_provider": "rule:regular_user",
|
||||
"get_lsn": "rule:admin_only",
|
||||
"create_lsn": "rule:admin_only"
|
||||
}
|
0
gbp/neutron/__init__.py
Normal file
0
gbp/neutron/__init__.py
Normal file
0
gbp/neutron/extensions/__init__.py
Normal file
0
gbp/neutron/extensions/__init__.py
Normal file
285
gbp/neutron/extensions/group_policy.py
Normal file
285
gbp/neutron/extensions/group_policy.py
Normal file
@ -0,0 +1,285 @@
|
||||
# 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 abc
|
||||
|
||||
import six
|
||||
|
||||
from neutron.api import extensions
|
||||
from neutron.api.v2 import attributes as attr
|
||||
from neutron.api.v2 import resource_helper
|
||||
from neutron.plugins.common import constants
|
||||
from neutron.services import service_base
|
||||
|
||||
import gbp.neutron.extensions
|
||||
|
||||
# The code below is a monkey patch of key Neutron's modules. This is needed for
|
||||
# the GBP service to be loaded correctly. GBP extensions' path is added
|
||||
# to Neutron's so that it's found at extension scanning time.
|
||||
|
||||
extensions.append_api_extensions_path(gbp.neutron.extensions.__path__)
|
||||
constants.GROUP_POLICY = "GROUP_POLICY"
|
||||
constants.COMMON_PREFIXES["GROUP_POLICY"] = "/grouppolicy"
|
||||
|
||||
ENDPOINTS = 'endpoints'
|
||||
ENDPOINT_GROUPS = 'endpoint_groups'
|
||||
L2_POLICIES = 'l2_policies'
|
||||
L3_POLICIES = 'l3_policies'
|
||||
|
||||
|
||||
RESOURCE_ATTRIBUTE_MAP = {
|
||||
ENDPOINTS: {
|
||||
'id': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid': None}, 'is_visible': True,
|
||||
'primary_key': True},
|
||||
'name': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string': None}, 'default': '',
|
||||
'is_visible': True},
|
||||
'description': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string': None},
|
||||
'is_visible': True, 'default': ''},
|
||||
'tenant_id': {'allow_post': True, 'allow_put': False,
|
||||
'validate': {'type:string': None},
|
||||
'required_by_policy': True, 'is_visible': True},
|
||||
'endpoint_group_id': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:uuid_or_none': None},
|
||||
'required': True, 'is_visible': True},
|
||||
},
|
||||
ENDPOINT_GROUPS: {
|
||||
'id': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid': None}, 'is_visible': True,
|
||||
'primary_key': True},
|
||||
'name': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string': None},
|
||||
'default': '', 'is_visible': True},
|
||||
'description': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string': None},
|
||||
'is_visible': True, 'default': ''},
|
||||
'tenant_id': {'allow_post': True, 'allow_put': False,
|
||||
'validate': {'type:string': None},
|
||||
'required_by_policy': True, 'is_visible': True},
|
||||
'endpoints': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid_list': None},
|
||||
'convert_to': attr.convert_none_to_empty_list,
|
||||
'default': None, 'is_visible': True},
|
||||
'l2_policy_id': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:uuid_or_none': None},
|
||||
'default': None, 'is_visible': True},
|
||||
'provided_contracts': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:dict_or_none': None},
|
||||
'convert_to': attr.convert_none_to_empty_dict,
|
||||
'default': None, 'is_visible': True},
|
||||
'consumed_contracts': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:dict_or_none': None},
|
||||
'convert_to': attr.convert_none_to_empty_dict,
|
||||
'default': None, 'is_visible': True},
|
||||
},
|
||||
L2_POLICIES: {
|
||||
'id': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid': None}, 'is_visible': True,
|
||||
'primary_key': True},
|
||||
'name': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string': None},
|
||||
'default': '', 'is_visible': True},
|
||||
'description': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string': None},
|
||||
'is_visible': True, 'default': ''},
|
||||
'tenant_id': {'allow_post': True, 'allow_put': False,
|
||||
'validate': {'type:string': None},
|
||||
'required_by_policy': True, 'is_visible': True},
|
||||
'endpoint_groups': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid_list': None},
|
||||
'convert_to': attr.convert_none_to_empty_list,
|
||||
'default': None, 'is_visible': True},
|
||||
'l3_policy_id': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:uuid_or_none': None},
|
||||
'default': None, 'is_visible': True,
|
||||
'required': True},
|
||||
# TODO(Sumit): uncomment when supported in data path
|
||||
# 'allow_broadcast': {'allow_post': True, 'allow_put': True,
|
||||
# 'default': True, 'is_visible': True,
|
||||
# 'convert_to': attr.convert_to_boolean,
|
||||
# 'required': False},
|
||||
},
|
||||
L3_POLICIES: {
|
||||
'id': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid': None}, 'is_visible': True,
|
||||
'primary_key': True},
|
||||
'name': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string': None},
|
||||
'default': '', 'is_visible': True},
|
||||
'description': {'allow_post': True, 'allow_put': True,
|
||||
'validate': {'type:string': None},
|
||||
'is_visible': True, 'default': ''},
|
||||
'tenant_id': {'allow_post': True, 'allow_put': False,
|
||||
'validate': {'type:string': None},
|
||||
'required_by_policy': True, 'is_visible': True},
|
||||
'ip_version': {'allow_post': True, 'allow_put': False,
|
||||
'convert_to': attr.convert_to_int,
|
||||
'validate': {'type:values': [4, 6]},
|
||||
'default': 4, 'is_visible': True},
|
||||
'ip_pool': {'allow_post': True, 'allow_put': False,
|
||||
'validate': {'type:subnet': None},
|
||||
'default': '10.0.0.0/8', 'is_visible': True},
|
||||
'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': 24, 'is_visible': True},
|
||||
'l2_policies': {'allow_post': False, 'allow_put': False,
|
||||
'validate': {'type:uuid_list': None},
|
||||
'convert_to': attr.convert_none_to_empty_list,
|
||||
'default': None, 'is_visible': True},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class Group_policy(extensions.ExtensionDescriptor):
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
return "Group Policy Abstraction"
|
||||
|
||||
@classmethod
|
||||
def get_alias(cls):
|
||||
return "group-policy"
|
||||
|
||||
@classmethod
|
||||
def get_description(cls):
|
||||
return "Extension for Group Policy Abstraction"
|
||||
|
||||
@classmethod
|
||||
def get_namespace(cls):
|
||||
return "http://wiki.openstack.org/neutron/gp/v2.0/"
|
||||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
return "2014-03-03T12:00:00-00:00"
|
||||
|
||||
@classmethod
|
||||
def get_resources(cls):
|
||||
special_mappings = {'l2_policies': 'l2_policy',
|
||||
'l3_policies': 'l3_policy'}
|
||||
plural_mappings = resource_helper.build_plural_mappings(
|
||||
special_mappings, RESOURCE_ATTRIBUTE_MAP)
|
||||
attr.PLURALS.update(plural_mappings)
|
||||
return resource_helper.build_resource_info(plural_mappings,
|
||||
RESOURCE_ATTRIBUTE_MAP,
|
||||
constants.GROUP_POLICY)
|
||||
|
||||
@classmethod
|
||||
def get_plugin_interface(cls):
|
||||
return GroupPolicyPluginBase
|
||||
|
||||
def update_attributes_map(self, attributes):
|
||||
super(Group_policy, self).update_attributes_map(
|
||||
attributes, extension_attrs_map=RESOURCE_ATTRIBUTE_MAP)
|
||||
|
||||
def get_extended_resources(self, version):
|
||||
if version == "2.0":
|
||||
return RESOURCE_ATTRIBUTE_MAP
|
||||
else:
|
||||
return {}
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class GroupPolicyPluginBase(service_base.ServicePluginBase):
|
||||
|
||||
def get_plugin_name(self):
|
||||
return constants.GROUP_POLICY
|
||||
|
||||
def get_plugin_type(self):
|
||||
return constants.GROUP_POLICY
|
||||
|
||||
def get_plugin_description(self):
|
||||
return 'Group Policy plugin'
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_endpoints(self, context, filters=None, fields=None):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_endpoint(self, context, endpoint_id, fields=None):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_endpoint(self, context, endpoint):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_endpoint(self, context, endpoint_id, endpoint):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete_endpoint(self, context, endpoint_id):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_endpoint_groups(self, context, filters=None, fields=None):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_endpoint_group(self, context, endpoint_group_id, fields=None):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_endpoint_group(self, context, endpoint_group):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_endpoint_group(self, context, endpoint_group_id,
|
||||
endpoint_group):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete_endpoint_group(self, context, endpoint_group_id):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_l2_policies(self, context, filters=None, fields=None):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_l2_policy(self, context, l2_policy_id, fields=None):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_l2_policy(self, context, l2_policy):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_l2_policy(self, context, l2_policy_id, l2_policy):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete_l2_policy(self, context, l2_policy_id):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_l3_policies(self, context, filters=None, fields=None):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_l3_policy(self, context, l3_policy_id, fields=None):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_l3_policy(self, context, l3_policy):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def update_l3_policy(self, context, l3_policy_id, l3_policy):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete_l3_policy(self, context, l3_policy_id):
|
||||
pass
|
0
gbp/neutron/tests/__init__.py
Normal file
0
gbp/neutron/tests/__init__.py
Normal file
0
gbp/neutron/tests/unit/__init__.py
Normal file
0
gbp/neutron/tests/unit/__init__.py
Normal file
437
gbp/neutron/tests/unit/test_extension_group_policy.py
Normal file
437
gbp/neutron/tests/unit/test_extension_group_policy.py
Normal file
@ -0,0 +1,437 @@
|
||||
# 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 copy
|
||||
|
||||
import mock
|
||||
from neutron.openstack.common import uuidutils
|
||||
from neutron.plugins.common import constants
|
||||
from neutron.tests.unit import test_api_v2
|
||||
from neutron.tests.unit import test_api_v2_extension
|
||||
from webob import exc
|
||||
|
||||
from gbp.neutron.extensions import group_policy as gp
|
||||
|
||||
_uuid = uuidutils.generate_uuid
|
||||
_get_path = test_api_v2._get_path
|
||||
GP_PLUGIN_BASE_NAME = (
|
||||
gp.GroupPolicyPluginBase.__module__ + '.' +
|
||||
gp.GroupPolicyPluginBase.__name__)
|
||||
GROUPPOLICY_URI = 'grouppolicy'
|
||||
ENDPOINTS_URI = GROUPPOLICY_URI + '/' + 'endpoints'
|
||||
ENDPOINT_GROUPS_URI = GROUPPOLICY_URI + '/' + 'endpoint_groups'
|
||||
L2_POLICIES_URI = GROUPPOLICY_URI + '/' + 'l2_policies'
|
||||
L3_POLICIES_URI = GROUPPOLICY_URI + '/' + 'l3_policies'
|
||||
|
||||
|
||||
class GroupPolicyExtensionTestCase(test_api_v2_extension.ExtensionTestCase):
|
||||
fmt = 'json'
|
||||
|
||||
def setUp(self):
|
||||
super(GroupPolicyExtensionTestCase, self).setUp()
|
||||
plural_mappings = {'l2_policy': 'l2_policies',
|
||||
'l3_policy': 'l3_policies'}
|
||||
self._setUpExtension(
|
||||
GP_PLUGIN_BASE_NAME, constants.GROUP_POLICY,
|
||||
gp.RESOURCE_ATTRIBUTE_MAP, gp.Group_policy, GROUPPOLICY_URI,
|
||||
plural_mappings=plural_mappings)
|
||||
self.instance = self.plugin.return_value
|
||||
|
||||
def _test_create_endpoint(self, data, expected_value, default_data=None):
|
||||
if not default_data:
|
||||
default_data = data
|
||||
self.instance.create_endpoint.return_value = expected_value
|
||||
res = self.api.post(_get_path(ENDPOINTS_URI, fmt=self.fmt),
|
||||
self.serialize(data),
|
||||
content_type='application/%s' % self.fmt)
|
||||
self.instance.create_endpoint.assert_called_once_with(
|
||||
mock.ANY, endpoint=default_data)
|
||||
self.assertEqual(exc.HTTPCreated.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint', res)
|
||||
self.assertEqual(expected_value, res['endpoint'])
|
||||
|
||||
def _get_create_endpoint_default_attrs(self):
|
||||
return {'name': '', 'description': ''}
|
||||
|
||||
def _get_create_endpoint_attrs(self):
|
||||
return {'name': 'ep1', 'endpoint_group_id': _uuid(),
|
||||
'tenant_id': _uuid(), 'description': 'test endpoint'}
|
||||
|
||||
def _get_update_endpoint_attrs(self):
|
||||
return {'name': 'new_name'}
|
||||
|
||||
def test_create_endpoint_with_defaults(self):
|
||||
endpoint_id = _uuid()
|
||||
data = {'endpoint': {'endpoint_group_id': _uuid(),
|
||||
'tenant_id': _uuid()}}
|
||||
default_attrs = self._get_create_endpoint_default_attrs()
|
||||
default_data = copy.copy(data)
|
||||
default_data['endpoint'].update(default_attrs)
|
||||
expected_value = dict(default_data['endpoint'])
|
||||
expected_value['id'] = endpoint_id
|
||||
|
||||
self._test_create_endpoint(data, expected_value, default_data)
|
||||
|
||||
def test_create_endpoint(self):
|
||||
endpoint_id = _uuid()
|
||||
data = {'endpoint': self._get_create_endpoint_attrs()}
|
||||
expected_value = dict(data['endpoint'])
|
||||
expected_value['id'] = endpoint_id
|
||||
|
||||
self._test_create_endpoint(data, expected_value)
|
||||
|
||||
def test_list_endpoints(self):
|
||||
endpoint_id = _uuid()
|
||||
expected_value = [{'tenant_id': _uuid(), 'id': endpoint_id}]
|
||||
|
||||
self.instance.get_endpoints.return_value = expected_value
|
||||
|
||||
res = self.api.get(_get_path(ENDPOINTS_URI, fmt=self.fmt))
|
||||
|
||||
self.instance.get_endpoints.assert_called_once_with(
|
||||
mock.ANY, fields=mock.ANY, filters=mock.ANY)
|
||||
self.assertEqual(exc.HTTPOk.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoints', res)
|
||||
self.assertEqual(expected_value, res['endpoints'])
|
||||
|
||||
def test_get_endpoint(self):
|
||||
endpoint_id = _uuid()
|
||||
expected_value = {'tenant_id': _uuid(), 'id': endpoint_id}
|
||||
|
||||
self.instance.get_endpoint.return_value = expected_value
|
||||
|
||||
res = self.api.get(_get_path(ENDPOINTS_URI, id=endpoint_id,
|
||||
fmt=self.fmt))
|
||||
|
||||
self.instance.get_endpoint.assert_called_once_with(
|
||||
mock.ANY, endpoint_id, fields=mock.ANY)
|
||||
self.assertEqual(exc.HTTPOk.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint', res)
|
||||
self.assertEqual(expected_value, res['endpoint'])
|
||||
|
||||
def test_update_endpoint(self):
|
||||
endpoint_id = _uuid()
|
||||
update_data = {'endpoint': self._get_update_endpoint_attrs()}
|
||||
expected_value = {'tenant_id': _uuid(), 'id': endpoint_id}
|
||||
|
||||
self.instance.update_endpoint.return_value = expected_value
|
||||
|
||||
res = self.api.put(_get_path(ENDPOINTS_URI, id=endpoint_id,
|
||||
fmt=self.fmt),
|
||||
self.serialize(update_data))
|
||||
|
||||
self.instance.update_endpoint.assert_called_once_with(
|
||||
mock.ANY, endpoint_id, endpoint=update_data)
|
||||
self.assertEqual(exc.HTTPOk.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint', res)
|
||||
self.assertEqual(expected_value, res['endpoint'])
|
||||
|
||||
def test_delete_endpoint(self):
|
||||
self._test_entity_delete('endpoint')
|
||||
|
||||
def _test_create_endpoint_group(self, data, expected_value,
|
||||
default_data=None):
|
||||
if not default_data:
|
||||
default_data = data
|
||||
|
||||
self.instance.create_endpoint_group.return_value = expected_value
|
||||
res = self.api.post(_get_path(ENDPOINT_GROUPS_URI, fmt=self.fmt),
|
||||
self.serialize(data),
|
||||
content_type='application/%s' % self.fmt)
|
||||
self.instance.create_endpoint_group.assert_called_once_with(
|
||||
mock.ANY, endpoint_group=default_data)
|
||||
self.assertEqual(exc.HTTPCreated.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint_group', res)
|
||||
self.assertEqual(expected_value, res['endpoint_group'])
|
||||
|
||||
def _get_create_endpoint_group_default_attrs(self):
|
||||
return {'name': '', 'description': '', 'l2_policy_id': None,
|
||||
'provided_contracts': {}, 'consumed_contracts': {}}
|
||||
|
||||
def _get_create_endpoint_group_attrs(self):
|
||||
return {'name': 'epg1', 'tenant_id': _uuid(),
|
||||
'description': 'test endpoint group', 'l2_policy_id': _uuid(),
|
||||
'provided_contracts': {_uuid(): None},
|
||||
'consumed_contracts': {_uuid(): None}}
|
||||
|
||||
def _get_update_endpoint_group_attrs(self):
|
||||
return {'name': 'new_name'}
|
||||
|
||||
def test_create_endpoint_group_with_defaults(self):
|
||||
endpoint_group_id = _uuid()
|
||||
data = {'endpoint_group': {'tenant_id': _uuid()}}
|
||||
default_attrs = self._get_create_endpoint_group_default_attrs()
|
||||
default_data = copy.copy(data)
|
||||
default_data['endpoint_group'].update(default_attrs)
|
||||
expected_value = copy.deepcopy(default_data['endpoint_group'])
|
||||
expected_value['id'] = endpoint_group_id
|
||||
|
||||
self._test_create_endpoint_group(data, expected_value, default_data)
|
||||
|
||||
def test_create_endpoint_group(self):
|
||||
endpoint_group_id = _uuid()
|
||||
data = {'endpoint_group': self._get_create_endpoint_group_attrs()}
|
||||
expected_value = copy.deepcopy(data['endpoint_group'])
|
||||
expected_value['id'] = endpoint_group_id
|
||||
|
||||
self._test_create_endpoint_group(data, expected_value)
|
||||
|
||||
def test_list_endpoint_groups(self):
|
||||
endpoint_group_id = _uuid()
|
||||
expected_value = [{'tenant_id': _uuid(), 'id': endpoint_group_id}]
|
||||
|
||||
self.instance.get_endpoint_groups.return_value = expected_value
|
||||
|
||||
res = self.api.get(_get_path(ENDPOINT_GROUPS_URI, fmt=self.fmt))
|
||||
|
||||
self.instance.get_endpoint_groups.assert_called_once_with(
|
||||
mock.ANY, fields=mock.ANY, filters=mock.ANY)
|
||||
self.assertEqual(exc.HTTPOk.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint_groups', res)
|
||||
self.assertEqual(expected_value, res['endpoint_groups'])
|
||||
|
||||
def test_get_endpoint_group(self):
|
||||
endpoint_group_id = _uuid()
|
||||
expected_value = {'tenant_id': _uuid(), 'id': endpoint_group_id}
|
||||
|
||||
self.instance.get_endpoint_group.return_value = expected_value
|
||||
|
||||
res = self.api.get(_get_path(ENDPOINT_GROUPS_URI, id=endpoint_group_id,
|
||||
fmt=self.fmt))
|
||||
|
||||
self.instance.get_endpoint_group.assert_called_once_with(
|
||||
mock.ANY, endpoint_group_id, fields=mock.ANY)
|
||||
self.assertEqual(exc.HTTPOk.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint_group', res)
|
||||
self.assertEqual(expected_value, res['endpoint_group'])
|
||||
|
||||
def test_update_endpoint_group(self):
|
||||
endpoint_group_id = _uuid()
|
||||
update_data = {'endpoint_group':
|
||||
self._get_update_endpoint_group_attrs()}
|
||||
expected_value = {'tenant_id': _uuid(), 'id': endpoint_group_id}
|
||||
|
||||
self.instance.update_endpoint_group.return_value = expected_value
|
||||
|
||||
res = self.api.put(_get_path(ENDPOINT_GROUPS_URI,
|
||||
id=endpoint_group_id, fmt=self.fmt),
|
||||
self.serialize(update_data))
|
||||
|
||||
self.instance.update_endpoint_group.assert_called_once_with(
|
||||
mock.ANY, endpoint_group_id, endpoint_group=update_data)
|
||||
self.assertEqual(exc.HTTPOk.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('endpoint_group', res)
|
||||
self.assertEqual(expected_value, res['endpoint_group'])
|
||||
|
||||
def test_delete_endpoint_group(self):
|
||||
self._test_entity_delete('endpoint_group')
|
||||
|
||||
def _test_create_l2_policy(self, data, expected_value, default_data=None):
|
||||
if not default_data:
|
||||
default_data = data
|
||||
self.instance.create_l2_policy.return_value = expected_value
|
||||
res = self.api.post(_get_path(L2_POLICIES_URI, fmt=self.fmt),
|
||||
self.serialize(data),
|
||||
content_type='application/%s' % self.fmt)
|
||||
self.instance.create_l2_policy.assert_called_once_with(
|
||||
mock.ANY, l2_policy=default_data)
|
||||
self.assertEqual(exc.HTTPCreated.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('l2_policy', res)
|
||||
self.assertEqual(expected_value, res['l2_policy'])
|
||||
|
||||
def _get_create_l2_policy_default_attrs(self):
|
||||
return {'name': '', 'description': ''}
|
||||
|
||||
def _get_create_l2_policy_attrs(self):
|
||||
return {'name': 'l2p1', 'tenant_id': _uuid(),
|
||||
'description': 'test L2 policy', 'l3_policy_id': _uuid()}
|
||||
|
||||
def _get_update_l2_policy_attrs(self):
|
||||
return {'name': 'new_name'}
|
||||
|
||||
def test_create_l2_policy_with_defaults(self):
|
||||
l2_policy_id = _uuid()
|
||||
data = {'l2_policy': {'tenant_id': _uuid(), 'l3_policy_id': _uuid()}}
|
||||
default_attrs = self._get_create_l2_policy_default_attrs()
|
||||
default_data = copy.copy(data)
|
||||
default_data['l2_policy'].update(default_attrs)
|
||||
expected_value = dict(default_data['l2_policy'])
|
||||
expected_value['id'] = l2_policy_id
|
||||
|
||||
self._test_create_l2_policy(data, expected_value, default_data)
|
||||
|
||||
def test_create_l2_policy(self):
|
||||
l2_policy_id = _uuid()
|
||||
data = {'l2_policy': self._get_create_l2_policy_attrs()}
|
||||
expected_value = dict(data['l2_policy'])
|
||||
expected_value['id'] = l2_policy_id
|
||||
|
||||
self._test_create_l2_policy(data, expected_value)
|
||||
|
||||
def test_list_l2_policies(self):
|
||||
l2_policy_id = _uuid()
|
||||
expected_value = [{'tenant_id': _uuid(), 'id': l2_policy_id}]
|
||||
|
||||
self.instance.get_l2_policies.return_value = expected_value
|
||||
|
||||
res = self.api.get(_get_path(L2_POLICIES_URI, fmt=self.fmt))
|
||||
|
||||
self.instance.get_l2_policies.assert_called_once_with(
|
||||
mock.ANY, fields=mock.ANY, filters=mock.ANY)
|
||||
self.assertEqual(exc.HTTPOk.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('l2_policies', res)
|
||||
self.assertEqual(expected_value, res['l2_policies'])
|
||||
|
||||
def test_get_l2_policy(self):
|
||||
l2_policy_id = _uuid()
|
||||
expected_value = {'tenant_id': _uuid(), 'id': l2_policy_id}
|
||||
|
||||
self.instance.get_l2_policy.return_value = expected_value
|
||||
|
||||
res = self.api.get(_get_path(L2_POLICIES_URI, id=l2_policy_id,
|
||||
fmt=self.fmt))
|
||||
|
||||
self.instance.get_l2_policy.assert_called_once_with(
|
||||
mock.ANY, l2_policy_id, fields=mock.ANY)
|
||||
self.assertEqual(exc.HTTPOk.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('l2_policy', res)
|
||||
self.assertEqual(expected_value, res['l2_policy'])
|
||||
|
||||
def test_update_l2_policy(self):
|
||||
l2_policy_id = _uuid()
|
||||
update_data = {'l2_policy': self._get_update_l2_policy_attrs()}
|
||||
expected_value = {'tenant_id': _uuid(), 'id': l2_policy_id}
|
||||
|
||||
self.instance.update_l2_policy.return_value = expected_value
|
||||
|
||||
res = self.api.put(_get_path(L2_POLICIES_URI, id=l2_policy_id,
|
||||
fmt=self.fmt),
|
||||
self.serialize(update_data))
|
||||
|
||||
self.instance.update_l2_policy.assert_called_once_with(
|
||||
mock.ANY, l2_policy_id, l2_policy=update_data)
|
||||
self.assertEqual(exc.HTTPOk.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('l2_policy', res)
|
||||
self.assertEqual(expected_value, res['l2_policy'])
|
||||
|
||||
def test_delete_l2_policy(self):
|
||||
self._test_entity_delete('l2_policy')
|
||||
|
||||
def _test_create_l3_policy(self, data, expected_value, default_data=None):
|
||||
if not default_data:
|
||||
default_data = data
|
||||
self.instance.create_l3_policy.return_value = expected_value
|
||||
res = self.api.post(_get_path(L3_POLICIES_URI, fmt=self.fmt),
|
||||
self.serialize(data),
|
||||
content_type='application/%s' % self.fmt)
|
||||
self.instance.create_l3_policy.assert_called_once_with(
|
||||
mock.ANY, l3_policy=default_data)
|
||||
self.assertEqual(exc.HTTPCreated.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('l3_policy', res)
|
||||
self.assertEqual(res['l3_policy'], expected_value)
|
||||
|
||||
def _get_create_l3_policy_default_attrs(self):
|
||||
return {'name': '', 'description': '', 'ip_version': 4,
|
||||
'ip_pool': '10.0.0.0/8', 'subnet_prefix_length': 24}
|
||||
|
||||
def _get_create_l3_policy_attrs(self):
|
||||
return {'name': 'l3p1', 'tenant_id': _uuid(),
|
||||
'description': 'test L3 policy', 'ip_version': 6,
|
||||
'ip_pool': 'fd01:2345:6789::/48',
|
||||
'subnet_prefix_length': 64}
|
||||
|
||||
def _get_update_l3_policy_attrs(self):
|
||||
return {'name': 'new_name'}
|
||||
|
||||
def test_create_l3_policy_with_defaults(self):
|
||||
l3_policy_id = _uuid()
|
||||
data = {'l3_policy': {'tenant_id': _uuid()}}
|
||||
default_attrs = self._get_create_l3_policy_default_attrs()
|
||||
default_data = copy.copy(data)
|
||||
default_data['l3_policy'].update(default_attrs)
|
||||
expected_value = dict(default_data['l3_policy'])
|
||||
expected_value['id'] = l3_policy_id
|
||||
|
||||
self._test_create_l3_policy(data, expected_value, default_data)
|
||||
|
||||
def test_create_l3_policy(self):
|
||||
l3_policy_id = _uuid()
|
||||
data = {'l3_policy': self._get_create_l3_policy_attrs()}
|
||||
expected_value = dict(data['l3_policy'])
|
||||
expected_value.update({'id': l3_policy_id})
|
||||
|
||||
self._test_create_l3_policy(data, expected_value)
|
||||
|
||||
def test_list_l3_policies(self):
|
||||
l3_policy_id = _uuid()
|
||||
expected_value = [{'tenant_id': _uuid(), 'id': l3_policy_id}]
|
||||
|
||||
self.instance.get_l3_policies.return_value = expected_value
|
||||
|
||||
res = self.api.get(_get_path(L3_POLICIES_URI, fmt=self.fmt))
|
||||
|
||||
self.instance.get_l3_policies.assert_called_once_with(
|
||||
mock.ANY, fields=mock.ANY, filters=mock.ANY)
|
||||
self.assertEqual(exc.HTTPOk.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('l3_policies', res)
|
||||
self.assertEqual(expected_value, res['l3_policies'])
|
||||
|
||||
def test_get_l3_policy(self):
|
||||
l3_policy_id = _uuid()
|
||||
expected_value = {'tenant_id': _uuid(), 'id': l3_policy_id}
|
||||
|
||||
self.instance.get_l3_policy.return_value = expected_value
|
||||
|
||||
res = self.api.get(_get_path(L3_POLICIES_URI, id=l3_policy_id,
|
||||
fmt=self.fmt))
|
||||
|
||||
self.instance.get_l3_policy.assert_called_once_with(
|
||||
mock.ANY, l3_policy_id, fields=mock.ANY)
|
||||
self.assertEqual(exc.HTTPOk.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('l3_policy', res)
|
||||
self.assertEqual(expected_value, res['l3_policy'])
|
||||
|
||||
def test_update_l3_policy(self):
|
||||
l3_policy_id = _uuid()
|
||||
update_data = {'l3_policy': self._get_update_l3_policy_attrs()}
|
||||
expected_value = {'tenant_id': _uuid(), 'id': l3_policy_id}
|
||||
|
||||
self.instance.update_l3_policy.return_value = expected_value
|
||||
|
||||
res = self.api.put(_get_path(L3_POLICIES_URI, id=l3_policy_id,
|
||||
fmt=self.fmt),
|
||||
self.serialize(update_data))
|
||||
|
||||
self.instance.update_l3_policy.assert_called_once_with(
|
||||
mock.ANY, l3_policy_id, l3_policy=update_data)
|
||||
self.assertEqual(exc.HTTPOk.code, res.status_int)
|
||||
res = self.deserialize(res)
|
||||
self.assertIn('l3_policy', res)
|
||||
self.assertEqual(expected_value, res['l3_policy'])
|
||||
|
||||
def test_delete_l3_policy(self):
|
||||
self._test_entity_delete('l3_policy')
|
@ -1,6 +1,3 @@
|
||||
# Copyright 2010-2011 OpenStack Foundation
|
||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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
|
||||
|
@ -1,5 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# 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
|
||||
|
@ -4,7 +4,15 @@
|
||||
|
||||
hacking>=0.9.2,<0.10
|
||||
|
||||
cliff>=1.6.0
|
||||
coverage>=3.6
|
||||
discover
|
||||
|
||||
fixtures>=0.3.14
|
||||
mock>=1.0
|
||||
python-subunit>=0.0.18
|
||||
ordereddict
|
||||
requests-mock>=0.4.0 # Apache-2.0
|
||||
sphinx>=1.1.2,!=1.2.0,<1.3
|
||||
oslosphinx>=2.2.0.0a2
|
||||
testrepository>=0.0.18
|
||||
|
Loading…
x
Reference in New Issue
Block a user