1919from osc_lib .i18n import _
2020
2121
22+ # TODO(dtroyer): Mingrate this to osc-lib
23+ class InvalidValue (Exception ):
24+ """An argument value is not valid: wrong type, out of range, etc"""
25+ message = "Supplied value is not valid"
26+
27+
2228class APIv2 (api .BaseAPI ):
2329 """Compute v2 API"""
2430
@@ -27,6 +33,29 @@ def __init__(self, **kwargs):
2733
2834 # Overrides
2935
36+ def _check_integer (self , value , msg = None ):
37+ """Attempt to convert value to an integer
38+
39+ Raises InvalidValue on failure
40+
41+ :param value:
42+ Convert this to an integer. None is converted to 0 (zero).
43+ :param msg:
44+ An alternate message for the exception, must include exactly
45+ one substitution to receive the attempted value.
46+ """
47+
48+ if value is None :
49+ return 0
50+
51+ try :
52+ value = int (value )
53+ except (TypeError , ValueError ):
54+ if not msg :
55+ msg = "%s is not an integer" % value
56+ raise InvalidValue (msg )
57+ return value
58+
3059 # TODO(dtroyer): Override find() until these fixes get into an osc-lib
3160 # minimum release
3261 def find (
@@ -209,3 +238,71 @@ def security_group_set(
209238 json = {'security_group' : security_group },
210239 ).json ()['security_group' ]
211240 return None
241+
242+ # Security Group Rules
243+
244+ def security_group_rule_create (
245+ self ,
246+ security_group_id = None ,
247+ ip_protocol = None ,
248+ from_port = None ,
249+ to_port = None ,
250+ remote_ip = None ,
251+ remote_group = None ,
252+ ):
253+ """Create a new security group rule
254+
255+ https://developer.openstack.org/api-ref/compute/#create-security-group-rule
256+
257+ :param string security_group_id:
258+ Security group ID
259+ :param ip_protocol:
260+ IP protocol, 'tcp', 'udp' or 'icmp'
261+ :param from_port:
262+ Source port
263+ :param to_port:
264+ Destination port
265+ :param remote_ip:
266+ Source IP address in CIDR notation
267+ :param remote_group:
268+ Remote security group
269+ """
270+
271+ url = "/os-security-group-rules"
272+
273+ if ip_protocol .lower () not in ['icmp' , 'tcp' , 'udp' ]:
274+ raise InvalidValue (
275+ "%(s) is not one of 'icmp', 'tcp', or 'udp'" % ip_protocol
276+ )
277+
278+ params = {
279+ 'parent_group_id' : security_group_id ,
280+ 'ip_protocol' : ip_protocol ,
281+ 'from_port' : self ._check_integer (from_port ),
282+ 'to_port' : self ._check_integer (to_port ),
283+ 'cidr' : remote_ip ,
284+ 'group_id' : remote_group ,
285+ }
286+
287+ return self .create (
288+ url ,
289+ json = {'security_group_rule' : params },
290+ )['security_group_rule' ]
291+
292+ def security_group_rule_delete (
293+ self ,
294+ security_group_rule_id = None ,
295+ ):
296+ """Delete a security group rule
297+
298+ https://developer.openstack.org/api-ref/compute/#delete-security-group-rule
299+
300+ :param string security_group_rule_id:
301+ Security group rule ID
302+ """
303+
304+ url = "/os-security-group-rules"
305+ if security_group_rule_id is not None :
306+ return self .delete ('/%s/%s' % (url , security_group_rule_id ))
307+
308+ return None
0 commit comments