From 17b26ef759a99c9010ea30e47205bfb332400e74 Mon Sep 17 00:00:00 2001 From: Adam Stokes Date: Tue, 27 Jun 2017 16:08:41 -0400 Subject: [PATCH] Adds support for getting/setting config on a model (#152) * Adds support for getting/setting config on a model Signed-off-by: Adam Stokes * Fix docstring parameter Signed-off-by: Adam Stokes * Support ConfigValue type for interacting with model config --- juju/client/overrides.py | 8 ++++++++ juju/model.py | 28 ++++++++++++++++++++++------ tests/integration/test_model.py | 17 ++++++++++++++++- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/juju/client/overrides.py b/juju/client/overrides.py index 6ad47e9..f439adb 100644 --- a/juju/client/overrides.py +++ b/juju/client/overrides.py @@ -10,6 +10,7 @@ __all__ = [ 'Delta', 'Number', 'Binary', + 'ConfigValue', ] __patches__ = [ @@ -265,3 +266,10 @@ class Binary(_definitions.Binary): def to_json(self): return self.serialize() + + +class ConfigValue(_definitions.ConfigValue): + def __repr__(self): + return '<{} source={} value={}>'.format(type(self).__name__, + repr(self.source), + repr(self.value)) diff --git a/juju/model.py b/juju/model.py index 7b86ba3..bd8709a 100644 --- a/juju/model.py +++ b/juju/model.py @@ -22,6 +22,7 @@ import theblues.errors from . import tag, utils from .client import client from .client import connection +from .client.client import ConfigValue from .constraints import parse as parse_constraints, normalize_key from .delta import get_entity_delta from .delta import get_entity_class @@ -1255,11 +1256,20 @@ class Model(object): """ raise NotImplementedError() - def get_config(self): + async def get_config(self): """Return the configuration settings for this model. + :returns: A ``dict`` mapping keys to `ConfigValue` instances, + which have `source` and `value` attributes. """ - raise NotImplementedError() + config_facade = client.ModelConfigFacade.from_connection( + self.connection + ) + result = await config_facade.ModelGet() + config = result.config + for key, value in config.items(): + config[key] = ConfigValue.from_json(value) + return config def get_constraints(self): """Return the machine constraints for this model. @@ -1440,13 +1450,19 @@ class Model(object): """ raise NotImplementedError() - def set_config(self, **config): + async def set_config(self, config): """Set configuration keys on this model. - :param \*\*config: Config key/values - + :param dict config: Mapping of config keys to either string values or + `ConfigValue` instances, as returned by `get_config`. """ - raise NotImplementedError() + config_facade = client.ModelConfigFacade.from_connection( + self.connection + ) + for key, value in config.items(): + if isinstance(value, ConfigValue): + config[key] = value.value + await config_facade.ModelSet(config) def set_constraints(self, constraints): """Set machine constraints on this model. diff --git a/tests/integration/test_model.py b/tests/integration/test_model.py index 37f51c0..8506786 100644 --- a/tests/integration/test_model.py +++ b/tests/integration/test_model.py @@ -5,10 +5,12 @@ import pytest from .. import base from juju.model import Model +from juju.client.client import ConfigValue MB = 1 GB = 1024 -SSH_KEY = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsYMJGNGG74HAJha3n2CFmWYsOOaORnJK6VqNy86pj0MIpvRXBzFzVy09uPQ66GOQhTEoJHEqE77VMui7+62AcMXT+GG7cFHcnU8XVQsGM6UirCcNyWNysfiEMoAdZScJf/GvoY87tMEszhZIUV37z8PUBx6twIqMdr31W1J0IaPa+sV6FEDadeLaNTvancDcHK1zuKsL39jzAg7+LYjKJfEfrsQP+lj/EQcjtKqlhVS5kzsJVfx8ZEd0xhW5G7N6bCdKNalS8mKCMaBXJpijNQ82AiyqCIDCRrre2To0/i7pTjRiL0U9f9mV3S4NJaQaokR050w/ZLySFf6F7joJT mathijs@Qrama-Mathijs' +SSH_KEY = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsYMJGNGG74HAJha3n2CFmWYsOOaORnJK6VqNy86pj0MIpvRXBzFzVy09uPQ66GOQhTEoJHEqE77VMui7+62AcMXT+GG7cFHcnU8XVQsGM6UirCcNyWNysfiEMoAdZScJf/GvoY87tMEszhZIUV37z8PUBx6twIqMdr31W1J0IaPa+sV6FEDadeLaNTvancDcHK1zuKsL39jzAg7+LYjKJfEfrsQP+lj/EQcjtKqlhVS5kzsJVfx8ZEd0xhW5G7N6bCdKNalS8mKCMaBXJpijNQ82AiyqCIDCRrre2To0/i7pTjRiL0U9f9mV3S4NJaQaokR050w/ZLySFf6F7joJT mathijs@Qrama-Mathijs' # noqa + @base.bootstrapped @pytest.mark.asyncio @@ -221,6 +223,19 @@ async def test_watcher_reconnect(event_loop): assert model.connection.is_open +@base.bootstrapped +@pytest.mark.asyncio +async def test_config(event_loop): + async with base.CleanModel() as model: + await model.set_config({ + 'extra-info': 'booyah', + 'test-mode': ConfigValue(value=True), + }) + result = await model.get_config() + assert 'extra-info' in result + assert result['extra-info'].source == 'model' + assert result['extra-info'].value == 'booyah' + # @base.bootstrapped # @pytest.mark.asyncio # async def test_grant(event_loop) -- 2.25.1