X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FN2VC.git;a=blobdiff_plain;f=modules%2Flibjuju%2Fjuju%2Fconstraints.py;fp=modules%2Flibjuju%2Fjuju%2Fconstraints.py;h=998862d02508499dd28d0f20983e1f5858498213;hp=0000000000000000000000000000000000000000;hb=68858c1915122c2dbc8999a5cd3229694abf5f3a;hpb=032a71b2a6692b8b4e30f629a1f906d246f06736 diff --git a/modules/libjuju/juju/constraints.py b/modules/libjuju/juju/constraints.py new file mode 100644 index 0000000..998862d --- /dev/null +++ b/modules/libjuju/juju/constraints.py @@ -0,0 +1,84 @@ +# +# Module that parses constraints +# +# The current version of juju core expects the client to take +# constraints given in the form "mem=10G foo=bar" and parse them into +# json that looks like {"mem": 10240, "foo": "bar"}. This module helps us +# accomplish that task. +# +# We do not attempt to duplicate the checking done in +# client/_client.py:Value here. That class will verify that the +# constraints keys are valid, and that we can successfully dump the +# constraints dict to json. +# +# Once https://bugs.launchpad.net/juju/+bug/1645402 is addressed, this +# module should be deprecated. +# + +import re + +# Matches on a string specifying memory size +MEM = re.compile('^[1-9][0-9]*[MGTP]$') + +# Multiplication factors to get Megabytes +# https://github.com/juju/juju/blob/master/constraints/constraints.go#L666 +FACTORS = { + "M": 1, + "G": 1024, + "T": 1024 * 1024, + "P": 1024 * 1024 * 1024 +} + +SNAKE1 = re.compile(r'(.)([A-Z][a-z]+)') +SNAKE2 = re.compile('([a-z0-9])([A-Z])') + + +def parse(constraints): + """ + Constraints must be expressed as a string containing only spaces + and key value pairs joined by an '='. + + """ + if not constraints: + return None + + if type(constraints) is dict: + # Fowards compatibilty: already parsed + return constraints + + constraints = { + normalize_key(k): normalize_value(v) for k, v in [ + s.split("=") for s in constraints.split(" ")]} + + return constraints + + +def normalize_key(key): + key = key.strip() + + key = key.replace("-", "_") # Our _client lib wants "_" in place of "-" + + # Convert camelCase to snake_case + key = SNAKE1.sub(r'\1_\2', key) + key = SNAKE2.sub(r'\1_\2', key).lower() + + return key + + +def normalize_value(value): + value = value.strip() + + if MEM.match(value): + # Translate aliases to Megabytes. e.g. 1G = 10240 + return int(value[:-1]) * FACTORS[value[-1:]] + + if "," in value: + # Handle csv strings. + values = value.split(",") + values = [normalize_value(v) for v in values] + return values + + if value.isdigit(): + return int(value) + + return value