-import logging
-
-from . import model
-
-log = logging.getLogger(__name__)
-
-
-class Endpoint:
- def __init__(self, model, data):
- self.model = model
- self.data = data
-
- def __repr__(self):
- return '<Endpoint {}:{}>'.format(self.application.name, self.name)
-
- @property
- def application(self):
- return self.model.applications[self.data['application-name']]
-
- @property
- def name(self):
- return self.data['relation']['name']
-
- @property
- def interface(self):
- return self.data['relation']['interface']
-
- @property
- def role(self):
- return self.data['relation']['role']
-
- @property
- def scope(self):
- return self.data['relation']['scope']
-
-
-class Relation(model.ModelEntity):
- def __repr__(self):
- return '<Relation id={} {}>'.format(self.entity_id, self.key)
-
- @property
- def endpoints(self):
- return [Endpoint(self.model, data)
- for data in self.safe_data['endpoints']]
-
- @property
- def provides(self):
- """
- The endpoint on the provides side of this relation, or None.
- """
- for endpoint in self.endpoints:
- if endpoint.role == 'provider':
- return endpoint
- return None
-
- @property
- def requires(self):
- """
- The endpoint on the requires side of this relation, or None.
- """
- for endpoint in self.endpoints:
- if endpoint.role == 'requirer':
- return endpoint
- return None
-
- @property
- def peers(self):
- """
- The peers endpoint of this relation, or None.
- """
- for endpoint in self.endpoints:
- if endpoint.role == 'peer':
- return endpoint
- return None
-
- @property
- def is_subordinate(self):
- return any(ep.scope == 'container' for ep in self.endpoints)
-
- @property
- def is_peer(self):
- return any(ep.role == 'peer' for ep in self.endpoints)
-
- def matches(self, *specs):
- """
- Check if this relation matches relationship specs.
-
- Relation specs are strings that would be given to Juju to establish a
- relation, and should be in the form ``<application>[:<endpoint_name>]``
- where the ``:<endpoint_name>`` suffix is optional. If the suffix is
- omitted, this relation will match on any endpoint as long as the given
- application is involved.
-
- In other words, this relation will match a spec if that spec could have
- created this relation.
-
- :return: True if all specs match.
- """
- for spec in specs:
- if ':' in spec:
- app_name, endpoint_name = spec.split(':')
- else:
- app_name, endpoint_name = spec, None
- for endpoint in self.endpoints:
- if app_name == endpoint.application.name and \
- endpoint_name in (endpoint.name, None):
- # found a match for this spec, so move to next one
- break
- else:
- # no match for this spec
- return False
- return True
-
- @property
- def applications(self):
- """
- All applications involved in this relation.
- """
- return [ep.application for ep in self.endpoints]
-
- async def destroy(self):
- raise NotImplementedError()
- # TODO: destroy a relation