Add source security group support to create rule
The 'security group rule create' command was updated to support a source security group. Now either a source IP address block or source security group can be specified when creating a rule. The default remains the same. Change-Id: If57de2871810caddeeaee96482eb34146968e173 Closes-Bug: #1522969
This commit is contained in:
		| @@ -14,7 +14,7 @@ Create a new security group rule | |||||||
|  |  | ||||||
|     os security group rule create |     os security group rule create | ||||||
|         [--proto <proto>] |         [--proto <proto>] | ||||||
|         [--src-ip <ip-address>] |         [--src-ip <ip-address> | --src-group <group>] | ||||||
|         [--dst-port <port-range>] |         [--dst-port <port-range>] | ||||||
|         <group> |         <group> | ||||||
|  |  | ||||||
| @@ -24,7 +24,11 @@ Create a new security group rule | |||||||
|  |  | ||||||
| .. option:: --src-ip <ip-address> | .. option:: --src-ip <ip-address> | ||||||
|  |  | ||||||
|     Source IP (may use CIDR notation; default: 0.0.0.0/0) |     Source IP address block (may use CIDR notation; default: 0.0.0.0/0) | ||||||
|  |  | ||||||
|  | .. option:: --src-group <group> | ||||||
|  |  | ||||||
|  |     Source security group (ID only) | ||||||
|  |  | ||||||
| .. option:: --dst-port <port-range> | .. option:: --dst-port <port-range> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -111,11 +111,18 @@ class CreateSecurityGroupRule(show.ShowOne): | |||||||
|             default="tcp", |             default="tcp", | ||||||
|             help="IP protocol (icmp, tcp, udp; default: tcp)", |             help="IP protocol (icmp, tcp, udp; default: tcp)", | ||||||
|         ) |         ) | ||||||
|         parser.add_argument( |         source_group = parser.add_mutually_exclusive_group() | ||||||
|  |         source_group.add_argument( | ||||||
|             "--src-ip", |             "--src-ip", | ||||||
|             metavar="<ip-address>", |             metavar="<ip-address>", | ||||||
|             default="0.0.0.0/0", |             default="0.0.0.0/0", | ||||||
|             help="Source IP (may use CIDR notation; default: 0.0.0.0/0)", |             help="Source IP address block (may use CIDR notation; default: " | ||||||
|  |                  "0.0.0.0/0)", | ||||||
|  |         ) | ||||||
|  |         source_group.add_argument( | ||||||
|  |             "--src-group", | ||||||
|  |             metavar="<group>", | ||||||
|  |             help="Source security group (ID only)", | ||||||
|         ) |         ) | ||||||
|         parser.add_argument( |         parser.add_argument( | ||||||
|             "--dst-port", |             "--dst-port", | ||||||
| @@ -145,6 +152,7 @@ class CreateSecurityGroupRule(show.ShowOne): | |||||||
|             from_port, |             from_port, | ||||||
|             to_port, |             to_port, | ||||||
|             parsed_args.src_ip, |             parsed_args.src_ip, | ||||||
|  |             parsed_args.src_group, | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         info = _xform_security_group_rule(data._info) |         info = _xform_security_group_rule(data._info) | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ from openstackclient.compute.v2 import security_group | |||||||
| from openstackclient.tests.compute.v2 import fakes as compute_fakes | from openstackclient.tests.compute.v2 import fakes as compute_fakes | ||||||
| from openstackclient.tests import fakes | from openstackclient.tests import fakes | ||||||
| from openstackclient.tests.identity.v2_0 import fakes as identity_fakes | from openstackclient.tests.identity.v2_0 import fakes as identity_fakes | ||||||
|  | from openstackclient.tests import utils | ||||||
|  |  | ||||||
|  |  | ||||||
| security_group_id = '11' | security_group_id = '11' | ||||||
| @@ -25,6 +26,7 @@ security_group_name = 'wide-open' | |||||||
| security_group_description = 'nothing but net' | security_group_description = 'nothing but net' | ||||||
|  |  | ||||||
| security_group_rule_id = '1' | security_group_rule_id = '1' | ||||||
|  | security_group_rule_cidr = '0.0.0.0/0' | ||||||
|  |  | ||||||
| SECURITY_GROUP = { | SECURITY_GROUP = { | ||||||
|     'id': security_group_id, |     'id': security_group_id, | ||||||
| @@ -37,7 +39,7 @@ SECURITY_GROUP_RULE = { | |||||||
|     'id': security_group_rule_id, |     'id': security_group_rule_id, | ||||||
|     'group': {}, |     'group': {}, | ||||||
|     'ip_protocol': 'tcp', |     'ip_protocol': 'tcp', | ||||||
|     'ip_range': '0.0.0.0/0', |     'ip_range': {'cidr': security_group_rule_cidr}, | ||||||
|     'parent_group_id': security_group_id, |     'parent_group_id': security_group_id, | ||||||
|     'from_port': 0, |     'from_port': 0, | ||||||
|     'to_port': 0, |     'to_port': 0, | ||||||
| @@ -47,7 +49,7 @@ SECURITY_GROUP_RULE_ICMP = { | |||||||
|     'id': security_group_rule_id, |     'id': security_group_rule_id, | ||||||
|     'group': {}, |     'group': {}, | ||||||
|     'ip_protocol': 'icmp', |     'ip_protocol': 'icmp', | ||||||
|     'ip_range': '0.0.0.0/0', |     'ip_range': {'cidr': security_group_rule_cidr}, | ||||||
|     'parent_group_id': security_group_id, |     'parent_group_id': security_group_id, | ||||||
|     'from_port': -1, |     'from_port': -1, | ||||||
|     'to_port': -1, |     'to_port': -1, | ||||||
| @@ -115,7 +117,8 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): | |||||||
|             'tcp', |             'tcp', | ||||||
|             0, |             0, | ||||||
|             0, |             0, | ||||||
|             '0.0.0.0/0', |             security_group_rule_cidr, | ||||||
|  |             None, | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         collist = ( |         collist = ( | ||||||
| @@ -131,7 +134,7 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): | |||||||
|             {}, |             {}, | ||||||
|             security_group_rule_id, |             security_group_rule_id, | ||||||
|             'tcp', |             'tcp', | ||||||
|             '', |             security_group_rule_cidr, | ||||||
|             security_group_id, |             security_group_id, | ||||||
|             '0:0', |             '0:0', | ||||||
|         ) |         ) | ||||||
| @@ -166,7 +169,8 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): | |||||||
|             'tcp', |             'tcp', | ||||||
|             20, |             20, | ||||||
|             21, |             21, | ||||||
|             '0.0.0.0/0', |             security_group_rule_cidr, | ||||||
|  |             None, | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         collist = ( |         collist = ( | ||||||
| @@ -182,7 +186,7 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): | |||||||
|             {}, |             {}, | ||||||
|             security_group_rule_id, |             security_group_rule_id, | ||||||
|             'tcp', |             'tcp', | ||||||
|             '', |             security_group_rule_cidr, | ||||||
|             security_group_id, |             security_group_id, | ||||||
|             '20:21', |             '20:21', | ||||||
|         ) |         ) | ||||||
| @@ -192,6 +196,7 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): | |||||||
|         sg_rule = copy.deepcopy(SECURITY_GROUP_RULE) |         sg_rule = copy.deepcopy(SECURITY_GROUP_RULE) | ||||||
|         sg_rule['from_port'] = 22 |         sg_rule['from_port'] = 22 | ||||||
|         sg_rule['to_port'] = 22 |         sg_rule['to_port'] = 22 | ||||||
|  |         sg_rule['group'] = {'name': security_group_name} | ||||||
|         self.sg_rules_mock.create.return_value = FakeSecurityGroupRuleResource( |         self.sg_rules_mock.create.return_value = FakeSecurityGroupRuleResource( | ||||||
|             None, |             None, | ||||||
|             sg_rule, |             sg_rule, | ||||||
| @@ -201,10 +206,12 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): | |||||||
|         arglist = [ |         arglist = [ | ||||||
|             security_group_name, |             security_group_name, | ||||||
|             '--dst-port', '22', |             '--dst-port', '22', | ||||||
|  |             '--src-group', security_group_id, | ||||||
|         ] |         ] | ||||||
|         verifylist = [ |         verifylist = [ | ||||||
|             ('group', security_group_name), |             ('group', security_group_name), | ||||||
|             ('dst_port', (22, 22)), |             ('dst_port', (22, 22)), | ||||||
|  |             ('src_group', security_group_id), | ||||||
|         ] |         ] | ||||||
|         parsed_args = self.check_parser(self.cmd, arglist, verifylist) |         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||||
|  |  | ||||||
| @@ -217,7 +224,8 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): | |||||||
|             'tcp', |             'tcp', | ||||||
|             22, |             22, | ||||||
|             22, |             22, | ||||||
|             '0.0.0.0/0', |             security_group_rule_cidr, | ||||||
|  |             security_group_id, | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         collist = ( |         collist = ( | ||||||
| @@ -230,10 +238,10 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): | |||||||
|         ) |         ) | ||||||
|         self.assertEqual(collist, columns) |         self.assertEqual(collist, columns) | ||||||
|         datalist = ( |         datalist = ( | ||||||
|             {}, |             {'name': security_group_name}, | ||||||
|             security_group_rule_id, |             security_group_rule_id, | ||||||
|             'tcp', |             'tcp', | ||||||
|             '', |             security_group_rule_cidr, | ||||||
|             security_group_id, |             security_group_id, | ||||||
|             '22:22', |             '22:22', | ||||||
|         ) |         ) | ||||||
| @@ -267,7 +275,8 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): | |||||||
|             'udp', |             'udp', | ||||||
|             0, |             0, | ||||||
|             0, |             0, | ||||||
|             '0.0.0.0/0', |             security_group_rule_cidr, | ||||||
|  |             None, | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         collist = ( |         collist = ( | ||||||
| @@ -283,26 +292,31 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): | |||||||
|             {}, |             {}, | ||||||
|             security_group_rule_id, |             security_group_rule_id, | ||||||
|             'udp', |             'udp', | ||||||
|             '', |             security_group_rule_cidr, | ||||||
|             security_group_id, |             security_group_id, | ||||||
|             '0:0', |             '0:0', | ||||||
|         ) |         ) | ||||||
|         self.assertEqual(datalist, data) |         self.assertEqual(datalist, data) | ||||||
|  |  | ||||||
|     def test_security_group_rule_create_icmp(self): |     def test_security_group_rule_create_icmp(self): | ||||||
|  |         sg_rule_cidr = '10.0.2.0/24' | ||||||
|  |         sg_rule = copy.deepcopy(SECURITY_GROUP_RULE_ICMP) | ||||||
|  |         sg_rule['ip_range'] = {'cidr': sg_rule_cidr} | ||||||
|         self.sg_rules_mock.create.return_value = FakeSecurityGroupRuleResource( |         self.sg_rules_mock.create.return_value = FakeSecurityGroupRuleResource( | ||||||
|             None, |             None, | ||||||
|             copy.deepcopy(SECURITY_GROUP_RULE_ICMP), |             sg_rule, | ||||||
|             loaded=True, |             loaded=True, | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         arglist = [ |         arglist = [ | ||||||
|             security_group_name, |             security_group_name, | ||||||
|             '--proto', 'ICMP', |             '--proto', 'ICMP', | ||||||
|  |             '--src-ip', sg_rule_cidr, | ||||||
|         ] |         ] | ||||||
|         verifylist = [ |         verifylist = [ | ||||||
|             ('group', security_group_name), |             ('group', security_group_name), | ||||||
|             ('proto', 'ICMP'), |             ('proto', 'ICMP'), | ||||||
|  |             ('src_ip', sg_rule_cidr) | ||||||
|         ] |         ] | ||||||
|         parsed_args = self.check_parser(self.cmd, arglist, verifylist) |         parsed_args = self.check_parser(self.cmd, arglist, verifylist) | ||||||
|  |  | ||||||
| @@ -315,7 +329,8 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): | |||||||
|             'ICMP', |             'ICMP', | ||||||
|             -1, |             -1, | ||||||
|             -1, |             -1, | ||||||
|             '0.0.0.0/0', |             sg_rule_cidr, | ||||||
|  |             None, | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         collist = ( |         collist = ( | ||||||
| @@ -331,8 +346,19 @@ class TestSecurityGroupRuleCreate(TestSecurityGroupRule): | |||||||
|             {}, |             {}, | ||||||
|             security_group_rule_id, |             security_group_rule_id, | ||||||
|             'icmp', |             'icmp', | ||||||
|             '', |             sg_rule_cidr, | ||||||
|             security_group_id, |             security_group_id, | ||||||
|             '', |             '', | ||||||
|         ) |         ) | ||||||
|         self.assertEqual(datalist, data) |         self.assertEqual(datalist, data) | ||||||
|  |  | ||||||
|  |     def test_security_group_rule_create_src_invalid(self): | ||||||
|  |         arglist = [ | ||||||
|  |             security_group_name, | ||||||
|  |             '--proto', 'ICMP', | ||||||
|  |             '--src-ip', security_group_rule_cidr, | ||||||
|  |             '--src-group', security_group_id, | ||||||
|  |         ] | ||||||
|  |  | ||||||
|  |         self.assertRaises(utils.ParserException, | ||||||
|  |                           self.check_parser, self.cmd, arglist, []) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Richard Theis
					Richard Theis