summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-06-25 15:16:05 +0000
committerGerrit Code Review <review@openstack.org>2018-06-25 15:16:05 +0000
commit4bde9af89251431791fc8d69fe09d5e17a8fba8f (patch)
treedf0928c1e202b98cf903460bc71768e1db9f1bf7 /openstackclient
parent5d2bd2a7380645bafb0f51e812752754c45ac88f (diff)
parentaaed4b315fa1e86b1ddf73201b5350dbdb4a660e (diff)
downloadpython-openstackclient-4bde9af89251431791fc8d69fe09d5e17a8fba8f.tar.gz
Merge "Network: Add tag support for security group"
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/network/v2/security_group.py43
-rw-r--r--openstackclient/tests/unit/network/v2/fakes.py1
-rw-r--r--openstackclient/tests/unit/network/v2/test_security_group_network.py174
3 files changed, 212 insertions, 6 deletions
diff --git a/openstackclient/network/v2/security_group.py b/openstackclient/network/v2/security_group.py
index 75af3587..ed6c8d7c 100644
--- a/openstackclient/network/v2/security_group.py
+++ b/openstackclient/network/v2/security_group.py
@@ -15,6 +15,7 @@
import argparse
+from osc_lib.command import command
from osc_lib import utils
import six
@@ -23,6 +24,7 @@ from openstackclient.identity import common as identity_common
from openstackclient.network import common
from openstackclient.network import sdk_utils
from openstackclient.network import utils as network_utils
+from openstackclient.network.v2 import _tag
def _format_network_security_group_rules(sg_rules):
@@ -106,6 +108,7 @@ class CreateSecurityGroup(common.NetworkAndComputeShowOne):
help=_("Owner's project (name or ID)")
)
identity_common.add_project_domain_option_to_parser(parser)
+ _tag.add_tag_option_to_parser_for_create(parser, _('security group'))
return parser
def _get_description(self, parsed_args):
@@ -130,6 +133,8 @@ class CreateSecurityGroup(common.NetworkAndComputeShowOne):
# Create the security group and display the results.
obj = client.create_security_group(**attrs)
+ # tags cannot be set when created, so tags need to be set later.
+ _tag.update_tags_for_set(client, obj, parsed_args)
display_columns, property_columns = _get_columns(obj)
data = utils.get_item_properties(
obj,
@@ -198,6 +203,7 @@ class ListSecurityGroup(common.NetworkAndComputeLister):
"(name or ID)")
)
identity_common.add_project_domain_option_to_parser(parser)
+ _tag.add_tag_filtering_option_to_parser(parser, _('security group'))
return parser
def update_parser_compute(self, parser):
@@ -220,19 +226,23 @@ class ListSecurityGroup(common.NetworkAndComputeLister):
).id
filters['tenant_id'] = project_id
filters['project_id'] = project_id
+
+ _tag.get_tag_filtering_args(parsed_args, filters)
data = client.security_groups(**filters)
columns = (
"ID",
"Name",
"Description",
- "Project ID"
+ "Project ID",
+ "tags"
)
column_headers = (
"ID",
"Name",
"Description",
- "Project"
+ "Project",
+ "Tags"
)
return (column_headers,
(utils.get_item_properties(
@@ -282,6 +292,10 @@ class SetSecurityGroup(common.NetworkAndComputeCommand):
)
return parser
+ def update_parser_network(self, parser):
+ _tag.add_tag_option_to_parser_for_set(parser, _('security group'))
+ return parser
+
def take_action_network(self, client, parsed_args):
obj = client.find_security_group(parsed_args.group,
ignore_missing=False)
@@ -295,6 +309,9 @@ class SetSecurityGroup(common.NetworkAndComputeCommand):
# the update.
client.update_security_group(obj, **attrs)
+ # tags is a subresource and it needs to be updated separately.
+ _tag.update_tags_for_set(client, obj, parsed_args)
+
def take_action_compute(self, client, parsed_args):
data = client.api.security_group_find(parsed_args.group)
@@ -344,3 +361,25 @@ class ShowSecurityGroup(common.NetworkAndComputeShowOne):
formatters=_formatters_compute
)
return (display_columns, data)
+
+
+class UnsetSecurityGroup(command.Command):
+ _description = _("Unset security group properties")
+
+ def get_parser(self, prog_name):
+ parser = super(UnsetSecurityGroup, self).get_parser(prog_name)
+ parser.add_argument(
+ 'group',
+ metavar="<group>",
+ help=_("Security group to modify (name or ID)")
+ )
+ _tag.add_tag_option_to_parser_for_unset(parser, _('security group'))
+ return parser
+
+ def take_action(self, parsed_args):
+ client = self.app.client_manager.network
+ obj = client.find_security_group(parsed_args.group,
+ ignore_missing=False)
+
+ # tags is a subresource and it needs to be updated separately.
+ _tag.update_tags_for_unset(client, obj, parsed_args)
diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py
index 0e21e2f8..45392125 100644
--- a/openstackclient/tests/unit/network/v2/fakes.py
+++ b/openstackclient/tests/unit/network/v2/fakes.py
@@ -1132,6 +1132,7 @@ class FakeSecurityGroup(object):
'description': 'security-group-description-' + uuid.uuid4().hex,
'project_id': 'project-id-' + uuid.uuid4().hex,
'security_group_rules': [],
+ 'tags': []
}
# Overwrite default attributes.
diff --git a/openstackclient/tests/unit/network/v2/test_security_group_network.py b/openstackclient/tests/unit/network/v2/test_security_group_network.py
index 35b7e366..83208287 100644
--- a/openstackclient/tests/unit/network/v2/test_security_group_network.py
+++ b/openstackclient/tests/unit/network/v2/test_security_group_network.py
@@ -40,8 +40,8 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
project = identity_fakes.FakeProject.create_one_project()
domain = identity_fakes.FakeDomain.create_one_domain()
# The security group to be created.
- _security_group = \
- network_fakes.FakeSecurityGroup.create_one_security_group()
+ _security_group = (
+ network_fakes.FakeSecurityGroup.create_one_security_group())
columns = (
'description',
@@ -49,6 +49,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
'name',
'project_id',
'rules',
+ 'tags',
)
data = (
@@ -57,6 +58,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
_security_group.name,
_security_group.project_id,
'',
+ _security_group.tags,
)
def setUp(self):
@@ -67,6 +69,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
self.projects_mock.get.return_value = self.project
self.domains_mock.get.return_value = self.domain
+ self.network.set_tags = mock.Mock(return_value=None)
# Get the command object to test
self.cmd = security_group.CreateSecurityGroup(self.app, self.namespace)
@@ -118,6 +121,43 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
+ def _test_create_with_tag(self, add_tags=True):
+ arglist = [self._security_group.name]
+ if add_tags:
+ arglist += ['--tag', 'red', '--tag', 'blue']
+ else:
+ arglist += ['--no-tag']
+
+ verifylist = [
+ ('name', self._security_group.name),
+ ]
+ if add_tags:
+ verifylist.append(('tags', ['red', 'blue']))
+ else:
+ verifylist.append(('no_tag', True))
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = (self.cmd.take_action(parsed_args))
+
+ self.network.create_security_group.assert_called_once_with(**{
+ 'description': self._security_group.name,
+ 'name': self._security_group.name,
+ })
+ if add_tags:
+ self.network.set_tags.assert_called_once_with(
+ self._security_group,
+ tests_utils.CompareBySet(['red', 'blue']))
+ else:
+ self.assertFalse(self.network.set_tags.called)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+ def test_create_with_tags(self):
+ self._test_create_with_tag(add_tags=True)
+
+ def test_create_with_no_tag(self):
+ self._test_create_with_tag(add_tags=False)
+
class TestDeleteSecurityGroupNetwork(TestSecurityGroupNetwork):
@@ -214,6 +254,7 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork):
'Name',
'Description',
'Project',
+ 'Tags',
)
data = []
@@ -223,6 +264,7 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork):
grp.name,
grp.description,
grp.project_id,
+ grp.tags,
))
def setUp(self):
@@ -300,12 +342,38 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
+ def test_list_with_tag_options(self):
+ arglist = [
+ '--tags', 'red,blue',
+ '--any-tags', 'red,green',
+ '--not-tags', 'orange,yellow',
+ '--not-any-tags', 'black,white',
+ ]
+ verifylist = [
+ ('tags', ['red', 'blue']),
+ ('any_tags', ['red', 'green']),
+ ('not_tags', ['orange', 'yellow']),
+ ('not_any_tags', ['black', 'white']),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.security_groups.assert_called_once_with(
+ **{'tags': 'red,blue',
+ 'any_tags': 'red,green',
+ 'not_tags': 'orange,yellow',
+ 'not_any_tags': 'black,white'}
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
class TestSetSecurityGroupNetwork(TestSecurityGroupNetwork):
# The security group to be set.
- _security_group = \
- network_fakes.FakeSecurityGroup.create_one_security_group()
+ _security_group = (
+ network_fakes.FakeSecurityGroup.create_one_security_group(
+ attrs={'tags': ['green', 'red']}))
def setUp(self):
super(TestSetSecurityGroupNetwork, self).setUp()
@@ -314,6 +382,7 @@ class TestSetSecurityGroupNetwork(TestSecurityGroupNetwork):
self.network.find_security_group = mock.Mock(
return_value=self._security_group)
+ self.network.set_tags = mock.Mock(return_value=None)
# Get the command object to test
self.cmd = security_group.SetSecurityGroup(self.app, self.namespace)
@@ -366,6 +435,34 @@ class TestSetSecurityGroupNetwork(TestSecurityGroupNetwork):
)
self.assertIsNone(result)
+ def _test_set_tags(self, with_tags=True):
+ if with_tags:
+ arglist = ['--tag', 'red', '--tag', 'blue']
+ verifylist = [('tags', ['red', 'blue'])]
+ expected_args = ['red', 'blue', 'green']
+ else:
+ arglist = ['--no-tag']
+ verifylist = [('no_tag', True)]
+ expected_args = []
+ arglist.append(self._security_group.name)
+ verifylist.append(
+ ('group', self._security_group.name))
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ self.assertTrue(self.network.update_security_group.called)
+ self.network.set_tags.assert_called_once_with(
+ self._security_group,
+ tests_utils.CompareBySet(expected_args))
+ self.assertIsNone(result)
+
+ def test_set_with_tags(self):
+ self._test_set_tags(with_tags=True)
+
+ def test_set_with_no_tag(self):
+ self._test_set_tags(with_tags=False)
+
class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
@@ -385,6 +482,7 @@ class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
'name',
'project_id',
'rules',
+ 'tags',
)
data = (
@@ -394,6 +492,7 @@ class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
_security_group.project_id,
security_group._format_network_security_group_rules(
[_security_group_rule._info]),
+ _security_group.tags,
)
def setUp(self):
@@ -424,3 +523,70 @@ class TestShowSecurityGroupNetwork(TestSecurityGroupNetwork):
self._security_group.id, ignore_missing=False)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
+
+
+class TestUnsetSecurityGroupNetwork(TestSecurityGroupNetwork):
+
+ # The security group to be unset.
+ _security_group = (
+ network_fakes.FakeSecurityGroup.create_one_security_group(
+ attrs={'tags': ['green', 'red']}))
+
+ def setUp(self):
+ super(TestUnsetSecurityGroupNetwork, self).setUp()
+
+ self.network.update_security_group = mock.Mock(return_value=None)
+
+ self.network.find_security_group = mock.Mock(
+ return_value=self._security_group)
+ self.network.set_tags = mock.Mock(return_value=None)
+
+ # Get the command object to test
+ self.cmd = security_group.UnsetSecurityGroup(self.app, self.namespace)
+
+ def test_set_no_options(self):
+ self.assertRaises(tests_utils.ParserException,
+ self.check_parser, self.cmd, [], [])
+
+ def test_set_no_updates(self):
+ arglist = [
+ self._security_group.name,
+ ]
+ verifylist = [
+ ('group', self._security_group.name),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ self.assertFalse(self.network.update_security_group.called)
+ self.assertFalse(self.network.set_tags.called)
+ self.assertIsNone(result)
+
+ def _test_unset_tags(self, with_tags=True):
+ if with_tags:
+ arglist = ['--tag', 'red', '--tag', 'blue']
+ verifylist = [('tags', ['red', 'blue'])]
+ expected_args = ['green']
+ else:
+ arglist = ['--all-tag']
+ verifylist = [('all_tag', True)]
+ expected_args = []
+ arglist.append(self._security_group.name)
+ verifylist.append(
+ ('group', self._security_group.name))
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ self.assertFalse(self.network.update_security_group.called)
+ self.network.set_tags.assert_called_once_with(
+ self._security_group,
+ tests_utils.CompareBySet(expected_args))
+ self.assertIsNone(result)
+
+ def test_unset_with_tags(self):
+ self._test_unset_tags(with_tags=True)
+
+ def test_unset_with_all_tag(self):
+ self._test_unset_tags(with_tags=False)