From ebc1dff510c2469fd14f410f6483a77a62ef901d Mon Sep 17 00:00:00 2001 From: Vishesh Gupta Date: Thu, 3 Jun 2021 14:42:09 -0400 Subject: [PATCH] Supporting Vault Mount Path (#14) * Added mount_path option for hvac client * Added test for vault mount_path and clean up setup config * Added a new engine to test mount_path * Lint and cleanup * Updated the test to work * Updated and added mount_path capability to vault * Added mount path capability to vault gestalt * Updated the mount * Updated the test for mount * Updated the correct path for basic test * Updated the test mount to be non-conflicting * Updated the test and removed prints * Fixed yapf issues * Updated the version --- .github/workflows/pythonpackage.yml | 2 ++ .github/workflows/pythonpublish.yml | 1 + .vscode/settings.json | 3 +++ gestalt/__init__.py | 21 +++++++++++++++------ setup.py | 2 +- tests/test_gestalt.py | 28 +++++++++++++++++++++++----- 6 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 6a1411c..ecdf512 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -50,6 +50,8 @@ jobs: VAULT_CONTAINER_ID="$(docker ps -aqf "name=vault-test")" docker exec ${VAULT_CONTAINER_ID} vault login myroot docker exec ${VAULT_CONTAINER_ID} vault kv put secret/test test_client=test_client_password + docker exec ${VAULT_CONTAINER_ID} vault secrets enable -path=test-mount kv-v2 + docker exec ${VAULT_CONTAINER_ID} vault kv put test-mount/test test_mount=test_mount_password - name: Test with pytest env: CODECOV_TOKEN: ${{ secrets.CODE_COV_TOKEN }} diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml index 21f2f01..a06e704 100644 --- a/.github/workflows/pythonpublish.yml +++ b/.github/workflows/pythonpublish.yml @@ -17,6 +17,7 @@ jobs: run: | python -m pip install --upgrade pip pip install setuptools wheel twine + pip install -r requirements.txt - name: Build and publish env: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..615aafb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "/usr/bin/python3" +} \ No newline at end of file diff --git a/gestalt/__init__.py b/gestalt/__init__.py index a540156..569a7cc 100644 --- a/gestalt/__init__.py +++ b/gestalt/__init__.py @@ -53,7 +53,7 @@ def __init__(self) -> None: float]] = dict() self.__conf_defaults: Dict[Text, Union[List[Any], Text, int, bool, float]] = dict() - self.__vault_paths: List[str] = [] + self.__vault_paths: List[Tuple[Union[str, None], str]] = [] def __flatten( self, @@ -585,20 +585,29 @@ def add_vault_config_provider( self.__authenticate_vault_client(auth_config['role'], auth_config['jwt']) - def add_vault_secret_path(self, path: str) -> None: + def add_vault_secret_path(self, + path: str, + mount_path: Optional[str] = None) -> None: """Adds a vault secret with key and path to gestalt Args: - key (str): The key by which the secret is made available in configuration path (str): The path to the secret in vault cluster + mount_path ([type], optional): The mount_path for a non-default secret + mount. Defaults to Optional[str]. """ - self.__vault_paths.append(path) + mount_path = mount_path if mount_path != None else "secret" + + self.__vault_paths.append((mount_path, path)) def fetch_vault_secrets(self) -> None: + """Fetches client secrets from vault first checks the path provided + """ if len(self.__vault_paths) <= 0: return print("Fetching secrets from VAULT") - for vault_secret_path in self.__vault_paths: + for vault_path in self.__vault_paths: + mount_path = str(vault_path[0]) + secret_path = vault_path[1] secret_token = self.vault_client.secrets.kv.v2.read_secret_version( - path=vault_secret_path) + mount_point=str(mount_path), path=secret_path) self.__conf_data.update(secret_token['data']['data']) diff --git a/setup.py b/setup.py index 79f0e05..1f0ce4f 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ def readme(): setup(name='gestalt-cfg', - version='1.0.7', + version='1.0.8', description='A sensible configuration library for Python', long_description=readme(), long_description_content_type="text/markdown", diff --git a/tests/test_gestalt.py b/tests/test_gestalt.py index 5fd9199..987408e 100644 --- a/tests/test_gestalt.py +++ b/tests/test_gestalt.py @@ -449,7 +449,6 @@ def test_vault_fail_setup(): def test_vault_fail_kubernetes_auth(): g = gestalt.Gestalt() client_config = gestalt.HVAC_ClientConfig() - client_config = gestalt.HVAC_ClientConfig() client_config['url'] = "" client_config['token'] = "" client_config['cert'] = None @@ -471,8 +470,27 @@ def test_vault_get(): client_config['verify'] = True g.add_vault_config_provider(client_config, auth_config=None) print("Requires the user to set a token in the client") - CLIENT_ID = "test_client" - g.add_vault_secret_path("test") + client_id = "test_client" + client_password = "test_client_password" + g.add_vault_secret_path(path="test") + g.fetch_vault_secrets() + secret = g.get_string(client_id) + assert secret == client_password + + +def test_vault_mount_path(): + g = gestalt.Gestalt() + g.build_config() + client_config = gestalt.HVAC_ClientConfig() + client_config['url'] = "" + client_config['token'] = "myroot" + client_config['cert'] = None + client_config['verify'] = True + g.add_vault_config_provider(client_config, auth_config=None) + print("Requires the user to set a token in the client") + client_id_mount_path = "test_mount" + client_password_mount_path = "test_mount_password" + g.add_vault_secret_path("test", mount_path="test-mount") g.fetch_vault_secrets() - secret = g.get_string(CLIENT_ID) - assert secret == 'test_client_password' + secret = g.get_string(client_id_mount_path) + assert secret == client_password_mount_path