Merge "Use Resource layer for network SecurityGroups"
This commit is contained in:
commit
b0501643b9
|
@ -92,13 +92,6 @@ class ComputeCloudMixin(_normalize.Normalizer):
|
|||
flavors = self.list_flavors(get_extra=get_extra)
|
||||
return _utils._filter_list(flavors, name_or_id, filters)
|
||||
|
||||
def search_security_groups(self, name_or_id=None, filters=None):
|
||||
# `filters` could be a dict or a jmespath (str)
|
||||
groups = self.list_security_groups(
|
||||
filters=filters if isinstance(filters, dict) else None
|
||||
)
|
||||
return _utils._filter_list(groups, name_or_id, filters)
|
||||
|
||||
def search_servers(
|
||||
self, name_or_id=None, filters=None, detailed=False,
|
||||
all_projects=False, bare=False):
|
||||
|
|
|
@ -1156,40 +1156,6 @@ class NetworkCloudMixin(_normalize.Normalizer):
|
|||
firewall_group[key + '_id'] = val
|
||||
del firewall_group[key]
|
||||
|
||||
def list_security_groups(self, filters=None):
|
||||
"""List all available security groups.
|
||||
|
||||
:param filters: (optional) dict of filter conditions to push down
|
||||
:returns: A list of security group ``munch.Munch``.
|
||||
|
||||
"""
|
||||
# Security groups not supported
|
||||
if not self._has_secgroups():
|
||||
raise exc.OpenStackCloudUnavailableFeature(
|
||||
"Unavailable feature: security groups"
|
||||
)
|
||||
|
||||
if not filters:
|
||||
filters = {}
|
||||
|
||||
data = []
|
||||
# Handle neutron security groups
|
||||
if self._use_neutron_secgroups():
|
||||
# Neutron returns dicts, so no need to convert objects here.
|
||||
resp = self.network.get('/security-groups.json', params=filters)
|
||||
data = proxy._json_response(
|
||||
resp,
|
||||
error_message="Error fetching security group list")
|
||||
return self._normalize_secgroups(
|
||||
self._get_and_munchify('security_groups', data))
|
||||
|
||||
# Handle nova security groups
|
||||
else:
|
||||
data = proxy._json_response(self.compute.get(
|
||||
'/os-security-groups', params=filters))
|
||||
return self._normalize_secgroups(
|
||||
self._get_and_munchify('security_groups', data))
|
||||
|
||||
@_utils.valid_kwargs("name", "description", "shared", "default",
|
||||
"project_id")
|
||||
def create_qos_policy(self, **kwargs):
|
||||
|
|
|
@ -28,6 +28,45 @@ class SecurityGroupCloudMixin(_normalize.Normalizer):
|
|||
def __init__(self):
|
||||
self.secgroup_source = self.config.config['secgroup_source']
|
||||
|
||||
def search_security_groups(self, name_or_id=None, filters=None):
|
||||
# `filters` could be a dict or a jmespath (str)
|
||||
groups = self.list_security_groups(
|
||||
filters=filters if isinstance(filters, dict) else None
|
||||
)
|
||||
return _utils._filter_list(groups, name_or_id, filters)
|
||||
|
||||
def list_security_groups(self, filters=None):
|
||||
"""List all available security groups.
|
||||
|
||||
:param filters: (optional) dict of filter conditions to push down
|
||||
:returns: A list of security group ``munch.Munch``.
|
||||
|
||||
"""
|
||||
# Security groups not supported
|
||||
if not self._has_secgroups():
|
||||
raise exc.OpenStackCloudUnavailableFeature(
|
||||
"Unavailable feature: security groups"
|
||||
)
|
||||
|
||||
if not filters:
|
||||
filters = {}
|
||||
|
||||
data = []
|
||||
# Handle neutron security groups
|
||||
if self._use_neutron_secgroups():
|
||||
# pass filters dict to the list to filter as much as possible on
|
||||
# the server side
|
||||
return list(
|
||||
self.network.security_groups(allow_unknown_params=True,
|
||||
**filters))
|
||||
|
||||
# Handle nova security groups
|
||||
else:
|
||||
data = proxy._json_response(self.compute.get(
|
||||
'/os-security-groups', params=filters))
|
||||
return self._normalize_secgroups(
|
||||
self._get_and_munchify('security_groups', data))
|
||||
|
||||
def get_security_group(self, name_or_id, filters=None):
|
||||
"""Get a security group by name or ID.
|
||||
|
||||
|
@ -67,8 +106,7 @@ class SecurityGroupCloudMixin(_normalize.Normalizer):
|
|||
error_message = ("Error getting security group with"
|
||||
" ID {id}".format(id=id))
|
||||
if self._use_neutron_secgroups():
|
||||
resp = self.network.get('/security-groups/{id}'.format(id=id))
|
||||
data = proxy._json_response(resp, error_message=error_message)
|
||||
return self.network.get_security_group(id)
|
||||
else:
|
||||
data = proxy._json_response(
|
||||
self.compute.get(
|
||||
|
@ -101,20 +139,17 @@ class SecurityGroupCloudMixin(_normalize.Normalizer):
|
|||
|
||||
data = []
|
||||
security_group_json = {
|
||||
'security_group': {
|
||||
'name': name, 'description': description
|
||||
}}
|
||||
'name': name, 'description': description
|
||||
}
|
||||
if project_id is not None:
|
||||
security_group_json['security_group']['tenant_id'] = project_id
|
||||
security_group_json['tenant_id'] = project_id
|
||||
if self._use_neutron_secgroups():
|
||||
data = proxy._json_response(
|
||||
self.network.post(
|
||||
'/security-groups.json',
|
||||
json=security_group_json),
|
||||
error_message="Error creating security group {0}".format(name))
|
||||
return self.network.create_security_group(
|
||||
**security_group_json)
|
||||
else:
|
||||
data = proxy._json_response(self.compute.post(
|
||||
'/os-security-groups', json=security_group_json))
|
||||
'/os-security-groups',
|
||||
json={'security_group': security_group_json}))
|
||||
return self._normalize_secgroup(
|
||||
self._get_and_munchify('security_group', data))
|
||||
|
||||
|
@ -144,13 +179,8 @@ class SecurityGroupCloudMixin(_normalize.Normalizer):
|
|||
return False
|
||||
|
||||
if self._use_neutron_secgroups():
|
||||
exceptions.raise_from_response(
|
||||
self.network.delete(
|
||||
'/security-groups/{sg_id}.json'.format(
|
||||
sg_id=secgroup['id'])),
|
||||
error_message="Error deleting security group {0}".format(
|
||||
name_or_id)
|
||||
)
|
||||
self.network.delete_security_group(
|
||||
secgroup['id'], ignore_missing=False)
|
||||
return True
|
||||
|
||||
else:
|
||||
|
@ -183,12 +213,10 @@ class SecurityGroupCloudMixin(_normalize.Normalizer):
|
|||
"Security group %s not found." % name_or_id)
|
||||
|
||||
if self._use_neutron_secgroups():
|
||||
data = proxy._json_response(
|
||||
self.network.put(
|
||||
'/security-groups/{sg_id}.json'.format(sg_id=group['id']),
|
||||
json={'security_group': kwargs}),
|
||||
error_message="Error updating security group {0}".format(
|
||||
name_or_id))
|
||||
return self.network.update_security_group(
|
||||
group['id'],
|
||||
**kwargs
|
||||
)
|
||||
else:
|
||||
for key in ('name', 'description'):
|
||||
kwargs.setdefault(key, group[key])
|
||||
|
@ -281,13 +309,12 @@ class SecurityGroupCloudMixin(_normalize.Normalizer):
|
|||
'ethertype': ethertype
|
||||
}
|
||||
if project_id is not None:
|
||||
rule_def['project_id'] = project_id
|
||||
rule_def['tenant_id'] = project_id
|
||||
|
||||
data = proxy._json_response(
|
||||
self.network.post(
|
||||
'/security-group-rules.json',
|
||||
json={'security_group_rule': rule_def}),
|
||||
error_message="Error creating security group rule")
|
||||
return self.network.create_security_group_rule(
|
||||
**rule_def
|
||||
)
|
||||
else:
|
||||
# NOTE: Neutron accepts None for protocol. Nova does not.
|
||||
if protocol is None:
|
||||
|
@ -355,15 +382,10 @@ class SecurityGroupCloudMixin(_normalize.Normalizer):
|
|||
)
|
||||
|
||||
if self._use_neutron_secgroups():
|
||||
try:
|
||||
exceptions.raise_from_response(
|
||||
self.network.delete(
|
||||
'/security-group-rules/{sg_id}.json'.format(
|
||||
sg_id=rule_id)),
|
||||
error_message="Error deleting security group rule "
|
||||
"{0}".format(rule_id))
|
||||
except exc.OpenStackCloudResourceNotFound:
|
||||
return False
|
||||
self.network.delete_security_group_rule(
|
||||
rule_id,
|
||||
ignore_missing=False
|
||||
)
|
||||
return True
|
||||
|
||||
else:
|
||||
|
|
|
@ -26,8 +26,8 @@ class SecurityGroup(resource.Resource, resource.TagMixin):
|
|||
allow_list = True
|
||||
|
||||
_query_mapping = resource.QueryParameters(
|
||||
'description', 'name',
|
||||
project_id='tenant_id',
|
||||
'description', 'name', 'project_id', 'tenant_id', 'revision_number',
|
||||
'sort_dir', 'sort_key',
|
||||
**resource.TagMixin._tag_query_parameters
|
||||
)
|
||||
|
||||
|
@ -39,12 +39,14 @@ class SecurityGroup(resource.Resource, resource.TagMixin):
|
|||
#: The security group name.
|
||||
name = resource.Body('name')
|
||||
#: The ID of the project this security group is associated with.
|
||||
project_id = resource.Body('tenant_id')
|
||||
project_id = resource.Body('project_id')
|
||||
#: Revision number of the security group. *Type: int*
|
||||
revision_number = resource.Body('revision_number', type=int)
|
||||
#: A list of
|
||||
#: :class:`~openstack.network.v2.security_group_rule.SecurityGroupRule`
|
||||
#: objects. *Type: list*
|
||||
security_group_rules = resource.Body('security_group_rules', type=list)
|
||||
#: The ID of the project this security group is associated with.
|
||||
tenant_id = resource.Body('tenant_id')
|
||||
#: Timestamp when the security group was last updated.
|
||||
updated_at = resource.Body('updated_at')
|
||||
|
|
|
@ -28,8 +28,11 @@ class SecurityGroupRule(resource.Resource, resource.TagMixin):
|
|||
_query_mapping = resource.QueryParameters(
|
||||
'description', 'direction', 'protocol',
|
||||
'remote_group_id', 'security_group_id',
|
||||
'port_range_max', 'port_range_min',
|
||||
'remote_ip_prefix', 'revision_number',
|
||||
'project_id', 'tenant_id',
|
||||
'sort_dir', 'sort_key',
|
||||
ether_type='ethertype',
|
||||
project_id='tenant_id',
|
||||
**resource.TagMixin._tag_query_parameters
|
||||
|
||||
)
|
||||
|
@ -58,7 +61,7 @@ class SecurityGroupRule(resource.Resource, resource.TagMixin):
|
|||
#: attribute. If the protocol is ICMP, this value must be an ICMP type.
|
||||
port_range_min = resource.Body('port_range_min', type=int)
|
||||
#: The ID of the project this security group rule is associated with.
|
||||
project_id = resource.Body('tenant_id')
|
||||
project_id = resource.Body('project_id')
|
||||
#: The protocol that is matched by the security group rule.
|
||||
#: Valid values are ``null``, ``tcp``, ``udp``, and ``icmp``.
|
||||
protocol = resource.Body('protocol')
|
||||
|
@ -75,5 +78,7 @@ class SecurityGroupRule(resource.Resource, resource.TagMixin):
|
|||
revision_number = resource.Body('revision_number', type=int)
|
||||
#: The security group ID to associate with this security group rule.
|
||||
security_group_id = resource.Body('security_group_id')
|
||||
#: The ID of the project this security group rule is associated with.
|
||||
tenant_id = resource.Body('tenant_id')
|
||||
#: Timestamp when the security group rule was last updated.
|
||||
updated_at = resource.Body('updated_at')
|
||||
|
|
|
@ -59,7 +59,7 @@ class TestSecurityGroups(base.TestCase):
|
|||
dict(method='GET',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups.json'],
|
||||
append=['v2.0', 'security-groups'],
|
||||
qs_elements=["project_id=%s" % project_id]),
|
||||
json={'security_groups': [neutron_grp_dict]})
|
||||
])
|
||||
|
@ -93,12 +93,13 @@ class TestSecurityGroups(base.TestCase):
|
|||
dict(method='GET',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups.json']),
|
||||
append=['v2.0', 'security-groups']),
|
||||
json={'security_groups': [neutron_grp_dict]}),
|
||||
dict(method='DELETE',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups', '%s.json' % sg_id]),
|
||||
append=['v2.0', 'security-groups', '%s' % sg_id]),
|
||||
status_code=200,
|
||||
json={})
|
||||
])
|
||||
self.assertTrue(self.cloud.delete_security_group('1'))
|
||||
|
@ -126,7 +127,7 @@ class TestSecurityGroups(base.TestCase):
|
|||
dict(method='GET',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups.json']),
|
||||
append=['v2.0', 'security-groups']),
|
||||
json={'security_groups': [neutron_grp_dict]})
|
||||
])
|
||||
self.assertFalse(self.cloud.delete_security_group('10'))
|
||||
|
@ -163,7 +164,7 @@ class TestSecurityGroups(base.TestCase):
|
|||
dict(method='POST',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups.json']),
|
||||
append=['v2.0', 'security-groups']),
|
||||
json={'security_group': new_group},
|
||||
validate=dict(
|
||||
json={'security_group': {
|
||||
|
@ -194,7 +195,7 @@ class TestSecurityGroups(base.TestCase):
|
|||
dict(method='POST',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups.json']),
|
||||
append=['v2.0', 'security-groups']),
|
||||
json={'security_group': new_group},
|
||||
validate=dict(
|
||||
json={'security_group': {
|
||||
|
@ -260,12 +261,12 @@ class TestSecurityGroups(base.TestCase):
|
|||
dict(method='GET',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups.json']),
|
||||
append=['v2.0', 'security-groups']),
|
||||
json={'security_groups': [neutron_grp_dict]}),
|
||||
dict(method='PUT',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups', '%s.json' % sg_id]),
|
||||
append=['v2.0', 'security-groups', '%s' % sg_id]),
|
||||
json={'security_group': update_return},
|
||||
validate=dict(json={
|
||||
'security_group': {'name': new_name}}))
|
||||
|
@ -321,28 +322,36 @@ class TestSecurityGroups(base.TestCase):
|
|||
|
||||
expected_new_rule = copy.copy(expected_args)
|
||||
expected_new_rule['id'] = '1234'
|
||||
expected_new_rule['tenant_id'] = ''
|
||||
expected_new_rule['tenant_id'] = None
|
||||
expected_new_rule['project_id'] = expected_new_rule['tenant_id']
|
||||
|
||||
self.register_uris([
|
||||
dict(method='GET',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups.json']),
|
||||
append=['v2.0', 'security-groups']),
|
||||
json={'security_groups': [neutron_grp_dict]}),
|
||||
dict(method='POST',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-group-rules.json']),
|
||||
append=['v2.0', 'security-group-rules']),
|
||||
json={'security_group_rule': expected_new_rule},
|
||||
validate=dict(json={
|
||||
'security_group_rule': expected_args}))
|
||||
])
|
||||
new_rule = self.cloud.create_security_group_rule(
|
||||
secgroup_name_or_id=neutron_grp_dict['id'], **args)
|
||||
# NOTE(slaweq): don't check location and properties in new rule
|
||||
new_rule.pop("location")
|
||||
new_rule.pop("properties")
|
||||
secgroup_name_or_id=neutron_grp_dict['id'], **args).to_dict(
|
||||
original_names=True
|
||||
)
|
||||
# NOTE(gtema): don't check location and not relevant properties
|
||||
# in new rule
|
||||
new_rule.pop('created_at')
|
||||
new_rule.pop('description')
|
||||
new_rule.pop('location')
|
||||
new_rule.pop('name')
|
||||
new_rule.pop('revision_number')
|
||||
new_rule.pop('tags')
|
||||
new_rule.pop('updated_at')
|
||||
self.assertEqual(expected_new_rule, new_rule)
|
||||
self.assert_calls()
|
||||
|
||||
|
@ -363,31 +372,36 @@ class TestSecurityGroups(base.TestCase):
|
|||
expected_args['port_range_min'] = None
|
||||
expected_args['security_group_id'] = neutron_grp_dict['id']
|
||||
expected_args['tenant_id'] = expected_args['project_id']
|
||||
expected_args.pop('project_id')
|
||||
|
||||
expected_new_rule = copy.copy(expected_args)
|
||||
expected_new_rule['id'] = '1234'
|
||||
expected_new_rule['project_id'] = expected_new_rule['tenant_id']
|
||||
|
||||
self.register_uris([
|
||||
dict(method='GET',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups.json']),
|
||||
append=['v2.0', 'security-groups']),
|
||||
json={'security_groups': [neutron_grp_dict]}),
|
||||
dict(method='POST',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-group-rules.json']),
|
||||
append=['v2.0', 'security-group-rules']),
|
||||
json={'security_group_rule': expected_new_rule},
|
||||
validate=dict(json={
|
||||
'security_group_rule': expected_args}))
|
||||
])
|
||||
new_rule = self.cloud.create_security_group_rule(
|
||||
secgroup_name_or_id=neutron_grp_dict['id'], ** args)
|
||||
secgroup_name_or_id=neutron_grp_dict['id'], ** args).to_dict(
|
||||
original_names=True
|
||||
)
|
||||
# NOTE(slaweq): don't check location and properties in new rule
|
||||
new_rule.pop("location")
|
||||
new_rule.pop("properties")
|
||||
new_rule.pop('created_at')
|
||||
new_rule.pop('description')
|
||||
new_rule.pop('location')
|
||||
new_rule.pop('name')
|
||||
new_rule.pop('revision_number')
|
||||
new_rule.pop('tags')
|
||||
new_rule.pop('updated_at')
|
||||
self.assertEqual(expected_new_rule, new_rule)
|
||||
self.assert_calls()
|
||||
|
||||
|
@ -477,7 +491,7 @@ class TestSecurityGroups(base.TestCase):
|
|||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-group-rules',
|
||||
'%s.json' % rule_id]),
|
||||
'%s' % rule_id]),
|
||||
json={})
|
||||
])
|
||||
self.assertTrue(self.cloud.delete_security_group_rule(rule_id))
|
||||
|
@ -509,7 +523,7 @@ class TestSecurityGroups(base.TestCase):
|
|||
dict(method='GET',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups.json']),
|
||||
append=['v2.0', 'security-groups']),
|
||||
json={'security_groups': [neutron_grp_dict]})
|
||||
])
|
||||
self.assertFalse(self.cloud.delete_security_group(rule_id))
|
||||
|
@ -618,7 +632,7 @@ class TestSecurityGroups(base.TestCase):
|
|||
dict(method='GET',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups.json']),
|
||||
append=['v2.0', 'security-groups']),
|
||||
json={'security_groups': [neutron_grp_dict]}),
|
||||
dict(method='POST',
|
||||
uri='%s/servers/%s/action' % (fakes.COMPUTE_ENDPOINT, '1234'),
|
||||
|
@ -674,7 +688,7 @@ class TestSecurityGroups(base.TestCase):
|
|||
dict(method='GET',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups.json']),
|
||||
append=['v2.0', 'security-groups']),
|
||||
json={'security_groups': [neutron_grp_dict]}),
|
||||
dict(method='POST',
|
||||
uri='%s/servers/%s/action' % (fakes.COMPUTE_ENDPOINT, '1234'),
|
||||
|
@ -729,7 +743,7 @@ class TestSecurityGroups(base.TestCase):
|
|||
dict(method='GET',
|
||||
uri=self.get_mock_url(
|
||||
'network', 'public',
|
||||
append=['v2.0', 'security-groups.json']),
|
||||
append=['v2.0', 'security-groups']),
|
||||
json={'security_groups': [neutron_grp_dict]})
|
||||
])
|
||||
self.assertFalse(self.cloud.add_server_security_groups(
|
||||
|
|
|
@ -57,6 +57,7 @@ EXAMPLE = {
|
|||
'revision_number': 3,
|
||||
'security_group_rules': RULES,
|
||||
'tenant_id': '4',
|
||||
'project_id': '4',
|
||||
'updated_at': '2016-10-14T12:16:57.233772',
|
||||
'tags': ['5']
|
||||
}
|
||||
|
@ -75,6 +76,22 @@ class TestSecurityGroup(base.TestCase):
|
|||
self.assertTrue(sot.allow_delete)
|
||||
self.assertTrue(sot.allow_list)
|
||||
|
||||
self.assertDictEqual({'any_tags': 'tags-any',
|
||||
'description': 'description',
|
||||
'limit': 'limit',
|
||||
'marker': 'marker',
|
||||
'name': 'name',
|
||||
'not_any_tags': 'not-tags-any',
|
||||
'not_tags': 'not-tags',
|
||||
'project_id': 'project_id',
|
||||
'revision_number': 'revision_number',
|
||||
'sort_dir': 'sort_dir',
|
||||
'sort_key': 'sort_key',
|
||||
'tags': 'tags',
|
||||
'tenant_id': 'tenant_id'
|
||||
},
|
||||
sot._query_mapping._mapping)
|
||||
|
||||
def test_make_it(self):
|
||||
sot = security_group.SecurityGroup(**EXAMPLE)
|
||||
self.assertEqual(EXAMPLE['created_at'], sot.created_at)
|
||||
|
@ -85,6 +102,7 @@ class TestSecurityGroup(base.TestCase):
|
|||
self.assertEqual(EXAMPLE['security_group_rules'],
|
||||
sot.security_group_rules)
|
||||
self.assertEqual(dict, type(sot.security_group_rules[0]))
|
||||
self.assertEqual(EXAMPLE['tenant_id'], sot.project_id)
|
||||
self.assertEqual(EXAMPLE['tenant_id'], sot.tenant_id)
|
||||
self.assertEqual(EXAMPLE['project_id'], sot.project_id)
|
||||
self.assertEqual(EXAMPLE['updated_at'], sot.updated_at)
|
||||
self.assertEqual(EXAMPLE['tags'], sot.tags)
|
||||
|
|
|
@ -29,6 +29,7 @@ EXAMPLE = {
|
|||
'revision_number': 9,
|
||||
'security_group_id': '10',
|
||||
'tenant_id': '11',
|
||||
'project_id': '11',
|
||||
'updated_at': '12'
|
||||
}
|
||||
|
||||
|
@ -46,6 +47,29 @@ class TestSecurityGroupRule(base.TestCase):
|
|||
self.assertTrue(sot.allow_delete)
|
||||
self.assertTrue(sot.allow_list)
|
||||
|
||||
self.assertDictEqual({'any_tags': 'tags-any',
|
||||
'description': 'description',
|
||||
'direction': 'direction',
|
||||
'ether_type': 'ethertype',
|
||||
'limit': 'limit',
|
||||
'marker': 'marker',
|
||||
'not_any_tags': 'not-tags-any',
|
||||
'not_tags': 'not-tags',
|
||||
'port_range_max': 'port_range_max',
|
||||
'port_range_min': 'port_range_min',
|
||||
'project_id': 'project_id',
|
||||
'protocol': 'protocol',
|
||||
'remote_group_id': 'remote_group_id',
|
||||
'remote_ip_prefix': 'remote_ip_prefix',
|
||||
'revision_number': 'revision_number',
|
||||
'security_group_id': 'security_group_id',
|
||||
'sort_dir': 'sort_dir',
|
||||
'sort_key': 'sort_key',
|
||||
'tags': 'tags',
|
||||
'tenant_id': 'tenant_id'
|
||||
},
|
||||
sot._query_mapping._mapping)
|
||||
|
||||
def test_make_it(self):
|
||||
sot = security_group_rule.SecurityGroupRule(**EXAMPLE)
|
||||
self.assertEqual(EXAMPLE['created_at'], sot.created_at)
|
||||
|
@ -60,5 +84,6 @@ class TestSecurityGroupRule(base.TestCase):
|
|||
self.assertEqual(EXAMPLE['remote_ip_prefix'], sot.remote_ip_prefix)
|
||||
self.assertEqual(EXAMPLE['revision_number'], sot.revision_number)
|
||||
self.assertEqual(EXAMPLE['security_group_id'], sot.security_group_id)
|
||||
self.assertEqual(EXAMPLE['tenant_id'], sot.project_id)
|
||||
self.assertEqual(EXAMPLE['tenant_id'], sot.tenant_id)
|
||||
self.assertEqual(EXAMPLE['project_id'], sot.project_id)
|
||||
self.assertEqual(EXAMPLE['updated_at'], sot.updated_at)
|
||||
|
|
Loading…
Reference in New Issue