X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=juju%2Fapplication.py;h=74f90579754891a06f65b67c5168f3b15e48f804;hb=9f92750dcbcfcd59367cf9ced122b45ae09f5d9b;hp=90a78ca25e3afdea3c6c768f526c9ddc468aaf09;hpb=d47bd509191abc8217a5568a6c73324467355036;p=osm%2FN2VC.git diff --git a/juju/application.py b/juju/application.py index 90a78ca..74f9057 100644 --- a/juju/application.py +++ b/juju/application.py @@ -3,6 +3,7 @@ import logging from . import model from .client import client +from .placement import parse as parse_placement log = logging.getLogger(__name__) @@ -35,18 +36,39 @@ class Application(model.ModelEntity): if unit.application == self.name ] - def add_relation(self, local_relation, remote_relation): - """Add a relation to another service. + @property + def status(self): + """Get the application status, as set by the charm's leader. + + """ + return self.data['status']['current'] - :param str local_relation: Name of relation on this service - :param str remote_relation: Name of relation on the other service in - the form '[:]' + @property + def status_message(self): + """Get the application status message, as set by the charm's leader. """ - pass + return self.data['status']['message'] + + @property + def tag(self): + return 'application-%s' % self.name + + async def add_relation(self, local_relation, remote_relation): + """Add a relation to another application. + + :param str local_relation: Name of relation on this application + :param str remote_relation: Name of relation on the other + application in the form '[:]' + + """ + if ':' not in local_relation: + local_relation = '{}:{}'.format(self.name, local_relation) + + return await self.model.add_relation(local_relation, remote_relation) async def add_unit(self, count=1, to=None): - """Add one or more units to this service. + """Add one or more units to this application. :param int count: Number of units to add :param str to: Placement directive, e.g.:: @@ -66,7 +88,7 @@ class Application(model.ModelEntity): result = await app_facade.AddUnits( application=self.name, - placement=to, + placement=[parse_placement(to)] if to else None, num_units=count, ) @@ -78,7 +100,7 @@ class Application(model.ModelEntity): add_units = add_unit def allocate(self, budget, value): - """Allocate budget to this service. + """Allocate budget to this application. :param str budget: Name of budget :param int value: Budget limit @@ -87,7 +109,7 @@ class Application(model.ModelEntity): pass def attach(self, resource_name, file_path): - """Upload a file as a resource for this service. + """Upload a file as a resource for this application. :param str resource: Name of the resource :param str file_path: Path to the file to upload @@ -96,24 +118,41 @@ class Application(model.ModelEntity): pass def collect_metrics(self): - """Collect metrics on this service. + """Collect metrics on this application. """ pass - def destroy_relation(self, local_relation, remote_relation): - """Remove a relation to another service. + async def destroy_relation(self, local_relation, remote_relation): + """Remove a relation to another application. - :param str local_relation: Name of relation on this service - :param str remote_relation: Name of relation on the other service in - the form '[:]' + :param str local_relation: Name of relation on this application + :param str remote_relation: Name of relation on the other + application in the form '[:]' """ - pass + if ':' not in local_relation: + local_relation = '{}:{}'.format(self.name, local_relation) + + app_facade = client.ApplicationFacade() + app_facade.connect(self.connection) + + log.debug( + 'Destroying relation %s <-> %s', local_relation, remote_relation) + + return await app_facade.DestroyRelation([ + local_relation, remote_relation]) remove_relation = destroy_relation + async def destroy_unit(self, *unit_names): + """Destroy units by name. + + """ + return await self.model.destroy_units(*unit_names) + destroy_units = destroy_unit + async def destroy(self): - """Remove this service from the model. + """Remove this application from the model. """ app_facade = client.ApplicationFacade() @@ -126,7 +165,7 @@ class Application(model.ModelEntity): remove = destroy async def expose(self): - """Make this service publicly available over the network. + """Make this application publicly available over the network. """ app_facade = client.ApplicationFacade() @@ -137,20 +176,33 @@ class Application(model.ModelEntity): return await app_facade.Expose(self.name) - def get_config(self): - """Return the configuration settings for this service. + async def get_config(self): + """Return the configuration settings dict for this application. """ - pass + app_facade = client.ApplicationFacade() + app_facade.connect(self.connection) + + log.debug( + 'Getting config for %s', self.name) + + return (await app_facade.Get(self.name)).config - def get_constraints(self): - """Return the machine constraints for this service. + async def get_constraints(self): + """Return the machine constraints dict for this application. """ - pass + app_facade = client.ApplicationFacade() + app_facade.connect(self.connection) + + log.debug( + 'Getting constraints for %s', self.name) + + result = (await app_facade.Get(self.name)).constraints + return vars(result) if result else result def get_actions(self, schema=False): - """Get actions defined for this service. + """Get actions defined for this application. :param bool schema: Return the full action schema @@ -158,7 +210,7 @@ class Application(model.ModelEntity): pass def get_resources(self, details=False): - """Return resources for this service. + """Return resources for this application. :param bool details: Include detailed info about resources used by each unit @@ -166,31 +218,74 @@ class Application(model.ModelEntity): """ pass - def run(self, command, timeout=None): - """Run command on all units for this service. + async def run(self, command, timeout=None): + """Run command on all units for this application. :param str command: The command to run :param int timeout: Time to wait before command is considered failed """ - pass + action = client.ActionFacade() + action.connect(self.connection) + + log.debug( + 'Running `%s` on all units of %s', command, self.name) + + # TODO this should return a list of Actions + return await action.Run( + [self.name], + command, + [], + timeout, + [], + ) - def set_config(self, to_default=False, **config): - """Set configuration options for this service. + async def set_annotations(self, annotations): + """Set annotations on this application. - :param bool to_default: Set service options to default values - :param \*\*config: Config key/values + :param annotations map[string]string: the annotations as key/value + pairs. """ - pass + log.debug('Updating annotations on application %s', self.name) + + self.ann_facade = client.AnnotationsFacade() + self.ann_facade.connect(self.connection) - def set_constraints(self, constraints): - """Set machine constraints for this service. + ann = client.EntityAnnotations( + entity=self.name, + annotations=annotations, + ) + return await self.ann_facade.Set([ann]) + + async def set_config(self, config, to_default=False): + """Set configuration options for this application. - :param :class:`juju.Constraints` constraints: Machine constraints + :param config: Dict of configuration to set + :param bool to_default: Set application options to default values """ - pass + app_facade = client.ApplicationFacade() + app_facade.connect(self.connection) + + log.debug( + 'Setting config for %s: %s', self.name, config) + + return await app_facade.Set(self.name, config) + + async def set_constraints(self, constraints): + """Set machine constraints for this application. + + :param dict constraints: Dict of machine constraints + + """ + app_facade = client.ApplicationFacade() + app_facade.connect(self.connection) + + log.debug( + 'Setting constraints for %s: %s', self.name, constraints) + + return await app_facade.SetConstraints(self.name, constraints) def set_meter_status(self, status, info=None): """Set the meter status on this status. @@ -202,21 +297,27 @@ class Application(model.ModelEntity): pass def set_plan(self, plan_name): - """Set the plan for this service, effective immediately. + """Set the plan for this application, effective immediately. :param str plan_name: Name of plan """ pass - def unexpose(self): - """Remove public availability over the network for this service. + async def unexpose(self): + """Remove public availability over the network for this application. """ - pass + app_facade = client.ApplicationFacade() + app_facade.connect(self.connection) + + log.debug( + 'Unexposing %s', self.name) + + return await app_facade.Unexpose(self.name) def update_allocation(self, allocation): - """Update existing allocation for this service. + """Update existing allocation for this application. :param int allocation: The allocation to set @@ -226,12 +327,12 @@ class Application(model.ModelEntity): def upgrade_charm( self, channel=None, force_series=False, force_units=False, path=None, resources=None, revision=-1, switch=None): - """Upgrade the charm for this service. + """Upgrade the charm for this application. :param str channel: Channel to use when getting the charm from the charm store, e.g. 'development' - :param bool force_series: Upgrade even if series of deployed service - is not supported by the new charm + :param bool force_series: Upgrade even if series of deployed + application is not supported by the new charm :param bool force_units: Upgrade all units immediately, even if in error state :param str path: Uprade to a charm located at path @@ -241,3 +342,6 @@ class Application(model.ModelEntity): """ pass + + async def get_metrics(self): + return await self.model.get_metrics(self.tag)