Skip to content

Commit d559686

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Refactor security group rule create to use SDK"
2 parents ef1faf7 + d906507 commit d559686

9 files changed

Lines changed: 434 additions & 345 deletions

File tree

doc/source/command-objects/security-group-rule.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ Create a new security group rule
3232

3333
.. option:: --dst-port <port-range>
3434

35-
Destination port, may be a range: 137:139 (default: 0; only required for proto tcp and udp)
35+
Destination port, may be a single port or port range: 137:139
36+
(only required for IP protocols tcp and udp)
3637

3738
.. describe:: <group>
3839

openstackclient/compute/v2/security_group.py

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,12 @@
1616

1717
"""Compute v2 Security Group action implementations"""
1818

19-
import six
20-
2119
try:
2220
from novaclient.v2 import security_group_rules
2321
except ImportError:
2422
from novaclient.v1_1 import security_group_rules
2523

2624
from openstackclient.common import command
27-
from openstackclient.common import parseractions
2825
from openstackclient.common import utils
2926

3027

@@ -56,68 +53,6 @@ def _xform_security_group_rule(sgroup):
5653
return info
5754

5855

59-
class CreateSecurityGroupRule(command.ShowOne):
60-
"""Create a new security group rule"""
61-
62-
def get_parser(self, prog_name):
63-
parser = super(CreateSecurityGroupRule, self).get_parser(prog_name)
64-
parser.add_argument(
65-
'group',
66-
metavar='<group>',
67-
help='Create rule in this security group (name or ID)',
68-
)
69-
parser.add_argument(
70-
"--proto",
71-
metavar="<proto>",
72-
default="tcp",
73-
help="IP protocol (icmp, tcp, udp; default: tcp)",
74-
)
75-
source_group = parser.add_mutually_exclusive_group()
76-
source_group.add_argument(
77-
"--src-ip",
78-
metavar="<ip-address>",
79-
default="0.0.0.0/0",
80-
help="Source IP address block (may use CIDR notation; default: "
81-
"0.0.0.0/0)",
82-
)
83-
source_group.add_argument(
84-
"--src-group",
85-
metavar="<group>",
86-
help="Source security group (ID only)",
87-
)
88-
parser.add_argument(
89-
"--dst-port",
90-
metavar="<port-range>",
91-
default=(0, 0),
92-
action=parseractions.RangeAction,
93-
help="Destination port, may be a range: 137:139 (default: 0; "
94-
"only required for proto tcp and udp)",
95-
)
96-
return parser
97-
98-
def take_action(self, parsed_args):
99-
compute_client = self.app.client_manager.compute
100-
group = utils.find_resource(
101-
compute_client.security_groups,
102-
parsed_args.group,
103-
)
104-
if parsed_args.proto.lower() == 'icmp':
105-
from_port, to_port = -1, -1
106-
else:
107-
from_port, to_port = parsed_args.dst_port
108-
data = compute_client.security_group_rules.create(
109-
group.id,
110-
parsed_args.proto,
111-
from_port,
112-
to_port,
113-
parsed_args.src_ip,
114-
parsed_args.src_group,
115-
)
116-
117-
info = _xform_security_group_rule(data._info)
118-
return zip(*sorted(six.iteritems(info)))
119-
120-
12156
class ListSecurityGroupRule(command.Lister):
12257
"""List security group rules"""
12358

openstackclient/network/v2/security_group_rule.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import six
1717

1818
from openstackclient.common import exceptions
19+
from openstackclient.common import parseractions
1920
from openstackclient.common import utils
2021
from openstackclient.network import common
2122
from openstackclient.network import utils as network_utils
@@ -34,6 +35,105 @@ def _get_columns(item):
3435
return tuple(sorted(columns))
3536

3637

38+
def _convert_to_lowercase(string):
39+
return string.lower()
40+
41+
42+
class CreateSecurityGroupRule(common.NetworkAndComputeShowOne):
43+
"""Create a new security group rule"""
44+
45+
def update_parser_common(self, parser):
46+
parser.add_argument(
47+
'group',
48+
metavar='<group>',
49+
help='Create rule in this security group (name or ID)',
50+
)
51+
# TODO(rtheis): Add support for additional protocols for network.
52+
# Until then, continue enforcing the compute choices.
53+
parser.add_argument(
54+
"--proto",
55+
metavar="<proto>",
56+
default="tcp",
57+
choices=['icmp', 'tcp', 'udp'],
58+
type=_convert_to_lowercase,
59+
help="IP protocol (icmp, tcp, udp; default: tcp)",
60+
)
61+
source_group = parser.add_mutually_exclusive_group()
62+
source_group.add_argument(
63+
"--src-ip",
64+
metavar="<ip-address>",
65+
default="0.0.0.0/0",
66+
help="Source IP address block (may use CIDR notation; default: "
67+
"0.0.0.0/0)",
68+
)
69+
source_group.add_argument(
70+
"--src-group",
71+
metavar="<group>",
72+
help="Source security group (ID only)",
73+
)
74+
parser.add_argument(
75+
"--dst-port",
76+
metavar="<port-range>",
77+
default=(0, 0),
78+
action=parseractions.RangeAction,
79+
help="Destination port, may be a single port or port range: "
80+
"137:139 (only required for IP protocols tcp and udp)",
81+
)
82+
return parser
83+
84+
def take_action_network(self, client, parsed_args):
85+
# Get the security group ID to hold the rule.
86+
security_group_id = client.find_security_group(
87+
parsed_args.group,
88+
ignore_missing=False
89+
).id
90+
91+
# Build the create attributes.
92+
attrs = {}
93+
# TODO(rtheis): Add --direction option. Until then, continue
94+
# with the default of 'ingress'.
95+
attrs['direction'] = 'ingress'
96+
# TODO(rtheis): Add --ethertype option. Until then, continue
97+
# with the default of 'IPv4'
98+
attrs['ethertype'] = 'IPv4'
99+
# TODO(rtheis): Add port range support (type and code) for icmp
100+
# protocol. Until then, continue ignoring the port range.
101+
if parsed_args.proto != 'icmp':
102+
attrs['port_range_min'] = parsed_args.dst_port[0]
103+
attrs['port_range_max'] = parsed_args.dst_port[1]
104+
attrs['protocol'] = parsed_args.proto
105+
if parsed_args.src_group is not None:
106+
attrs['remote_group_id'] = parsed_args.src_group
107+
else:
108+
attrs['remote_ip_prefix'] = parsed_args.src_ip
109+
attrs['security_group_id'] = security_group_id
110+
111+
# Create and show the security group rule.
112+
obj = client.create_security_group_rule(**attrs)
113+
columns = _get_columns(obj)
114+
data = utils.get_item_properties(obj, columns)
115+
return (columns, data)
116+
117+
def take_action_compute(self, client, parsed_args):
118+
group = utils.find_resource(
119+
client.security_groups,
120+
parsed_args.group,
121+
)
122+
if parsed_args.proto == 'icmp':
123+
from_port, to_port = -1, -1
124+
else:
125+
from_port, to_port = parsed_args.dst_port
126+
obj = client.security_group_rules.create(
127+
group.id,
128+
parsed_args.proto,
129+
from_port,
130+
to_port,
131+
parsed_args.src_ip,
132+
parsed_args.src_group,
133+
)
134+
return _format_security_group_rule_show(obj._info)
135+
136+
37137
class DeleteSecurityGroupRule(common.NetworkAndComputeCommand):
38138
"""Delete a security group rule"""
39139

openstackclient/tests/compute/v2/fakes.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -393,13 +393,13 @@ def create_one_security_group_rule(attrs=None, methods=None):
393393

394394
# Set default attributes.
395395
security_group_rule_attrs = {
396-
'from_port': -1,
396+
'from_port': 0,
397397
'group': {},
398398
'id': 'security-group-rule-id-' + uuid.uuid4().hex,
399-
'ip_protocol': 'icmp',
399+
'ip_protocol': 'tcp',
400400
'ip_range': {'cidr': '0.0.0.0/0'},
401401
'parent_group_id': 'security-group-id-' + uuid.uuid4().hex,
402-
'to_port': -1,
402+
'to_port': 0,
403403
}
404404

405405
# Overwrite default attributes.

0 commit comments

Comments
 (0)