diff --git a/juju/client/connector.py b/juju/client/connector.py index a3a54b1db..e51f610cc 100644 --- a/juju/client/connector.py +++ b/juju/client/connector.py @@ -7,9 +7,9 @@ import macaroonbakery.httpbakery as httpbakery from juju.client.connection import Connection from juju.client.gocookies import GoCookieJar, go_to_py_cookie -from juju.client.jujudata import FileJujuData +from juju.client.jujudata import FileJujuData, API_ENDPOINTS_KEY from juju.client.proxy.factory import proxy_from_config -from juju.errors import JujuConnectionError, JujuError +from juju.errors import JujuConnectionError, JujuError, PylibjujuProgrammingError from juju.client import client log = logging.getLogger('connector') @@ -82,6 +82,11 @@ async def connect(self, **kwargs): await self._connection.close() self._connection = await Connection.connect(**kwargs) + if not self.controller_name: + if 'endpoint' not in kwargs: + raise PylibjujuProgrammingError("Please report this error to the maintainers.") + self.controller_name = self.jujudata.controller_name_by_endpoint(kwargs['endpoint']) + # Check if we support the target controller if not self._connection.info['server-version'].startswith(SUPPORTED_JUJU_API_PREFIX): raise JujuConnectionError("juju server-version %s not supported" % self._connection.info["server-version"]) @@ -108,7 +113,7 @@ async def connect_controller(self, controller_name=None, specified_facades=None) raise JujuConnectionError('No current controller') controller = self.jujudata.controllers()[controller_name] - endpoints = controller['api-endpoints'] + endpoints = controller[API_ENDPOINTS_KEY] accounts = self.jujudata.accounts().get(controller_name, {}) proxy = proxy_from_config(controller.get('proxy-config', None)) @@ -142,7 +147,7 @@ async def connect_model(self, model_name=None, **kwargs): if controller is None: raise JujuConnectionError('Controller {} not found'.format( controller_name)) - endpoints = controller['api-endpoints'] + endpoints = controller[API_ENDPOINTS_KEY] account = self.jujudata.accounts().get(controller_name, {}) models = self.jujudata.models().get(controller_name, {}).get('models', {}) diff --git a/juju/client/jujudata.py b/juju/client/jujudata.py index a4c1d5ff7..00e783408 100644 --- a/juju/client/jujudata.py +++ b/juju/client/jujudata.py @@ -10,9 +10,10 @@ import yaml from juju import tag from juju.client.gocookies import GoCookieJar -from juju.errors import JujuError +from juju.errors import JujuError, PylibjujuProgrammingError from juju.utils import juju_config_dir +API_ENDPOINTS_KEY = 'api-endpoints' class NoModelException(Exception): pass @@ -126,6 +127,23 @@ def load_credential(self, cloud, name=None): except (KeyError, FileNotFoundError): return None, None + def controller_name_by_endpoint(self, endpoint): + """Finds the controller that has the given endpoints, returns the name. + + :param str endpoint: The endpoint of the controller we're looking for + """ + for controller_name, controller in self.controllers().items(): + if isinstance(endpoint, str): + if endpoint in controller[API_ENDPOINTS_KEY]: + return controller_name + elif isinstance(endpoint, list): + for e in endpoint: + if e in controller[API_ENDPOINTS_KEY]: + return controller_name + else: + raise PylibjujuProgrammingError() + raise JujuError(f'Unable to find controller with endpoint {endpoint}') + def controllers(self): return self._load_yaml('controllers.yaml', 'controllers') diff --git a/juju/errors.py b/juju/errors.py index 6ca9711e1..b43e84827 100644 --- a/juju/errors.py +++ b/juju/errors.py @@ -85,6 +85,8 @@ class JujuUnitError(JujuError): class JujuBackupError(JujuError): pass +class PylibjujuProgrammingError(Exception): + pass class JujuConfigError(JujuError): """Exception raised during processing a configuration key-value pair