diff --git a/charts/gha-runner-scale-set-dev/templates/_helpers.tpl b/charts/gha-runner-scale-set-dev/templates/_helpers.tpl index 4bda9298..25366f52 100644 --- a/charts/gha-runner-scale-set-dev/templates/_helpers.tpl +++ b/charts/gha-runner-scale-set-dev/templates/_helpers.tpl @@ -63,6 +63,41 @@ Takes a map of user labels and removes the ones with "actions.github.com/" prefi {{- $processed | toYaml -}} {{- end }} +{{/* +Takes a map of user annotations and removes reserved ones. + +Reserved annotations are managed by ARC/controllers and should not be set by users: +- actions.github.com/cleanup-* +- actions.github.com/values-hash +*/}} +{{- define "gha-process-annotations" -}} +{{- $userAnnotations := . -}} +{{- $processed := dict -}} +{{- range $key, $value := $userAnnotations -}} + {{- if not (or (hasPrefix "actions.github.com/cleanup-" $key) (eq $key "actions.github.com/values-hash")) -}} + {{- $_ := set $processed $key $value -}} + {{- end -}} +{{- end -}} +{{- $processed | toYaml -}} +{{- end }} + +{{/* +Create the annotations for the autoscaling runner set. + +Order of precedence: +1) resource.all.metadata.annotations +2) resource.autoscalingRunnerSet.metadata.annotations +Reserved annotations are excluded from both levels. +*/}} +{{- define "autoscaling-runner-set.annotations" -}} +{{- $global := include "gha-process-annotations" (.Values.resource.all.metadata.annotations | default (dict)) | fromYaml -}} +{{- $resource := include "gha-process-annotations" (.Values.resource.autoscalingRunnerSet.metadata.annotations | default (dict)) | fromYaml -}} +{{- $annotations := mergeOverwrite $global $resource -}} +{{- range $k, $v := $annotations }} +{{ $k }}: {{ $v | quote }} +{{- end }} +{{- end }} + {{/* Create chart name and version as used by the chart label. */}} diff --git a/charts/gha-runner-scale-set-dev/templates/autoscalingrunnserset.yaml b/charts/gha-runner-scale-set-dev/templates/autoscalingrunnserset.yaml index 6dd601d2..06b9249f 100644 --- a/charts/gha-runner-scale-set-dev/templates/autoscalingrunnserset.yaml +++ b/charts/gha-runner-scale-set-dev/templates/autoscalingrunnserset.yaml @@ -5,6 +5,9 @@ metadata: namespace: {{ include "autoscaling-runner-set.namespace" . | quote }} labels: {{- include "autoscaling-runner-set.labels" . | nindent 4 }} + annotations: + {{- include "autoscaling-runner-set.annotations" . | nindent 4 }} + actions.github.com/values-hash: {{ toJson .Values | sha256sum | trunc 63 }} spec: githubConfigUrl: {{ required ".Values.auth.url is required" (trimSuffix "/" .Values.auth.url) | quote }} @@ -36,7 +39,7 @@ spec: certificatePath: {{ .Values.secretResolution.azureKeyVault.certificatePath }} secretKey: {{ .Values.secretResolution.azureKeyVault.secretKey }} {{- else }} - {{- fail "Unsupported keyVault type: " .Values.secretResolution.type }} + {{- fail (printf "Unsupported keyVault type: %s" .Values.secretResolution.type) }} {{- end }} {{- end }} @@ -93,5 +96,4 @@ spec: template: spec: - containers: - # {{- include "container-spec.runner" . | nindent 8 }} + containers: \ No newline at end of file diff --git a/charts/gha-runner-scale-set-dev/tests/autoscaling_runner_set_annotations_test.yaml b/charts/gha-runner-scale-set-dev/tests/autoscaling_runner_set_annotations_test.yaml new file mode 100644 index 00000000..9021e6b0 --- /dev/null +++ b/charts/gha-runner-scale-set-dev/tests/autoscaling_runner_set_annotations_test.yaml @@ -0,0 +1,79 @@ +suite: "Test AutoscalingRunnerSet Annotations" +templates: + - autoscalingrunnserset.yaml +tests: + - it: should render values-hash annotation + set: + scaleset.name: "test" + auth.url: "https://github.com/org" + auth.githubToken: "gh_token12345" + controllerServiceAccount.name: "arc" + controllerServiceAccount.namespace: "arc-system" + release: + name: "test-name" + namespace: "test-namespace" + asserts: + - exists: + path: metadata.annotations["actions.github.com/values-hash"] + + - it: should merge global and resource annotations (resource overrides global) + set: + scaleset.name: "test" + auth.url: "https://github.com/org" + auth.githubToken: "gh_token12345" + controllerServiceAccount.name: "arc" + controllerServiceAccount.namespace: "arc-system" + resource: + all: + metadata: + annotations: + a: "global" + shared: "global" + autoscalingRunnerSet: + metadata: + annotations: + b: "resource" + shared: "resource" + release: + name: "test-name" + namespace: "test-namespace" + asserts: + - equal: + path: metadata.annotations.a + value: "global" + - equal: + path: metadata.annotations.b + value: "resource" + - equal: + path: metadata.annotations.shared + value: "resource" + + - it: should not allow overriding reserved values-hash annotation + set: + scaleset.name: "test" + auth.url: "https://github.com/org" + auth.githubToken: "gh_token12345" + controllerServiceAccount.name: "arc" + controllerServiceAccount.namespace: "arc-system" + resource: + all: + metadata: + annotations: + actions.github.com/values-hash: "user-value" + ok: "ok" + autoscalingRunnerSet: + metadata: + annotations: + actions.github.com/cleanup-something: "should-not-render" + release: + name: "test-name" + namespace: "test-namespace" + asserts: + - equal: + path: metadata.annotations.ok + value: "ok" + - notEqual: + path: metadata.annotations["actions.github.com/values-hash"] + value: "user-value" + - notExists: + path: metadata.annotations["actions.github.com/cleanup-something"] diff --git a/charts/gha-runner-scale-set-dev/tests/autoscaling_runner_set_listener_metrics_test.yaml b/charts/gha-runner-scale-set-dev/tests/autoscaling_runner_set_listener_metrics_test.yaml new file mode 100644 index 00000000..3a2b4ff8 --- /dev/null +++ b/charts/gha-runner-scale-set-dev/tests/autoscaling_runner_set_listener_metrics_test.yaml @@ -0,0 +1,55 @@ +suite: "Test AutoscalingRunnerSet Listener Metrics" +templates: + - autoscalingrunnserset.yaml +tests: + - it: should not render listenerMetrics when not configured + set: + scaleset.name: "test" + auth.url: "https://github.com/org" + auth.githubToken: "gh_token12345" + controllerServiceAccount.name: "arc" + controllerServiceAccount.namespace: "arc-system" + release: + name: "test-name" + namespace: "test-namespace" + asserts: + - notExists: + path: spec.listenerMetrics + + - it: should render listenerMetrics when configured + set: + scaleset.name: "test" + auth.url: "https://github.com/org" + auth.githubToken: "gh_token12345" + controllerServiceAccount.name: "arc" + controllerServiceAccount.namespace: "arc-system" + listenerMetrics: + counters: + gha_started_jobs_total: + labels: + - repository + - organization + histograms: + gha_job_startup_duration_seconds: + buckets: + - 0.1 + - 1 + - 2.5 + release: + name: "test-name" + namespace: "test-namespace" + asserts: + - exists: + path: spec.listenerMetrics + - equal: + path: spec.listenerMetrics.counters.gha_started_jobs_total.labels[0] + value: repository + - equal: + path: spec.listenerMetrics.counters.gha_started_jobs_total.labels[1] + value: organization + - contains: + path: spec.listenerMetrics.histograms.gha_job_startup_duration_seconds.buckets + content: 0.1 + - contains: + path: spec.listenerMetrics.histograms.gha_job_startup_duration_seconds.buckets + content: 2.5 diff --git a/charts/gha-runner-scale-set-dev/tests/autoscaling_runner_set_vault_config_test.yaml b/charts/gha-runner-scale-set-dev/tests/autoscaling_runner_set_vault_config_test.yaml new file mode 100644 index 00000000..a5f93c40 --- /dev/null +++ b/charts/gha-runner-scale-set-dev/tests/autoscaling_runner_set_vault_config_test.yaml @@ -0,0 +1,110 @@ +suite: "Test AutoscalingRunnerSet Vault Config" +templates: + - autoscalingrunnserset.yaml +tests: + - it: should not render vaultConfig when secretResolution.type is kubernetes + set: + scaleset.name: "test" + auth.url: "https://github.com/org" + auth.githubToken: "gh_token12345" + controllerServiceAccount.name: "arc" + controllerServiceAccount.namespace: "arc-system" + secretResolution: + type: kubernetes + release: + name: "test-name" + namespace: "test-namespace" + asserts: + - notExists: + path: spec.vaultConfig + + - it: should render azureKeyVault vaultConfig when configured + set: + scaleset.name: "test" + auth.url: "https://github.com/org" + auth.githubToken: "gh_token12345" + controllerServiceAccount.name: "arc" + controllerServiceAccount.namespace: "arc-system" + secretResolution: + type: azureKeyVault + azureKeyVault: + url: "https://myvault.vault.azure.net" + tenantId: "tenant-123" + clientId: "client-456" + certificatePath: "/etc/certs/akv.pem" + secretKey: "secret-key-name" + release: + name: "test-name" + namespace: "test-namespace" + asserts: + - equal: + path: spec.vaultConfig.type + value: azureKeyVault + - equal: + path: spec.vaultConfig.azureKeyVault.url + value: "https://myvault.vault.azure.net" + - equal: + path: spec.vaultConfig.azureKeyVault.tenantId + value: "tenant-123" + - equal: + path: spec.vaultConfig.azureKeyVault.clientId + value: "client-456" + - equal: + path: spec.vaultConfig.azureKeyVault.certificatePath + value: "/etc/certs/akv.pem" + - equal: + path: spec.vaultConfig.azureKeyVault.secretKey + value: "secret-key-name" + + - it: should render vaultConfig proxy when configured + set: + scaleset.name: "test" + auth.url: "https://github.com/org" + auth.githubToken: "gh_token12345" + controllerServiceAccount.name: "arc" + controllerServiceAccount.namespace: "arc-system" + secretResolution: + type: azureKeyVault + proxy: + http: + url: "http://proxy.example.com:3128" + credentialSecretRef: "proxy-credentials" + noProxy: + - "localhost" + azureKeyVault: + url: "https://myvault.vault.azure.net" + tenantId: "tenant-123" + clientId: "client-456" + certificatePath: "/etc/certs/akv.pem" + secretKey: "secret-key-name" + release: + name: "test-name" + namespace: "test-namespace" + asserts: + - equal: + path: spec.vaultConfig.proxy.http.url + value: "http://proxy.example.com:3128" + - equal: + path: spec.vaultConfig.proxy.http.credentialSecretRef + value: "proxy-credentials" + - contains: + path: spec.vaultConfig.proxy.noProxy + content: "localhost" + - notExists: + path: spec.proxy + + - it: should fail for unsupported secretResolution.type + set: + scaleset.name: "test" + auth.url: "https://github.com/org" + auth.githubToken: "gh_token12345" + controllerServiceAccount.name: "arc" + controllerServiceAccount.namespace: "arc-system" + secretResolution: + type: "hashicorpVault" + release: + name: "test-name" + namespace: "test-namespace" + asserts: + - failedTemplate: + errorMessage: "Unsupported keyVault type: hashicorpVault"