Skip to content

Commit 4a651b9

Browse files
Merge branch 'master' into pr-doc-destroy-model
2 parents de88c05 + a0380b2 commit 4a651b9

3 files changed

Lines changed: 35 additions & 11 deletions

File tree

juju/client/connection.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ async def connect(
230230
If uuid is None, the connection will be to the controller. Otherwise it
231231
will be to the model.
232232
233-
:param str endpoint: The hostname:port of the controller to connect to.
233+
:param str endpoint: The hostname:port of the controller to connect to (or list of strings).
234234
:param str uuid: The model UUID to connect to (None for a
235235
controller-only connection).
236236
:param str username: The username for controller-local users (or None
@@ -256,6 +256,8 @@ async def connect(
256256
self = cls()
257257
if endpoint is None:
258258
raise ValueError('no endpoint provided')
259+
if not isinstance(endpoint, str) and not isinstance(endpoint, list):
260+
raise TypeError("Endpoint should be either str or list")
259261
self.uuid = uuid
260262
if bakery_client is None:
261263
bakery_client = httpbakery.Client()
@@ -279,6 +281,7 @@ async def connect(
279281
self.addr = None
280282
self.ws = None
281283
self.endpoint = None
284+
self.endpoints = None
282285
self.cacert = None
283286
self.info = None
284287

@@ -297,7 +300,11 @@ async def connect(
297300
if max_frame_size is None:
298301
max_frame_size = self.MAX_FRAME_SIZE
299302
self.max_frame_size = max_frame_size
300-
await self._connect_with_redirect([(endpoint, cacert)])
303+
await self._connect_with_redirect(
304+
[(endpoint, cacert)]
305+
if isinstance(endpoint, str)
306+
else [(e, cacert) for e in endpoint]
307+
)
301308
return self
302309

303310
@property
@@ -570,7 +577,11 @@ async def reconnect(self):
570577
return
571578
async with monitor.reconnecting:
572579
await self.close()
573-
await self._connect_with_login([(self.endpoint, self.cacert)])
580+
await self._connect_with_login(
581+
[(self.endpoint, self.cacert)]
582+
if not self.endpoints else
583+
self.endpoints
584+
)
574585

575586
async def _connect(self, endpoints):
576587
if len(endpoints) == 0:
@@ -660,6 +671,8 @@ async def _connect_with_login(self, endpoints):
660671
finally:
661672
if not success:
662673
await self.close()
674+
else:
675+
self._pinger_task.start()
663676

664677
async def _connect_with_redirect(self, endpoints):
665678
try:

juju/client/connector.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ async def connect(self, **kwargs):
6767
for macaroon in kwargs.pop('macaroons'):
6868
jar.set_cookie(go_to_py_cookie(macaroon))
6969
self._connection = await Connection.connect(**kwargs)
70+
controller = self.jujudata.controllers()[
71+
self.jujudata.current_controller()
72+
]
73+
self._connection.endpoints = [
74+
(e, controller["ca-cert"])
75+
for e in controller["api-endpoints"]
76+
]
7077

7178
async def disconnect(self):
7279
"""Shut down the watcher task and close websockets.
@@ -86,13 +93,11 @@ async def connect_controller(self, controller_name=None, specified_facades=None)
8693
raise JujuConnectionError('No current controller')
8794

8895
controller = self.jujudata.controllers()[controller_name]
89-
# TODO change Connection so we can pass all the endpoints
90-
# instead of just the first.
91-
endpoint = controller['api-endpoints'][0]
96+
endpoints = controller['api-endpoints']
9297
accounts = self.jujudata.accounts().get(controller_name, {})
9398

9499
await self.connect(
95-
endpoint=endpoint,
100+
endpoint=endpoints,
96101
uuid=None,
97102
username=accounts.get('user'),
98103
password=accounts.get('password'),
@@ -119,9 +124,7 @@ async def connect_model(self, model_name=None):
119124
if controller is None:
120125
raise JujuConnectionError('Controller {} not found'.format(
121126
controller_name))
122-
# TODO change Connection so we can pass all the endpoints
123-
# instead of just the first one.
124-
endpoint = controller['api-endpoints'][0]
127+
endpoints = controller['api-endpoints']
125128
account = self.jujudata.accounts().get(controller_name, {})
126129
models = self.jujudata.models().get(controller_name, {}).get('models',
127130
{})
@@ -135,7 +138,7 @@ async def connect_model(self, model_name=None):
135138
# and also remove the need for base.CleanModel to
136139
# subclass JujuData.
137140
await self.connect(
138-
endpoint=endpoint,
141+
endpoint=endpoints,
139142
uuid=models[model_name]['uuid'],
140143
username=account.get('user'),
141144
password=account.get('password'),

juju/controller.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,14 @@ def controller_name(self):
180180
def controller_uuid(self):
181181
return self._connector.controller_uuid
182182

183+
@property
184+
def api_endpoints(self):
185+
controller_name = self._connector.jujudata.current_controller()
186+
if controller_name:
187+
return self._connector.jujudata.controllers().get(controller_name).get(
188+
"api-endpoints"
189+
)
190+
183191
async def disconnect(self):
184192
"""Shut down the watcher task and close websockets.
185193

0 commit comments

Comments
 (0)