@@ -81,3 +81,103 @@ def str2dict(strdict):
8181 key , sep , value = kv .partition (':' )
8282 result [key ] = value
8383 return result
84+
85+
86+ def format_security_group_rule_show (obj ):
87+ data = transform_compute_security_group_rule (obj )
88+ return zip (* sorted (data .items ()))
89+
90+
91+ def format_network_port_range (rule ):
92+ # Display port range or ICMP type and code. For example:
93+ # - ICMP type: 'type=3'
94+ # - ICMP type and code: 'type=3:code=0'
95+ # - ICMP code: Not supported
96+ # - Matching port range: '443:443'
97+ # - Different port range: '22:24'
98+ # - Single port: '80:80'
99+ # - No port range: ''
100+ port_range = ''
101+ if is_icmp_protocol (rule ['protocol' ]):
102+ if rule ['port_range_min' ]:
103+ port_range += 'type=' + str (rule ['port_range_min' ])
104+ if rule ['port_range_max' ]:
105+ port_range += ':code=' + str (rule ['port_range_max' ])
106+ elif rule ['port_range_min' ] or rule ['port_range_max' ]:
107+ port_range_min = str (rule ['port_range_min' ])
108+ port_range_max = str (rule ['port_range_max' ])
109+ if rule ['port_range_min' ] is None :
110+ port_range_min = port_range_max
111+ if rule ['port_range_max' ] is None :
112+ port_range_max = port_range_min
113+ port_range = port_range_min + ':' + port_range_max
114+ return port_range
115+
116+
117+ def format_remote_ip_prefix (rule ):
118+ remote_ip_prefix = rule ['remote_ip_prefix' ]
119+ if remote_ip_prefix is None :
120+ ethertype = rule ['ether_type' ]
121+ if ethertype == 'IPv4' :
122+ remote_ip_prefix = '0.0.0.0/0'
123+ elif ethertype == 'IPv6' :
124+ remote_ip_prefix = '::/0'
125+ return remote_ip_prefix
126+
127+
128+ def convert_ipvx_case (string ):
129+ if string .lower () == 'ipv4' :
130+ return 'IPv4'
131+ if string .lower () == 'ipv6' :
132+ return 'IPv6'
133+ return string
134+
135+
136+ def is_icmp_protocol (protocol ):
137+ # NOTE(rtheis): Neutron has deprecated protocol icmpv6.
138+ # However, while the OSC CLI doesn't document the protocol,
139+ # the code must still handle it. In addition, handle both
140+ # protocol names and numbers.
141+ if protocol in ['icmp' , 'icmpv6' , 'ipv6-icmp' , '1' , '58' ]:
142+ return True
143+ else :
144+ return False
145+
146+
147+ def convert_to_lowercase (string ):
148+ return string .lower ()
149+
150+
151+ def get_protocol (parsed_args , default_protocol = 'any' ):
152+ protocol = default_protocol
153+ if parsed_args .protocol is not None :
154+ protocol = parsed_args .protocol
155+ if hasattr (parsed_args , "proto" ) and parsed_args .proto is not None :
156+ protocol = parsed_args .proto
157+ if protocol == 'any' :
158+ protocol = None
159+ return protocol
160+
161+
162+ def get_ethertype (parsed_args , protocol ):
163+ ethertype = 'IPv4'
164+ if parsed_args .ethertype is not None :
165+ ethertype = parsed_args .ethertype
166+ elif is_ipv6_protocol (protocol ):
167+ ethertype = 'IPv6'
168+ return ethertype
169+
170+
171+ def is_ipv6_protocol (protocol ):
172+ # NOTE(rtheis): Neutron has deprecated protocol icmpv6.
173+ # However, while the OSC CLI doesn't document the protocol,
174+ # the code must still handle it. In addition, handle both
175+ # protocol names and numbers.
176+ if (
177+ protocol is not None
178+ and protocol .startswith ('ipv6-' )
179+ or protocol in ['icmpv6' , '41' , '43' , '44' , '58' , '59' , '60' ]
180+ ):
181+ return True
182+ else :
183+ return False
0 commit comments