juju/python-libjuju

KeyError "controller" when connecting

erik78se opened this issue · 5 comments

Description

I want to test the connection to a controller, when I'm faced with a KeyError 'controller'

It works with the admin account (since it can see the controller model). Also, it works if I grant read access to the controller model which makes no sense.

DEBUG:websockets.client:> TEXT '{\n  "type": "Pinger",\n  "request": "Ping",\n ...,\n  "request-id": 3\n}' [94 bytes]
DEBUG:websockets.client:< TEXT '{"request-id":3,"response":{}}\n' [31 bytes]
DEBUG:juju.client.connection:connection 140522019237424 <- {'request-id': 3, 'response': {}}
DEBUG:websockets.client:< TEXT '{"request-id":2,"response":{"user-models":null}}\n' [49 bytes]
DEBUG:juju.client.connection:connection 140522019237424 <- {'request-id': 2, 'response': {'user-models': None}}
Traceback (most recent call last):
  File "/root/deployments_site/jsync/./connect-controller.py", line 28, in <module>
    jasyncio.run(main())
  File "/usr/local/lib/python3.10/dist-packages/juju/jasyncio.py", line 120, in run
    raise task.exception()
  File "/root/deployments_site/jsync/./connect-controller.py", line 18, in main
    await controller.connect(endpoint="10.10.10.2:17070",
  File "/usr/local/lib/python3.10/dist-packages/juju/controller.py", line 139, in connect
    await self.update_endpoints()
  File "/usr/local/lib/python3.10/dist-packages/juju/controller.py", line 142, in update_endpoints
    info = await self.info()
  File "/usr/local/lib/python3.10/dist-packages/juju/controller.py", line 285, in info
    params = [client.Entity(tag.model(uuids["controller"]))]
KeyError: 'controller'

Urgency

Blocks

Python-libjuju version

2.9.46.0

Juju version

2.9.46

Reproduce / Test

#!/usr/bin/env python3

import logging
from juju.controller import Controller
from juju import jasyncio
import jujuutils

async def main():
    """
    Gets all models from a Juju controller and returns a list of JujuModel objects
    """
    controller = Controller()
    crt = jujuutils.get_controller_cacert('my-controller')
    print(crt)
    await controller.connect(endpoint="10.10.10.2:17070",
                            username='my-user', 
                            password='my-password', 
                            cacert=jujuutils.get_controller_cacert('my-controller.crt'))
    await controller.disconnect()

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    ws_logger = logging.getLogger('websockets.protocol')
    ws_logger.setLevel(logging.INFO)
    jasyncio.run(main())

If I grant the user "read" access to the controller model, it works as a workaround. But this feels like a strange thing.

Yeah I think this needs to be corrected. Looks like that update_endpoints() call was added a while ago to support dynamically update the endpoints using the API (as opposed to the static local/share/controllers.yaml) in HA scenarios. It certainly shouldn't fail for non-admin users, it should just not update. I'll push a fix for this soon 👍

The fix for this is easy, however, testing it requires a fix for #1001

Fixed by #1003