1515
1616import six
1717
18+ try :
19+ from novaclient .v2 import security_group_rules as compute_secgroup_rules
20+ except ImportError :
21+ from novaclient .v1_1 import security_group_rules as compute_secgroup_rules
22+
1823from openstackclient .common import exceptions
1924from openstackclient .common import parseractions
2025from openstackclient .common import utils
@@ -27,6 +32,20 @@ def _format_security_group_rule_show(obj):
2732 return zip (* sorted (six .iteritems (data )))
2833
2934
35+ def _format_network_port_range (rule ):
36+ port_range = ''
37+ if (rule .protocol != 'icmp' and
38+ (rule .port_range_min or rule .port_range_max )):
39+ port_range_min = str (rule .port_range_min )
40+ port_range_max = str (rule .port_range_max )
41+ if rule .port_range_min is None :
42+ port_range_min = port_range_max
43+ if rule .port_range_max is None :
44+ port_range_max = port_range_min
45+ port_range = port_range_min + ':' + port_range_max
46+ return port_range
47+
48+
3049def _get_columns (item ):
3150 columns = list (item .keys ())
3251 if 'tenant_id' in columns :
@@ -161,6 +180,102 @@ def take_action_compute(self, client, parsed_args):
161180 client .security_group_rules .delete (parsed_args .rule )
162181
163182
183+ class ListSecurityGroupRule (common .NetworkAndComputeLister ):
184+ """List security group rules"""
185+
186+ def update_parser_common (self , parser ):
187+ parser .add_argument (
188+ 'group' ,
189+ metavar = '<group>' ,
190+ nargs = '?' ,
191+ help = 'List all rules in this security group (name or ID)' ,
192+ )
193+ return parser
194+
195+ def _get_column_headers (self , parsed_args ):
196+ column_headers = (
197+ 'ID' ,
198+ 'IP Protocol' ,
199+ 'IP Range' ,
200+ 'Port Range' ,
201+ 'Remote Security Group' ,
202+ )
203+ if parsed_args .group is None :
204+ column_headers = column_headers + ('Security Group' ,)
205+ return column_headers
206+
207+ def take_action_network (self , client , parsed_args ):
208+ column_headers = self ._get_column_headers (parsed_args )
209+ columns = (
210+ 'id' ,
211+ 'protocol' ,
212+ 'remote_ip_prefix' ,
213+ 'port_range_min' ,
214+ 'remote_group_id' ,
215+ )
216+
217+ # Get the security group rules using the requested query.
218+ query = {}
219+ if parsed_args .group is not None :
220+ # NOTE(rtheis): Unfortunately, the security group resource
221+ # does not contain security group rules resources. So use
222+ # the security group ID in a query to get the resources.
223+ security_group_id = client .find_security_group (
224+ parsed_args .group ,
225+ ignore_missing = False
226+ ).id
227+ query = {'security_group_id' : security_group_id }
228+ else :
229+ columns = columns + ('security_group_id' ,)
230+ rules = list (client .security_group_rules (** query ))
231+
232+ # Reformat the rules to display a port range instead
233+ # of just the port range minimum. This maintains
234+ # output compatibility with compute.
235+ for rule in rules :
236+ rule .port_range_min = _format_network_port_range (rule )
237+
238+ return (column_headers ,
239+ (utils .get_item_properties (
240+ s , columns ,
241+ ) for s in rules ))
242+
243+ def take_action_compute (self , client , parsed_args ):
244+ column_headers = self ._get_column_headers (parsed_args )
245+ columns = (
246+ "ID" ,
247+ "IP Protocol" ,
248+ "IP Range" ,
249+ "Port Range" ,
250+ "Remote Security Group" ,
251+ )
252+
253+ rules_to_list = []
254+ if parsed_args .group is not None :
255+ group = utils .find_resource (
256+ client .security_groups ,
257+ parsed_args .group ,
258+ )
259+ rules_to_list = group .rules
260+ else :
261+ columns = columns + ('parent_group_id' ,)
262+ for group in client .security_groups .list ():
263+ rules_to_list .extend (group .rules )
264+
265+ # NOTE(rtheis): Turn the raw rules into resources.
266+ rules = []
267+ for rule in rules_to_list :
268+ rules .append (compute_secgroup_rules .SecurityGroupRule (
269+ client .security_group_rules ,
270+ network_utils .transform_compute_security_group_rule (rule ),
271+ ))
272+
273+ return (column_headers ,
274+ (utils .get_item_properties (
275+ s , columns ,
276+ ) for s in rules ))
277+
278+
164279class ShowSecurityGroupRule (common .NetworkAndComputeShowOne ):
165280 """Display security group rule details"""
166281
0 commit comments