X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FN2VC.git;a=blobdiff_plain;f=modules%2Flibjuju%2Fjuju%2Fapplication.py;h=3f7f02e46236259fa8cd9385e61a277c81feb38f;hp=620e9c998aff2f4c174a41a6fd29df2f4dd6d053;hb=b2a07f566be558a8b59b8b5dedfe8da5ae1b0132;hpb=1a15d1c84fc826fa7996c1c9d221a324edd33432;ds=sidebyside diff --git a/modules/libjuju/juju/application.py b/modules/libjuju/juju/application.py index 620e9c9..3f7f02e 100644 --- a/modules/libjuju/juju/application.py +++ b/modules/libjuju/juju/application.py @@ -51,6 +51,24 @@ class Application(model.ModelEntity): if unit.application == self.name ] + @property + def relations(self): + return [rel for rel in self.model.relations if rel.matches(self.name)] + + def related_applications(self, endpoint_name=None): + apps = {} + for rel in self.relations: + if rel.is_peer: + local_ep, remote_ep = rel.endpoints[0] + else: + def is_us(ep): + return ep.application.name == self.name + local_ep, remote_ep = sorted(rel.endpoints, key=is_us) + if endpoint_name is not None and endpoint_name != local_ep.name: + continue + apps[remote_ep.application.name] = remote_ep.application + return apps + @property def status(self): """Get the application status, as set by the charm's leader. @@ -113,6 +131,31 @@ class Application(model.ModelEntity): add_units = add_unit + async def scale(self, scale=None, scale_change=None): + """ + Set or adjust the scale of this (K8s) application. + + One or the other of scale or scale_change must be provided. + + :param int scale: Scale to which to set this application. + :param int scale_change: Amount by which to adjust the scale of this + application (can be positive or negative). + """ + app_facade = client.ApplicationFacade.from_connection(self.connection) + + if (scale, scale_change) == (None, None): + raise ValueError('Must provide either scale or scale_change') + + log.debug( + 'Scaling application %s %s %s', + self.name, 'to' if scale else 'by', scale or scale_change) + + await app_facade.ScaleApplications([ + client.ScaleApplicationParam(application_tag=self.tag, + scale=scale, + scale_change=scale_change) + ]) + def allocate(self, budget, value): """Allocate budget to this application. @@ -210,22 +253,43 @@ class Application(model.ModelEntity): result = (await app_facade.Get(self.name)).constraints return vars(result) if result else result - def get_actions(self, schema=False): + async def get_actions(self, schema=False): """Get actions defined for this application. :param bool schema: Return the full action schema - + :return dict: The charms actions, empty dict if none are defined. """ - raise NotImplementedError() - - def get_resources(self, details=False): + actions = {} + entity = [{"tag": self.tag}] + action_facade = client.ActionFacade.from_connection(self.connection) + results = ( + await action_facade.ApplicationsCharmsActions(entity)).results + for result in results: + if result.application_tag == self.tag and result.actions: + actions = result.actions + break + if not schema: + actions = {k: v['description'] for k, v in actions.items()} + return actions + + async def get_resources(self): """Return resources for this application. - :param bool details: Include detailed info about resources used by each - unit - + Returns a dict mapping resource name to + :class:`~juju._definitions.CharmResource` instances. """ - raise NotImplementedError() + facade = client.ResourcesFacade.from_connection(self.connection) + response = await facade.ListResources([client.Entity(self.tag)]) + + resources = dict() + for result in response.results: + for resource in result.charm_store_resources or []: + resources[resource.name] = resource + for resource in result.resources or []: + if resource.charmresource: + resource = resource.charmresource + resources[resource.name] = resource + return resources async def run(self, command, timeout=None): """Run command on all units for this application. @@ -266,12 +330,10 @@ class Application(model.ModelEntity): ) return await self.ann_facade.Set([ann]) - async def set_config(self, config, to_default=False): + async def set_config(self, config): """Set configuration options for this application. :param config: Dict of configuration to set - :param bool to_default: Set application options to default values - """ app_facade = client.ApplicationFacade.from_connection(self.connection) @@ -280,6 +342,20 @@ class Application(model.ModelEntity): return await app_facade.Set(self.name, config) + async def reset_config(self, to_default): + """ + Restore application config to default values. + + :param list to_default: A list of config options to be reset to their + default value. + """ + app_facade = client.ApplicationFacade.from_connection(self.connection) + + log.debug( + 'Restoring default config for %s: %s', self.name, to_default) + + return await app_facade.Unset(self.name, to_default) + async def set_constraints(self, constraints): """Set machine constraints for this application.