10 log
= logging
.getLogger("websocket")
15 client = await Connection.connect(info)
18 self
.__requestId
__ = 0
22 def _get_ssl(self
, cert
):
23 return ssl
.create_default_context(
24 purpose
=ssl
.Purpose
.CLIENT_AUTH
, cadata
=cert
)
26 async def open(self
, addr
, cert
=None):
29 kw
['ssl'] = self
._get
_ssl
(cert
)
31 self
.ws
= await websockets
.connect(addr
, **kw
)
34 async def close(self
):
38 result
= await self
.ws
.recv()
39 if result
is not None:
40 result
= json
.loads(result
)
43 async def rpc(self
, msg
):
45 msg
['RequestId'] = self
.__requestID
46 if'Params' not in msg
:
48 if "Version" not in msg
:
49 msg
['Version'] = self
.facades
[msg
['Type']]
50 outgoing
= json
.dumps(msg
, indent
=2)
51 await self
.ws
.send(outgoing
)
52 result
= await self
.recv()
53 log
.debug("send %s got %s", msg
, result
)
54 if result
and 'Error' in result
:
55 raise RuntimeError(result
)
59 async def connect(cls
, info
):
60 uuid
= info
.model_uuid
61 controller
= info
.controller
62 details
= controller
['details']
63 endpoint
= "wss://{}/model/{}/api".format(
64 details
['api-endpoints'][0],
67 await client
.dial(endpoint
, details
['ca-cert'])
68 server_info
= await client
.login(info
)
69 client
.build_facades(server_info
['facades'])
70 log
.info("Driver connected to juju %s", endpoint
)
73 def build_facades(self
, info
):
76 self
.facades
[facade
['Name']] = facade
['Versions'][-1]
78 async def login(self
, info
):
79 account
= info
.account
80 result
= await client
.rpc({
85 "auth-tag": "user-{}".format(account
['user']),
86 "credentials": account
['password'],
87 "Nonce": "".join(random
.sample(string
.printable
, 12)),
89 return result
['Response']