Parse and validate kustomize output
from pytest_kustomize import resolve_configmaps, extract_externalsecret_data
import pytest
@pytest.mark.parametrize("environment, value", [
("staging", "shared-db.staging.example.com"),
("production", "myservice-db.production.example.com"),
])
def test_database_matches_environment(kustomize_resources, environment, value):
config = resolve_configmaps(kustomize_resources[environment])
for deployment in ["webui", "api"]:
assert config[deployment]["db_host"] == value
def test_production_has_no_staging_vault_paths(kustomize_resources):
for secret in extract_externalsecret_data(kustomize_resources["production"]).values():
assert "staging" not in secret["key"]
@pytest.mark.parametrize("environment", ["staging", "production"])
def test_jq(kustomize_jq, environment):
for apiVersion in kustomize_jq(
""".[] | select(."kind"=="ConfigMap").apiVersion""", environment
):
assert apiVersion == "v1"You can access the kustomize output as follows:
- The
kustomize_manifestsfixture returns adict[str, str], environment name:kustomize buildoutput - The
kustomize_resourcesfixture returns adict[str, List[dict]], environment name: yaml-parsed output - The
kustomize_jqfixture returns a query helper which applies ato the given environment and returns an instance of
. Only available by explicitly installing
jq(orpytest_kustomize[jq])
Optionally, define the directory where kustomize manifests are looked up by providing this fixture
@pytest.fixture(scope="session")
def kustomize_root_directory():
return "/path/to/kustomizations"Default: ./k8s
Optionally, define for which subdirectories manifests should be generated by providing this fixture
@pytest.fixture(scope="session")
def kustomize_environment_names():
return ["overlays/staging", "overlays/production"]Default: All direct subdirectories that contain a kustomization.yaml
The package provides these helper functions:
resolve_configmaps()resolvesenvFromreferences toConfigMaps inDeployments. It takes a list of yaml dicts (usuallykustomize_resources[environment]) and returns adict[str, dict[str, str]], deployment+container name: {key: value}. The dict keys work as follows:- Containers are named
{deployment}-{container} - Init Containers are named
{deployment}-init-{container} - For convenience, the first container is also available just under the name
{deployment}, and the first init container as{deployment}-init
- Containers are named
extract_externalsecret_data()extracts thedatasections of allExternalSecretresources. It takes a list of yaml dicts and returns{"key_in_secret": {"key": "example/vault/path", "property": "token"}}
These take an optional name_transform callable which defaults to lambda x: x.rsplit('-', 1)[0], to normalize e.g. kustomize-generated ConfigMap names like project-44fb7dkk64.