+import asyncio
import base64
import io
import json
import string
import subprocess
import websockets
+from http.client import HTTPSConnection
import yaml
-from juju.errors import JujuAPIError
+from juju import tag
+from juju.errors import JujuAPIError, JujuConnectionError
log = logging.getLogger("websocket")
raise JujuAPIError(result)
return result
+ def http_headers(self):
+ """Return dictionary of http headers necessary for making an http
+ connection to the endpoint of this Connection.
+
+ :return: Dictionary of headers
+
+ """
+ if not self.username:
+ return {}
+
+ creds = u'{}:{}'.format(
+ tag.user(self.username),
+ self.password or ''
+ )
+ token = base64.b64encode(creds.encode())
+ return {
+ 'Authorization': 'Basic {}'.format(token.decode())
+ }
+
+ def https_connection(self):
+ """Return an https connection to this Connection's endpoint.
+
+ Returns a 3-tuple containing::
+
+ 1. The :class:`HTTPSConnection` instance
+ 2. Dictionary of auth headers to be used with the connection
+ 3. The root url path (str) to be used for requests.
+
+ """
+ endpoint = self.endpoint
+ host, remainder = endpoint.split(':', 1)
+ port = remainder
+ if '/' in remainder:
+ port, _ = remainder.split('/', 1)
+
+ conn = HTTPSConnection(
+ host, int(port),
+ context=self._get_ssl(self.cacert),
+ )
+
+ path = (
+ "/model/{}".format(self.uuid)
+ if self.uuid else ""
+ )
+ return conn, self.http_headers(), path
+
async def clone(self):
"""Return a new Connection, connected to the same websocket endpoint
as this one.
"""
jujudata = JujuData()
controller_name = jujudata.current_controller()
+ if not controller_name:
+ raise JujuConnectionError('No current controller')
return await cls.connect_controller(controller_name)
self.path = os.path.abspath(os.path.expanduser(self.path))
def current_controller(self):
- cmd = shlex.split('juju show-controller --format yaml')
+ cmd = shlex.split('juju list-controllers --format yaml')
output = subprocess.check_output(cmd)
output = yaml.safe_load(output)
- return list(output.keys())[0]
+ return output.get('current-controller', '')
def controllers(self):
return self._load_yaml('controllers.yaml', 'controllers')