juju / python-libjuju

Python library for the Juju API
Apache License 2.0
59 stars 99 forks source link

Connect to JAAS controller fails #410

Closed xavpaice closed 4 years ago

xavpaice commented 4 years ago

When running connect() to the controller, if the current controller is JAAS (canonical-jimm.jujucharms.com), the connection errors out with "KeyError: 'JIMM'"

If I switch to a controller that I've deployed on the same cloud, the connect works fine (but eats one machine of my quota for the controller).

The traceback I'm seeing:

___________________________________________________________________________ ERROR at setup of test_charmetckeeper_deploy[xenial-local] ___________________________________________________________________________

args = (), kwargs = {}, request = <SubRequest 'controller' for <Function test_charmetckeeper_deploy[xenial-local]>>, setup = <function pytest_fixture_setup.<locals>.wrapper.<locals>.setup at 0x7efdfb030e60>
finalizer = <function pytest_fixture_setup.<locals>.wrapper.<locals>.finalizer at 0x7efdfb030dd0>

    def wrapper(*args, **kwargs):
        request = kwargs['request']
        if strip_request:
            del kwargs['request']

        gen_obj = generator(*args, **kwargs)

        async def setup():
            res = await gen_obj.__anext__()
            return res

        def finalizer():
            """Yield again, to finalize."""
            async def async_finalizer():
                try:
                    await gen_obj.__anext__()
                except StopAsyncIteration:
                    pass
                else:
                    msg = "Async generator fixture didn't stop."
                    msg += "Yield only once."
                    raise ValueError(msg)
            asyncio.get_event_loop().run_until_complete(async_finalizer())

        request.addfinalizer(finalizer)
>       return asyncio.get_event_loop().run_until_complete(setup())

.tox/functional/lib/python3.7/site-packages/pytest_asyncio/plugin.py:102: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/lib/python3.7/asyncio/base_events.py:579: in run_until_complete
    return future.result()
.tox/functional/lib/python3.7/site-packages/pytest_asyncio/plugin.py:85: in setup
    res = await gen_obj.__anext__()
tests/functional/conftest.py:39: in controller
    await _controller.connect()
.tox/functional/lib/python3.7/site-packages/juju/controller.py:111: in connect
    await self._connector.connect_controller(controller_name, **kwargs)
.tox/functional/lib/python3.7/site-packages/juju/client/connector.py:101: in connect_controller
    specified_facades=specified_facades,
.tox/functional/lib/python3.7/site-packages/juju/client/connector.py:69: in connect
    self._connection = await Connection.connect(**kwargs)
.tox/functional/lib/python3.7/site-packages/juju/client/connection.py:299: in connect
    await self._connect_with_redirect([(endpoint, cacert)])
.tox/functional/lib/python3.7/site-packages/juju/client/connection.py:671: in _connect_with_redirect
    self._build_facades(login_result.get('facades', {}))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <juju.client.connection.Connection object at 0x7efdfaee0150>
facades = [{'name': 'Bundle', 'versions': [1]}, {'name': 'Cloud', 'versions': [1, 2, 3, 4, 5]}, {'name': 'Controller', 'versions...'JIMM', 'versions': [1]}, {'name': 'ModelManager', 'versions': [2, 3, 4, 5]}, {'name': 'Pinger', 'versions': [1]}, ...]

    def _build_facades(self, facades):
        self.facades.clear()
        for facade in facades:
            name = facade['name']
            # the following attempts to get the best facade version for the
            # client. The client knows about the best facade versions it speaks,
            # so in order to be compatible forwards and backwards we speak a
            # common facade versions.
            if (name not in client_facades) and (name not in self.specified_facades):
                # if a facade is required but the client doesn't know about
                # it, then log a warning.
                log.warning('unknown facade {}'.format(name))

            try:
                known = []
                # allow the ability to specify a set of facade versions, so the
                # client can define the non-conservitive facade client pinning.
                if name in self.specified_facades:
                    known = self.specified_facades[name]['versions']
                else:
>                   known = client_facades[name]['versions']
E                   KeyError: 'JIMM'

.tox/functional/lib/python3.7/site-packages/juju/client/connection.py:694: KeyError
----------------------------------------------------------------------------------------------- Captured log setup -----------------------------------------------------------------------------------------------
WARNING  juju.client.connection:connection.py:685 unknown facade JIMM
================================================================================================ warnings summary ================================================================================================
.tox/functional/lib/python3.7/site-packages/_pytest/junitxml.py:417
  /home/xav/charms/charm-etckeeper/.tox/functional/lib/python3.7/site-packages/_pytest/junitxml.py:417: PytestDeprecationWarning: The 'junit_family' default value will change to 'xunit2' in pytest 6.0.
  Add 'junit_family=xunit1' to your pytest.ini file to keep the current format in future versions of pytest and silence this warning.
    _issue_warning_captured(deprecated.JUNIT_XML_DEFAULT_FAMILY, config.hook, 2)

-- Docs: https://docs.pytest.org/en/latest/warnings.html
---------------------------------------------------------------- generated xml file: /home/xav/charms/charm-etckeeper/report/functional/junit.xml ----------------------------------------------------------------
----------------------------------------------------------- generated html file: file:///home/xav/charms/charm-etckeeper/report/functional/index.html ------------------------------------------------------------
============================================================================================ short test summary info =============================================================================================
ERROR tests/functional/test_deploy.py::test_charmetckeeper_deploy[xenial-local] - KeyError: 'JIMM'
xavpaice commented 4 years ago

This might be a simpler example, using the controller.py from the example dir:

(venv) xav@xplt:~/repos/python-libjuju/examples$ python3 controller.py
DEBUG:asyncio:Using selector: EpollSelector
DEBUG:juju.client.connection:Driver connected to juju wss://canonical-jimm.jujucharms.com:443/api
DEBUG:juju.client.connection:connection 139800843530448 -> {
  "type": "Admin",
  "request": "Login",
  "version": 3,
  "params": {
    "auth-tag": null,
    "macaroons": [
      [
        {
          "identifier": "redacted",
          "signature": "redacted",
          "location": "jimm",
          "caveats": [
            {
              "cid": "redacted",
              "vid": "redacted",
              "cl": "https://api.jujucharms.com/identity"
            }
          ]
        },
        {
          "identifier": "redacted",
          "signature": "redacted",
          "caveats": [
            {
              "cid": "declared username my_username"
            },
            {
              "cid": "time-before 2020-06-11T00:32:41.490962218Z"
            }
          ]
        }
      ]
    ]
  },
  "request-id": 1
}
DEBUG:juju.client.connection:connection 139800843530448 <- {'request-id': 1, 'response': {'controller-tag': 'controller-3875af18-2e12-11e9-ad13-4bddbe64a218', 'user-info': {'display-name': 'my_username', 'identity': 'user-my_username@external', 'controller-access': '', 'model-access': ''}, 'facades': [{'name': 'Bundle', 'versions': [1]}, {'name': 'Cloud', 'versions': [1, 2, 3, 4, 5]}, {'name': 'Controller', 'versions': [3]}, {'name': 'JIMM', 'versions': [1]}, {'name': 'ModelManager', 'versions': [2, 3, 4, 5]}, {'name': 'Pinger', 'versions': [1]}, {'name': 'UserManager', 'versions': [1]}], 'server-version': '2.6.10'}}
WARNING:juju.client.connection:unknown facade JIMM
Traceback (most recent call last):
  File "controller.py", line 41, in <module>
    loop.run(main())
  File "/home/xav/repos/python-libjuju/examples/venv/lib/python3.7/site-packages/juju/loop.py", line 38, in run
    raise task.exception()
  File "controller.py", line 20, in main
    await controller.connect()
  File "/home/xav/repos/python-libjuju/examples/venv/lib/python3.7/site-packages/juju/controller.py", line 111, in connect
    await self._connector.connect_controller(controller_name, **kwargs)
  File "/home/xav/repos/python-libjuju/examples/venv/lib/python3.7/site-packages/juju/client/connector.py", line 101, in connect_controller
    specified_facades=specified_facades,
  File "/home/xav/repos/python-libjuju/examples/venv/lib/python3.7/site-packages/juju/client/connector.py", line 69, in connect
    self._connection = await Connection.connect(**kwargs)
  File "/home/xav/repos/python-libjuju/examples/venv/lib/python3.7/site-packages/juju/client/connection.py", line 299, in connect
    await self._connect_with_redirect([(endpoint, cacert)])
  File "/home/xav/repos/python-libjuju/examples/venv/lib/python3.7/site-packages/juju/client/connection.py", line 671, in _connect_with_redirect
    self._build_facades(login_result.get('facades', {}))
  File "/home/xav/repos/python-libjuju/examples/venv/lib/python3.7/site-packages/juju/client/connection.py", line 694, in _build_facades
    known = client_facades[name]['versions']
KeyError: 'JIMM'

This is using juju==2.7.1 and Python 3.7.5, with the Juju snap v 2.7.6

xavpaice commented 4 years ago

Unfortunately due to click-happiness I somehow closed this by accident!

hpidcock commented 4 years ago

382 fixes this 2.8.1 will contain this and other fixes