X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=juju%2Fclient%2Foverrides.py;h=f439adb466645812e09492bd24ca9003b639996e;hb=17b26ef759a99c9010ea30e47205bfb332400e74;hp=2a6923b39517f0a8b9b30379fa1fd77091378b7f;hpb=6637bf37c99d012ccd51823501dd7325ba3d6840;p=osm%2FN2VC.git diff --git a/juju/client/overrides.py b/juju/client/overrides.py index 2a6923b..f439adb 100644 --- a/juju/client/overrides.py +++ b/juju/client/overrides.py @@ -1,14 +1,21 @@ from collections import namedtuple +import re -from .facade import ReturnMapping, Type +from .facade import ReturnMapping, Type, TypeEncoder from .import _client +from .import _definitions + __all__ = [ 'Delta', + 'Number', + 'Binary', + 'ConfigValue', ] __patches__ = [ 'ResourcesFacade', + 'AllWatcherFacade', ] @@ -80,3 +87,189 @@ class ResourcesFacade(Type): _params['resources'] = resources reply = await self.rpc(msg) return reply + + +class AllWatcherFacade(Type): + """ + Patch rpc method of allwatcher to add in 'id' stuff. + + """ + async def rpc(self, msg): + if not hasattr(self, 'Id'): + client = _client.ClientFacade.from_connection(self.connection) + + result = await client.WatchAll() + self.Id = result.watcher_id + + msg['Id'] = self.Id + result = await self.connection.rpc(msg, encoder=TypeEncoder) + return result + + +class Number(_definitions.Number): + """ + This type represents a semver string. + + Because it is not standard JSON, the typical from_json parsing fails and + the parsing must be handled specially. + + See https://github.com/juju/version for more info. + """ + numberPat = re.compile(r'^(\d{1,9})\.(\d{1,9})(?:\.|-([a-z]+))(\d{1,9})(\.\d{1,9})?$') # noqa + + def __init__(self, major=None, minor=None, patch=None, tag=None, + build=None, **unknown_fields): + ''' + major : int + minor : int + patch : int + tag : str + build : int + ''' + self.major = int(major or '0') + self.minor = int(minor or '0') + self.patch = int(patch or '0') + self.tag = tag or '' + self.build = int(build or '0') + + def __repr__(self): + return ''.format( + self.major, self.minor, self.patch, self.tag, self.build) + + def __str__(self): + return self.serialize() + + def __eq__(self, other): + return ( + isinstance(other, type(self)) and + other.major == self.major and + other.minor == self.minor and + other.tag == self.tag and + other.patch == self.patch and + other.build == self.build) + + @classmethod + def from_json(cls, data): + parsed = None + if isinstance(data, cls): + return data + elif data is None: + return cls() + elif isinstance(data, dict): + parsed = data + elif isinstance(data, str): + match = cls.numberPat.match(data) + if match: + parsed = { + 'major': match.group(1), + 'minor': match.group(2), + 'tag': match.group(3), + 'patch': match.group(4), + 'build': (match.group(5)[1:] if match.group(5) + else 0), + } + if not parsed: + raise TypeError('Unable to parse Number version string: ' + '{}'.format(data)) + d = {} + for k, v in parsed.items(): + d[cls._toPy.get(k, k)] = v + + return cls(**d) + + def serialize(self): + s = "" + if not self.tag: + s = "{}.{}.{}".format(self.major, self.minor, self.patch) + else: + s = "{}.{}-{}{}".format(self.major, self.minor, self.tag, + self.patch) + if self.build: + s = "{}.{}".format(s, self.build) + return s + + def to_json(self): + return self.serialize() + + +class Binary(_definitions.Binary): + """ + This type represents a semver string with additional series and arch info. + + Because it is not standard JSON, the typical from_json parsing fails and + the parsing must be handled specially. + + See https://github.com/juju/version for more info. + """ + binaryPat = re.compile(r'^(\d{1,9})\.(\d{1,9})(?:\.|-([a-z]+))(\d{1,9})(\.\d{1,9})?-([^-]+)-([^-]+)$') # noqa + + def __init__(self, number=None, series=None, arch=None, **unknown_fields): + ''' + number : Number + series : str + arch : str + ''' + self.number = Number.from_json(number) + self.series = series + self.arch = arch + + def __repr__(self): + return ''.format( + self.number, self.series, self.arch) + + def __str__(self): + return self.serialize() + + def __eq__(self, other): + return ( + isinstance(other, type(self)) and + other.number == self.number and + other.series == self.series and + other.arch == self.arch) + + @classmethod + def from_json(cls, data): + parsed = None + if isinstance(data, cls): + return data + elif data is None: + return cls() + elif isinstance(data, dict): + parsed = data + elif isinstance(data, str): + match = cls.binaryPat.match(data) + if match: + parsed = { + 'number': { + 'major': match.group(1), + 'minor': match.group(2), + 'tag': match.group(3), + 'patch': match.group(4), + 'build': (match.group(5)[1:] if match.group(5) + else 0), + }, + 'series': match.group(6), + 'arch': match.group(7), + } + if parsed is None: + raise TypeError('Unable to parse Binary version string: ' + '{}'.format(data)) + d = {} + for k, v in parsed.items(): + d[cls._toPy.get(k, k)] = v + + return cls(**d) + + def serialize(self): + return "{}-{}-{}".format(self.number.serialize(), + self.series, self.arch) + + def to_json(self): + return self.serialize() + + +class ConfigValue(_definitions.ConfigValue): + def __repr__(self): + return '<{} source={} value={}>'.format(type(self).__name__, + repr(self.source), + repr(self.value))