Skip to content

Commit

Permalink
Merge pull request #966 from cderici/controller-name-fix-forward-port
Browse files Browse the repository at this point in the history
#966

#### Description

This is a forward port for the fix #964 for the issue #771 that was on 2.9, bringing it into 3.x.

#### QA Steps

Manual QA should follow the steps described in #771.

Find the details of a controller you bootstrapped (any controller would do):

```sh
 $ juju show-controller --show-password
```

Grab the details there and plug them into either a script or in the repl (repl is awkward to use with the certificate):

```python
 c = Controller()
 await c.connect(endpoint="<ip>:17070", username="admin", password="admin_pass", cacert="ca_cert") # explicit connection with credential values
 # check the name
 print(c.controller_name)
```

All CI tests need to pass.

#### Notes & Discussion

JUJU-4781
  • Loading branch information
jujubot authored Oct 20, 2023
2 parents be013d7 + 7162c6d commit 15616c0
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 5 deletions.
13 changes: 9 additions & 4 deletions juju/client/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
from juju.version import SUPPORTED_MAJOR_VERSION, TARGET_JUJU_VERSION

Expand Down Expand Up @@ -83,6 +83,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
juju_server_version = self._connection.info['server-version']
if not juju_server_version.startswith(TARGET_JUJU_VERSION):
Expand Down Expand Up @@ -112,7 +117,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))
Expand Down Expand Up @@ -146,7 +151,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',
{})
Expand Down
21 changes: 20 additions & 1 deletion juju/client/jujudata.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
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
Expand Down Expand Up @@ -126,6 +128,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')

Expand Down
4 changes: 4 additions & 0 deletions juju/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ class JujuBackupError(JujuError):
pass


class PylibjujuProgrammingError(Exception):
pass


class JujuNotValid(JujuError):
def __init__(self, entity_type, entity_name):
self.entity_type = entity_type
Expand Down

0 comments on commit 15616c0

Please sign in to comment.