Skip to content

Commit

Permalink
add the possibility to add extra settings to the env from outside of …
Browse files Browse the repository at this point in the history
…inmanta-core (Issue inmanta/inmanta-lsm#927, PR #4603)

Pull request opened by the merge tool on behalf of #4603
  • Loading branch information
FloLey authored and inmantaci committed Aug 4, 2022
1 parent 0f7dcae commit d083501
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 4 deletions.
5 changes: 5 additions & 0 deletions changelogs/unreleased/927-add-env-settings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
description: add the possibility to add extra settings to the env from outside of inmanta-core
issue-nr: 927
issue-repo: inmanta-lsm
change-type: minor
destination-branches: [master, iso5]
13 changes: 13 additions & 0 deletions src/inmanta/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2401,6 +2401,19 @@ async def get_next_version(self) -> int:
self.last_version = version
return version

@classmethod
async def register_setting(cls, setting: Setting) -> None:
"""
Adds a new setting to the environments from outside inmanta-core.
As example, inmanta-lsm can use this method to add settings that are only
relevant for inmanta-lsm but that are needed in the environments.
:param setting: the setting that should be added to the existing settings
"""
if setting.name in cls._settings:
raise KeyError()
cls._settings[setting.name] = setting

@classmethod
async def get_list(
cls: Type[TBaseDocument],
Expand Down
15 changes: 13 additions & 2 deletions src/inmanta/server/services/environmentservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from asyncpg import StringDataRightTruncationError

from inmanta import config, data
from inmanta.data import model
from inmanta.data import Setting, model
from inmanta.protocol import encode_token, handle, methods, methods_v2
from inmanta.protocol.common import ReturnValue, attach_warnings
from inmanta.protocol.exceptions import BadRequest, Forbidden, NotFound, ServerError
Expand Down Expand Up @@ -305,7 +305,8 @@ async def create_token(self, env: data.Environment, client_types: List[str], ide

@handle(methods.list_settings, env="tid")
async def list_settings(self, env: data.Environment) -> Apireturn:
return 200, {"settings": env.settings, "metadata": data.Environment._settings}
settings = {k: env.settings[k] for k in env.settings.keys() if k in data.Environment._settings.keys()}
return 200, {"settings": settings, "metadata": data.Environment._settings}

@handle(methods.set_setting, env="tid", key="id")
async def set_setting(self, env: data.Environment, key: str, value: model.EnvSettingType) -> Apireturn:
Expand Down Expand Up @@ -601,3 +602,13 @@ async def notify_listeners(
await listener.environment_action_updated(updated_env, original_env)
except Exception:
LOGGER.warning(f"Notifying listener of {action} failed with the following exception", exc_info=True)

async def register_setting(self, setting: Setting) -> None:
"""
Should only be called during pre-start
Adds a new setting to the environments from outside inmanta-core.
As example, inmanta-lsm can use this method to add settings that are only
relevant for inmanta-lsm but that are needed in the environment.
:param setting: the setting that should be added to the existing settings
"""
await data.Environment.register_setting(setting)
29 changes: 27 additions & 2 deletions tests/agent_server/test_server_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,16 @@
from inmanta.ast import CompilerException
from inmanta.config import Config
from inmanta.const import AgentAction, AgentStatus, ParameterSource, ResourceState
from inmanta.data import ENVIRONMENT_AGENT_TRIGGER_METHOD
from inmanta.server import SLICE_AGENT_MANAGER, SLICE_AUTOSTARTED_AGENT_MANAGER, SLICE_PARAM, SLICE_SESSION_MANAGER
from inmanta.data import ENVIRONMENT_AGENT_TRIGGER_METHOD, Setting, convert_boolean
from inmanta.server import (
SLICE_AGENT_MANAGER,
SLICE_AUTOSTARTED_AGENT_MANAGER,
SLICE_ENVIRONMENT,
SLICE_PARAM,
SLICE_SESSION_MANAGER,
)
from inmanta.server.bootloader import InmantaBootloader
from inmanta.server.services.environmentservice import EnvironmentService
from inmanta.util import get_compiler_version
from utils import (
UNKWN,
Expand Down Expand Up @@ -719,6 +726,24 @@ async def test_get_set_param(resource_container, environment, client, server):
assert result.code == 200


async def test_register_setting(environment, client, server):
"""
Test registering a new setting.
"""
new_setting: Setting = Setting(
name="a new boolean setting",
default=False,
typ="bool",
validator=convert_boolean,
doc="a new setting",
)
env_slice: EnvironmentService = server.get_slice(SLICE_ENVIRONMENT)
await env_slice.register_setting(new_setting)
result = await client.get_setting(tid=environment, id="a new boolean setting")
assert result.code == 200
assert result.result["value"] is False


async def test_unkown_parameters(resource_container, environment, client, server, clienthelper, agent, no_agent_backoff):
"""
Test retrieving facts from the agent
Expand Down
86 changes: 86 additions & 0 deletions tests/server/test_env_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@
Contact: code@inmanta.com
"""
from typing import Dict
from uuid import UUID

import pytest

from inmanta import data
from inmanta.data import Environment, Setting, convert_boolean
from inmanta.util import get_compiler_version


Expand Down Expand Up @@ -311,3 +315,85 @@ async def test_default_value_purge_on_delete_setting(server, client):
result = await client.get_setting(tid=env_id, id=data.PURGE_ON_DELETE)
assert result.code == 200
assert result.result["value"] is False


async def test_environment_add_new_setting_parameter(server, client, environment):
new_setting: Setting = Setting(
name="a new setting",
default=False,
typ="bool",
validator=convert_boolean,
doc="a new setting",
)

await data.Environment.register_setting(new_setting)

result = await client.get_setting(tid=environment, id="a new setting")
assert result.code == 200
assert result.result["value"] is False

result = await client.set_setting(tid=environment, id="a new setting", value=True)
assert result.code == 200

result = await client.get_setting(tid=environment, id="a new setting")
assert result.code == 200
assert result.result["value"] is True

result = await client.get_setting(tid=environment, id=data.AUTO_DEPLOY)
assert result.code == 200
assert result.result["value"] is False

existing_setting: Setting = Setting(
name=data.AUTO_DEPLOY,
default=False,
typ="bool",
validator=convert_boolean,
doc="an existing setting",
)
with pytest.raises(KeyError):
await data.Environment.register_setting(existing_setting)

result = await client.get_setting(tid=environment, id=data.AUTO_DEPLOY)
assert result.code == 200
assert result.result["value"] is False


async def test_get_setting_no_longer_exist(server, client, environment):
"""
Test what happens when a setting exists in the database for which the definition no longer exists
"""
env_id = UUID(environment)
env = await data.Environment.get_by_id(env_id)
project_id = env.project
setting_db_query = (
"UPDATE environment SET settings=jsonb_set(settings, $1::text[], "
"to_jsonb($2::boolean), TRUE) WHERE name=$3 AND project=$4"
)
values = [["new_setting"], True, "dev", project_id]
await Environment._execute_query(setting_db_query, *values)

result = await client.get_setting(tid=environment, id="a setting")
assert result.code == 404
assert result.result["message"] == "Request or referenced resource does not exist"

result = await client.list_settings(tid=environment)
assert result.code == 200
assert "new_setting" not in result.result["settings"].keys()

new_setting: Setting = Setting(
name="new_setting",
default=False,
typ="bool",
validator=convert_boolean,
doc="new_setting",
)

await data.Environment.register_setting(new_setting)

result = await client.get_setting(tid=environment, id="new_setting")
assert result.code == 200
assert result.result["value"] is True

result = await client.list_settings(tid=environment)
assert result.code == 200
assert "new_setting" in result.result["settings"].keys()

0 comments on commit d083501

Please sign in to comment.