From d89189030156be62bec2f4b06d82fc3d37efe9d0 Mon Sep 17 00:00:00 2001 From: Ronen Hilewicz Date: Fri, 22 Nov 2024 08:50:54 -0500 Subject: [PATCH] ktest handles config-maps + CI tests --- .github/workflows/ci.yaml | 32 ++++++++++++++++++++-- .gitignore | 1 + charts/directory/ci/minimal-values.yaml | 5 ++-- charts/directory/templates/_helpers.tpl | 10 +++++++ charts/directory/templates/admin_keys.yaml | 12 +++++--- charts/directory/templates/config.yaml | 2 +- charts/directory/templates/deployment.yaml | 2 +- charts/directory/values.yaml | 14 +++++++--- test/directory/directory.values.yaml | 6 ++-- test/directory/tests.yaml | 11 ++++++-- tools/ktest/ktest.py | 11 ++++++-- tools/ktest/model.py | 13 +++++++++ tools/ktest/namespace.py | 9 +++++- 13 files changed, 105 insertions(+), 23 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6862d03..4c7c0c5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,10 +7,11 @@ on: env: HELM_VERSION: v3.14.4 - PYTHON_VERSION: 3.x + PYTHON_VERSION: 3.13 + UV_VERSION: 0.5.3 jobs: - lint: + test: runs-on: ubuntu-latest steps: - @@ -21,7 +22,6 @@ jobs: url: https://vault.eng.aserto.com/ token: ${{ secrets.VAULT_TOKEN }} secrets: | - kv/data/github "USERNAME" | DOCKER_USERNAME; kv/data/github "READ_WRITE_TOKEN" | READ_WRITE_TOKEN; - uses: actions/checkout@v4 @@ -47,3 +47,29 @@ jobs: name: Lint run: | ct lint --config ct.yaml --helm-repo-extra-args "aserto-helm=-u gh -p ${READ_WRITE_TOKEN}" + - + name: Install uv package manager + uses: astral-sh/setup-uv@v3 + with: + version: ${{ env.UV_VERSION }} + - + uses: AbsaOSS/k3d-action@v2 + name: Create k8s cluster + with: + cluster-name: "test" + args: --agents 1 + - + name: Generate admin ssh key + id: sshkey + run: | + ssh-keygen -t ed25519 -N "" -f ~/.ssh/admin_ed25519 + echo "public_key=~/.ssh/admin_ed25519.pub" >> $GITHUB_OUTPUT + echo "private_key=~/.ssh/admin_ed25519" >> $GITHUB_OUTPUT + - + name: Test Directory + env: + SSH_PUBLIC_KEY: ${{ steps.sshkey.public_key }} + SSH_PRIVATE_KEY: ${{ steps.sshkey.private_key }} + run: | + cd tools/ktest + uv run ktest.py ../../test/directory/tests.yaml diff --git a/.gitignore b/.gitignore index fe60ce6..0c2225c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ # python **/__pycache__/ +.venv-path diff --git a/charts/directory/ci/minimal-values.yaml b/charts/directory/ci/minimal-values.yaml index 02e2813..8d98684 100644 --- a/charts/directory/ci/minimal-values.yaml +++ b/charts/directory/ci/minimal-values.yaml @@ -9,5 +9,6 @@ rootDirectory: tenantDirectory: database: host: tenant-db-host -sshAdminKeys: | - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDf6 +sshAdminKeys: + keys: | + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDf6 diff --git a/charts/directory/templates/_helpers.tpl b/charts/directory/templates/_helpers.tpl index e8899b0..f3bc67d 100644 --- a/charts/directory/templates/_helpers.tpl +++ b/charts/directory/templates/_helpers.tpl @@ -112,3 +112,13 @@ valueFrom: key: api-key {{- end }} {{- end }} + +{{- define "directory.adminKeysConfigMapName" -}} +{{ ((.Values.sshAdminKeys).configMap).name | default + (printf "%s-admin-keys" (include "directory.fullname" .)) }} +{{- end }} + +{{- define "directory.adminKeysConfigMapKey" -}} +{{ ((.Values.sshAdminKeys).configMap).key | default "authorized_keys" }} +{{- end }} + diff --git a/charts/directory/templates/admin_keys.yaml b/charts/directory/templates/admin_keys.yaml index 80a2708..103deef 100644 --- a/charts/directory/templates/admin_keys.yaml +++ b/charts/directory/templates/admin_keys.yaml @@ -1,9 +1,13 @@ +{{- if empty .Values.sshAdminKeys -}} + {{ fail "sshAdminKeys is required" }} +{{- end -}} +{{- if (.Values.sshAdminKeys).keys -}} --- apiVersion: v1 kind: ConfigMap metadata: - name: {{ include "directory.fullname" . }}-admin-keys + name: {{ include "directory.adminKeysConfigMapName" . }} data: - authorized_keys: | - {{- .Values.sshAdminKeys | required "sshAdminKeys is required" | nindent 4 }} - + {{ include "directory.adminKeysConfigMapKey" . }}: | + {{- $.Values.sshAdminKeys.keys | required "sshAdminKeys.keys is required" | nindent 4 }} +{{- end -}} diff --git a/charts/directory/templates/config.yaml b/charts/directory/templates/config.yaml index ca6ae5c..cc3c3b0 100644 --- a/charts/directory/templates/config.yaml +++ b/charts/directory/templates/config.yaml @@ -22,7 +22,7 @@ stringData: metrics: {{- include "aserto-lib.metricsService" . | nindent 8 }} admin: - authorized_keys_path: /admin-keys/authorized_keys + authorized_keys_path: /admin-keys/{{ include "directory.adminKeysConfigMapKey" . }} {{ if .Values.rootDirectory.runService }} {{- with .Values.rootDirectory.database -}} diff --git a/charts/directory/templates/deployment.yaml b/charts/directory/templates/deployment.yaml index 1c55d5f..fa401ac 100644 --- a/charts/directory/templates/deployment.yaml +++ b/charts/directory/templates/deployment.yaml @@ -35,7 +35,7 @@ spec: path: config.yaml - name: admin-keys configMap: - name: {{ include "directory.fullname" . }}-admin-keys + name: {{ include "directory.adminKeysConfigMapName" . }} {{- with (include "aserto-lib.grpcConfig" . | fromYaml).certSecret }} - name: grpc-certs secret: diff --git a/charts/directory/values.yaml b/charts/directory/values.yaml index 3836d0d..0b75b84 100644 --- a/charts/directory/values.yaml +++ b/charts/directory/values.yaml @@ -21,10 +21,16 @@ oidc: # audience: "" # Required: Provide one or more SSH public keys to be granted admin access. -# sshAdminKeys: | -# # Add your authorized SSH public keys here -# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDf6 -# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDa7 +# sshAdminKeys: +# # Keys can be provided inline as a multi-line string under keys: +# keys: | +# # Add your authorized SSH public keys here +# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDf6 +# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDa7 +# # Keys can also be provided in a ConfigMap +# configMap: +# name: directory-admin-keys +# key: authorized_keys rootDirectory: runService: true diff --git a/test/directory/directory.values.yaml b/test/directory/directory.values.yaml index 1a971e8..cae0b2e 100644 --- a/test/directory/directory.values.yaml +++ b/test/directory/directory.values.yaml @@ -28,8 +28,10 @@ tenantDirectory: cache: sizeMB: 100 -sshAdminKeys: | - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMEAOAWPotrmDRxyLRSswrectb8NJ4pH/i09N91Hd4Lj ronen@hilewi.cz +sshAdminKeys: + configMap: + name: directory-admin-keys + key: authorized_keys tenants: - name: test diff --git a/test/directory/tests.yaml b/test/directory/tests.yaml index deb083d..239dac9 100644 --- a/test/directory/tests.yaml +++ b/test/directory/tests.yaml @@ -11,6 +11,11 @@ tests: values: reader: apikey_tenant_reader writer: apikey_tenant_writer + config_maps: + - name: directory-admin-keys + keys: + - name: authorized_keys + file: $SSH_PUBLIC_KEY deployments: - chart: directory values: directory.values.yaml @@ -19,15 +24,15 @@ tests: 8282: 8282 run: - > - ssh -p 2222 -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR + ssh -i ${SSH_PRIVATE_KEY:-$(ls -1 ~/.ssh/id_* | head -1)} -p 2222 -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR localhost provision root-keys - > - ssh -p 2222 -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR + ssh -i ${SSH_PRIVATE_KEY:-$(ls -1 ~/.ssh/id_* | head -1)} -p 2222 -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR localhost provision tenant test --id 3dbaa470-9c7e-11ef-bf36-00fcb2a75cb1 - > ${TOPAZ:-topaz} ds get manifest -H localhost:8282 --tenant-id 3dbaa470-9c7e-11ef-bf36-00fcb2a75cb1 -k apikey_tenant_reader --stdout --plaintext cleanup: - > - ssh -p 2222 -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR + ssh -i ${SSH_PRIVATE_KEY:-$(ls -1 ~/.ssh/id_* | head -1)} -p 2222 -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR localhost provision tenant test --id 3dbaa470-9c7e-11ef-bf36-00fcb2a75cb1 --delete diff --git a/tools/ktest/ktest.py b/tools/ktest/ktest.py index 9b15fd5..a82d82e 100755 --- a/tools/ktest/ktest.py +++ b/tools/ktest/ktest.py @@ -39,6 +39,12 @@ def run(self): ) ns.create_secret(secret) + for config_map in self.test.config_maps: + click.echo( + f"πŸ“‹ {click.style("Creating sconfig map", fg=COLOR_HARNESS)} {config_map.name}" + ) + ns.create_config_map(config_map) + for deployment in self.test.deployments: click.echo( f"πŸ—ΊοΈ {click.style("Installing chart:", fg=COLOR_HARNESS)} {deployment.chart}" @@ -54,6 +60,8 @@ def run(self): for deployment in self.test.deployments: ns.wait(ns.svc_pod(deployment.chart)) + click.echo("\nβœ… Deployment complete.\n") + with ExitStack() as stack: for deployment in self.test.deployments: click.echo( @@ -62,7 +70,6 @@ def run(self): ) stack.enter_context(ns.forward(deployment.chart, deployment.ports)) - click.echo("\nβœ… Deployment complete.\n") try: self.execute_steps() @@ -71,7 +78,7 @@ def run(self): self.execute_cleanup() def execute_steps(self): - click.echo(f"πŸƒ {click.style("Running tests", fg=COLOR_HARNESS)}\n") + click.echo(f"\nπŸƒ {click.style("Running tests", fg=COLOR_HARNESS)}\n") for step in self.test.run: click.echo(f"πŸ§ͺ {click.style(step, fg=COLOR_STEP)}") self.subprocess(step) diff --git a/tools/ktest/model.py b/tools/ktest/model.py index 096a13b..d0155f3 100644 --- a/tools/ktest/model.py +++ b/tools/ktest/model.py @@ -2,6 +2,18 @@ from pydantic import BaseModel +@dataclass +class ConfigMapKey: + name: str + file: str + + +@dataclass +class ConfigMap: + name: str + keys: list[ConfigMapKey] + + @dataclass class Secret: name: str @@ -20,6 +32,7 @@ class Test: name: str pull_secret: str secrets: list[Secret] + config_maps: list[ConfigMap] deployments: list[Deployment] run: list[str] cleanup: list[str] diff --git a/tools/ktest/namespace.py b/tools/ktest/namespace.py index dc7ad09..4e8dabe 100644 --- a/tools/ktest/namespace.py +++ b/tools/ktest/namespace.py @@ -11,7 +11,7 @@ from kubernetes import client from kubernetes.client.rest import ApiException -from model import Secret +from model import ConfigMap, Secret logger = logging.getLogger("namespace") @@ -49,6 +49,13 @@ def create_secret(self, secret: Secret): *keys, ) + def create_config_map(self, config_map: ConfigMap): + keys = ( + f"--from-file={key.name}={path.expandvars(key.file)}" + for key in config_map.keys + ) + self.kubectl("create", "configmap", config_map.name, *keys) + def kubectl(self, *args): kubectl(*args, "-n", self.namespace)