From f685632cd86fc2affe2ef7404c55ed41d50f8551 Mon Sep 17 00:00:00 2001 From: Karim Radhouani Date: Sat, 4 Jul 2026 20:45:36 -0700 Subject: [PATCH] Enhance integration testing setup by adding secret creation and target posting functionality. Updated Makefile to include new targets for creating secrets and sending targets to the API server. Modified authentication logic to support dynamic header names for signature verification. Updated HTTP target source configuration to enable push with authentication. --- Makefile | 2 +- internal/apiserver/auth.go | 9 +++++++-- test.mk | 16 ++++++++++++++++ test/integration/http/resources/configmap.yaml | 9 --------- .../resources/targetsources/http.yaml | 9 +++++++++ 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index b5acbac1..d46e82ce 100644 --- a/Makefile +++ b/Makefile @@ -308,7 +308,7 @@ delete-targetsources-dev-lab: ## Delete the target sources for the development l ##@ Testing Lab .PHONY: run-integration-tests -run-integration-tests: docker-build undeploy-test-cluster deploy-test-cluster install-test-cluster-dependencies load-test-image deploy deploy-test-http-server install-kubectl install-gnmic install-containerlab deploy-test-topology apply-test-resources +run-integration-tests: docker-build undeploy-test-cluster deploy-test-cluster install-test-cluster-dependencies load-test-image deploy deploy-test-http-server create-secrets-for-apiserver install-kubectl install-gnmic install-containerlab deploy-test-topology apply-test-resources send-target-to-apiserver kubectl wait --for=condition=Ready cluster --all --timeout=180s kubectl wait --for=condition=Ready pipeline --all --timeout=180s kubectl wait --for=jsonpath='{.status.targetsCount}'=3 targetsource --all --timeout=180s diff --git a/internal/apiserver/auth.go b/internal/apiserver/auth.go index 338e0fd0..2ef32608 100644 --- a/internal/apiserver/auth.go +++ b/internal/apiserver/auth.go @@ -39,10 +39,15 @@ func (a *APIServer) verifyAuthentication(ctx *gin.Context, registry core.Discove return true, nil } -// verifySignature verifies x-hook-signature from POST header with hmac from body and a kubernetes secret. +// verifySignature verifies the configured signature header from a POST request +// against an hmac computed from the body and a kubernetes secret. func (a *APIServer) verifySignature(ctx *gin.Context, registry core.DiscoveryRegistryValue, logger logr.Logger) (bool, error) { - signatureHeader := ctx.GetHeader("x-hook-signature") clc := registry.CommonLoaderConfig + headerName := clc.PushConfig.Auth.Signature.Header + if headerName == "" { + headerName = "x-hook-signature" + } + signatureHeader := ctx.GetHeader(headerName) secret, err := getSecret(clc, clc.PushConfig.Auth.Signature.SecretRef.Key, clc.PushConfig.Auth.Signature.SecretRef.Name) if err != nil { diff --git a/test.mk b/test.mk index fb30c305..84d55b7d 100644 --- a/test.mk +++ b/test.mk @@ -95,6 +95,22 @@ deploy-test-http-server: ## Deploy a test http pod with a static file inventory undeploy-test-http-server: ## Undeploy the http pod for testing kubectl delete -f test/integration/http/resources/ +.PHONY: create-secrets-for-apiserver +create-secrets-for-apiserver: ## Create the secret used to authenticate push-API requests (HMAC signature) + kubectl create secret generic gnmic-signature --from-literal=signature=1879 + +.PHONY: send-target-to-apiserver +send-target-to-apiserver: ## POST a target to the push API, authenticated with an HMAC-SHA512 signature over the body + @SIG_SECRET=$$(kubectl get secret gnmic-signature -o jsonpath='{.data.signature}' | base64 --decode); \ + BODY='[{"address":"clab-t1-leaf2","port":57400,"name":"leaf2","operation":"created","targetProfile":"default","labels":[{"vendor":"nokia_srlinux"},{"role":"leaf"}]}]'; \ + SIGNATURE=$$(printf '%s' "$$BODY" | openssl dgst -sha512 -hmac "$$SIG_SECRET" | awk '{print $$NF}'); \ + kubectl port-forward -n gnmic-system svc/gnmic-controller-manager-api 8082:8082 --address=0.0.0.0 >/dev/null 2>&1 & \ + sleep 3; \ + curl --retry 3 --retry-delay 1 --retry-connrefused -X POST "http://localhost:8082/api/v1/default/target-source/http-ts/applyTargets" \ + -H "Content-Type: application/json" \ + -H "x-hook-signature: $$SIGNATURE" \ + -d "$$BODY" + .PHONY: deploy-test-netbox-instance deploy-test-netbox-instance: NETBOX_CLUSTER_NAME=$(TEST_CLUSTER_NAME) ## Deploy the test netbox instance for testing deploy-test-netbox-instance: NETBOX_PASSWORD=Netbox123 diff --git a/test/integration/http/resources/configmap.yaml b/test/integration/http/resources/configmap.yaml index 5bd06f43..e0c9a9f8 100644 --- a/test/integration/http/resources/configmap.yaml +++ b/test/integration/http/resources/configmap.yaml @@ -22,14 +22,5 @@ data: "vendor": "nokia_srlinux", "role": "leaf" } - }, - { - "address": "clab-t1-leaf2", - "port": 57400, - "name": "leaf2", - "labels": { - "vendor": "nokia_srlinux", - "role": "leaf" - } } ] diff --git a/test/integration/resources/targetsources/http.yaml b/test/integration/resources/targetsources/http.yaml index 422cfdcd..77d9c862 100644 --- a/test/integration/resources/targetsources/http.yaml +++ b/test/integration/resources/targetsources/http.yaml @@ -6,6 +6,15 @@ spec: provider: http: url: http://http-svc.default.svc/targets.json + push: + enabled: true + auth: + signature: + secretRef: + name: gnmic-signature + key: signature + header: x-hook-signature + algorithm: sha512 targetLabels: integrationtest: http targetProfile: default \ No newline at end of file