- if uuid:
- url = "wss://{}/model/{}/api".format(endpoint, uuid)
- else:
- url = "wss://{}/api".format(endpoint)
- client = cls(endpoint, uuid, username, password, cacert)
- await client.open(url, cacert)
- server_info = await client.login(username, password)
- client.build_facades(server_info['facades'])
- log.info("Driver connected to juju %s", url)
-
- return client
+ client = cls(endpoint, uuid, username, password, cacert, macaroons)
+ await client.open()
+
+ redirect_info = await client.redirect_info()
+ if not redirect_info:
+ server_info = await client.login(username, password, macaroons)
+ client.build_facades(server_info['facades'])
+ return client
+
+ await client.close()
+ servers = [
+ s for servers in redirect_info['servers']
+ for s in servers if s["scope"] == 'public'
+ ]
+ for server in servers:
+ client = cls(
+ "{value}:{port}".format(**server), uuid, username,
+ password, redirect_info['ca-cert'], macaroons)
+ await client.open()
+ try:
+ result = await client.login(username, password, macaroons)
+ if 'discharge-required-error' in result:
+ continue
+ client.build_facades(result['facades'])
+ return client
+ except Exception as e:
+ await client.close()
+ log.exception(e)
+
+ raise Exception(
+ "Couldn't authenticate to %s", endpoint)