| Adam Israel | dcdf82b | 2017-08-15 15:26:43 -0400 | [diff] [blame] | 1 | import logging |
| 2 | |
| 3 | from . import model |
| 4 | |
| 5 | log = logging.getLogger(__name__) |
| 6 | |
| 7 | |
| Adam Israel | c3e6c2e | 2018-03-01 09:31:50 -0500 | [diff] [blame] | 8 | class Endpoint: |
| 9 | def __init__(self, model, data): |
| 10 | self.model = model |
| 11 | self.data = data |
| 12 | |
| 13 | def __repr__(self): |
| 14 | return '<Endpoint {}:{}>'.format(self.application.name, self.name) |
| 15 | |
| 16 | @property |
| 17 | def application(self): |
| 18 | return self.model.applications[self.data['application-name']] |
| 19 | |
| 20 | @property |
| 21 | def name(self): |
| 22 | return self.data['relation']['name'] |
| 23 | |
| 24 | @property |
| 25 | def interface(self): |
| 26 | return self.data['relation']['interface'] |
| 27 | |
| 28 | @property |
| 29 | def role(self): |
| 30 | return self.data['relation']['role'] |
| 31 | |
| 32 | @property |
| 33 | def scope(self): |
| 34 | return self.data['relation']['scope'] |
| 35 | |
| 36 | |
| Adam Israel | dcdf82b | 2017-08-15 15:26:43 -0400 | [diff] [blame] | 37 | class Relation(model.ModelEntity): |
| Adam Israel | c3e6c2e | 2018-03-01 09:31:50 -0500 | [diff] [blame] | 38 | def __repr__(self): |
| 39 | return '<Relation id={} {}>'.format(self.entity_id, self.key) |
| 40 | |
| 41 | @property |
| 42 | def endpoints(self): |
| 43 | return [Endpoint(self.model, data) |
| 44 | for data in self.safe_data['endpoints']] |
| 45 | |
| 46 | @property |
| 47 | def provides(self): |
| 48 | """ |
| 49 | The endpoint on the provides side of this relation, or None. |
| 50 | """ |
| 51 | for endpoint in self.endpoints: |
| 52 | if endpoint.role == 'provider': |
| 53 | return endpoint |
| 54 | return None |
| 55 | |
| 56 | @property |
| 57 | def requires(self): |
| 58 | """ |
| 59 | The endpoint on the requires side of this relation, or None. |
| 60 | """ |
| 61 | for endpoint in self.endpoints: |
| 62 | if endpoint.role == 'requirer': |
| 63 | return endpoint |
| 64 | return None |
| 65 | |
| 66 | @property |
| 67 | def peers(self): |
| 68 | """ |
| 69 | The peers endpoint of this relation, or None. |
| 70 | """ |
| 71 | for endpoint in self.endpoints: |
| 72 | if endpoint.role == 'peer': |
| 73 | return endpoint |
| 74 | return None |
| 75 | |
| 76 | @property |
| 77 | def is_subordinate(self): |
| 78 | return any(ep.scope == 'container' for ep in self.endpoints) |
| 79 | |
| 80 | @property |
| 81 | def is_peer(self): |
| 82 | return any(ep.role == 'peer' for ep in self.endpoints) |
| 83 | |
| 84 | def matches(self, *specs): |
| 85 | """ |
| 86 | Check if this relation matches relationship specs. |
| 87 | |
| 88 | Relation specs are strings that would be given to Juju to establish a |
| 89 | relation, and should be in the form ``<application>[:<endpoint_name>]`` |
| 90 | where the ``:<endpoint_name>`` suffix is optional. If the suffix is |
| 91 | omitted, this relation will match on any endpoint as long as the given |
| 92 | application is involved. |
| 93 | |
| 94 | In other words, this relation will match a spec if that spec could have |
| 95 | created this relation. |
| 96 | |
| 97 | :return: True if all specs match. |
| 98 | """ |
| 99 | for spec in specs: |
| 100 | if ':' in spec: |
| 101 | app_name, endpoint_name = spec.split(':') |
| 102 | else: |
| 103 | app_name, endpoint_name = spec, None |
| 104 | for endpoint in self.endpoints: |
| 105 | if app_name == endpoint.application.name and \ |
| 106 | endpoint_name in (endpoint.name, None): |
| 107 | # found a match for this spec, so move to next one |
| 108 | break |
| 109 | else: |
| 110 | # no match for this spec |
| 111 | return False |
| 112 | return True |
| 113 | |
| 114 | @property |
| 115 | def applications(self): |
| 116 | """ |
| 117 | All applications involved in this relation. |
| 118 | """ |
| 119 | return [ep.application for ep in self.endpoints] |
| 120 | |
| Adam Israel | dcdf82b | 2017-08-15 15:26:43 -0400 | [diff] [blame] | 121 | async def destroy(self): |
| 122 | raise NotImplementedError() |
| 123 | # TODO: destroy a relation |