Merge pull request #13 from petevg/feature/unit-is-leader
[osm/N2VC.git] / juju / unit.py
1 import asyncio
2 import logging
3 from datetime import datetime
4
5 from . import model
6 from .client import client
7
8 log = logging.getLogger(__name__)
9
10
11 class Unit(model.ModelEntity):
12 @property
13 def agent_status(self):
14 """Returns the current agent status string.
15
16 """
17 return self.data['agent-status']['current']
18
19 @property
20 def agent_status_since(self):
21 """Get the time when the `agent_status` was last updated.
22
23 """
24 since = self.data['agent-status']['since']
25 # Juju gives us nanoseconds, but Python only supports microseconds
26 since = since[:26]
27 return datetime.strptime(since, "%Y-%m-%dT%H:%M:%S.%f")
28
29 @property
30 def agent_status_message(self):
31 """Get the agent status message.
32
33 """
34 return self.data['agent-status']['message']
35
36 @property
37 def workload_status(self):
38 """Returns the current workload status string.
39
40 """
41 return self.data['workload-status']['current']
42
43 @property
44 def workload_status_since(self):
45 """Get the time when the `workload_status` was last updated.
46
47 """
48 since = self.data['workload-status']['since']
49 # Juju gives us nanoseconds, but Python only supports microseconds
50 since = since[:26]
51 return datetime.strptime(since, "%Y-%m-%dT%H:%M:%S.%f")
52
53 @property
54 def workload_status_message(self):
55 """Get the workload status message.
56
57 """
58 return self.data['workload-status']['message']
59
60 def add_storage(self, name, constraints=None):
61 """Add unit storage dynamically.
62
63 :param str name: Storage name, as specified by the charm
64 :param str constraints: Comma-separated list of constraints in the
65 form 'POOL,COUNT,SIZE'
66
67 """
68 pass
69
70 def collect_metrics(self):
71 """Collect metrics on this unit.
72
73 """
74 pass
75
76 async def destroy(self):
77 """Destroy this unit.
78
79 """
80 app_facade = client.ApplicationFacade()
81 app_facade.connect(self.connection)
82
83 log.debug(
84 'Destroying %s', self.name)
85
86 return await app_facade.DestroyUnits([self.name])
87 remove = destroy
88
89 def get_resources(self, details=False):
90 """Return resources for this unit.
91
92 :param bool details: Include detailed info about resources used by each
93 unit
94
95 """
96 pass
97
98 def resolved(self, retry=False):
99 """Mark unit errors resolved.
100
101 :param bool retry: Re-execute failed hooks
102
103 """
104 pass
105
106 async def run(self, command, timeout=None):
107 """Run command on this unit.
108
109 :param str command: The command to run
110 :param int timeout: Time to wait before command is considered failed
111
112 Returns a tuple containing the stdout, stderr, and return code
113 from the command.
114
115 """
116 action = client.ActionFacade()
117 action.connect(self.connection)
118
119 log.debug(
120 'Running `%s` on %s', command, self.name)
121
122 res = await action.Run(
123 [],
124 command,
125 [],
126 timeout,
127 [self.name],
128 )
129 return await self.model.wait_for_action(res.results[0].action.tag)
130
131 def run_action(self, action_name, **params):
132 """Run action on this unit.
133
134 :param str action_name: Name of action to run
135 :param \*\*params: Action parameters
136
137 """
138 pass
139
140 def scp(
141 self, source_path, user=None, destination_path=None, proxy=False,
142 scp_opts=None):
143 """Transfer files to this unit.
144
145 :param str source_path: Path of file(s) to transfer
146 :param str user: Remote username
147 :param str destination_path: Destination of transferred files on
148 remote machine
149 :param bool proxy: Proxy through the Juju API server
150 :param str scp_opts: Additional options to the `scp` command
151
152 """
153 pass
154
155 def set_meter_status(self):
156 """Set the meter status on this unit.
157
158 """
159 pass
160
161 def ssh(
162 self, command, user=None, proxy=False, ssh_opts=None):
163 """Execute a command over SSH on this unit.
164
165 :param str command: Command to execute
166 :param str user: Remote username
167 :param bool proxy: Proxy through the Juju API server
168 :param str ssh_opts: Additional options to the `ssh` command
169
170 """
171 pass
172
173 def status_history(self, num=20, utc=False):
174 """Get status history for this unit.
175
176 :param int num: Size of history backlog
177 :param bool utc: Display time as UTC in RFC3339 format
178
179 """
180 pass
181
182 async def is_leader_from_status(self):
183 """
184 Check to see if this unit is the leader. Returns True if so, and
185 False if it is not, or if leadership does not make sense
186 (e.g., there is no leader in this application.)
187
188 This method is a kluge that calls FullStatus in the
189 ClientFacade to get its information. Once
190 https://bugs.launchpad.net/juju/+bug/1643691 is resolved, we
191 should add a simple .is_leader property, and deprecate this
192 method.
193
194 """
195 app = self.name.split("/")[0]
196
197 c = client.ClientFacade()
198 c.connect(self.model.connection)
199
200 status = await c.FullStatus(None)
201
202 return status.applications[app]['units'][self.name].get(
203 'leader', False)