From a5b3ca008f209211ceb10c662e172266235dcb86 Mon Sep 17 00:00:00 2001 From: Viktor Voytovych Date: Mon, 19 Oct 2026 23:36:59 +0300 Subject: [PATCH 1/2] fix: Deploy NSO with its config in one build The bootstrap deployed NSO's bundle, then applied its own network-services-operator-config by server-side apply, and restarted NSO. That works only while NSO's bundle names its ConfigMap with no hash. With a hash, NSO mounts its own ConfigMap and runs on its default config, with no error. The nso overlay now builds NSO's config/default and replaces its config with `behavior: replace`. The manager mounts this config under the name the bundle gives it, hashed or not. The re-apply and the restart go. --- Makefile | 9 +++------ config/overlays/nso/kustomization.yaml | 13 ++++++------- config/overlays/nso/namespace.yaml | 5 ----- 3 files changed, 9 insertions(+), 18 deletions(-) delete mode 100644 config/overlays/nso/namespace.yaml diff --git a/Makefile b/Makefile index 2c446847..ad624128 100644 --- a/Makefile +++ b/Makefile @@ -215,6 +215,7 @@ KIND_IMAGE ?= $(IMG) # Network Services Operator integration NSO_REPO ?= https://github.com/datum-cloud/network-services-operator.git +# config/overlays/nso builds NSO from this default path NSO_DIR ?= dev/network-services-operator NSO_IMG ?= ghcr.io/datum-cloud/network-services-operator:latest NSO_NAMESPACE ?= network-services-operator-system @@ -322,10 +323,6 @@ bootstrap-upstream: ## Create kind upstream and deploy replicator pointing to do echo "[bootstrap-upstream] Installing Kubernetes Gateway API CRDs ($(GATEWAY_API_VERSION))"; \ $(MAKE) install-gateway-api-crds CONTEXT=kind-$(UPSTREAM_CLUSTER_NAME) ; \ $(MAKE) nso-deploy-upstream KUBECONFIG=$(abspath dev/kind.upstream.kubeconfig) ; \ - echo "[bootstrap-upstream] Re-applying NSO overlay (config + RBAC) with server-side apply to override defaults"; \ - CONTEXT=kind-$(UPSTREAM_CLUSTER_NAME) KUSTOMIZE_DIR=config/overlays/nso $(MAKE) kustomize-apply-ssa ; \ - echo "[bootstrap-upstream] Restarting NSO to pick up new ConfigMap"; \ - kubectl --context kind-$(UPSTREAM_CLUSTER_NAME) -n network-services-operator-system rollout restart deploy/network-services-operator-controller-manager || true ; \ else \ echo "[bootstrap-upstream] Skipping NSO deployment (NSO_DEPLOY=false). Only CRDs installed."; \ fi @@ -491,10 +488,10 @@ nso-load-upstream: ## Load NSO image into upstream kind cluster $(KIND) load docker-image $(NSO_IMG) --name $(UPSTREAM_CLUSTER_NAME) .PHONY: nso-deploy-upstream -nso-deploy-upstream: nso-build nso-load-upstream ## Deploy NSO into upstream cluster using KUBECONFIG +nso-deploy-upstream: nso-build nso-load-upstream kustomize ## Deploy NSO with config/overlays/nso into upstream cluster using KUBECONFIG @test -n "$(KUBECONFIG)" || { echo "KUBECONFIG is required (e.g., dev/kind.upstream.kubeconfig)"; exit 1; } KUBECONFIG=$(abspath $(KUBECONFIG)) $(MAKE) -C $(NSO_DIR) set-image-controller IMG=$(NSO_IMG) - KUBECONFIG=$(abspath $(KUBECONFIG)) $(MAKE) -C $(NSO_DIR) deploy IMG=$(NSO_IMG) + $(KUSTOMIZE) build --load-restrictor LoadRestrictionsNone config/overlays/nso | KUBECONFIG=$(abspath $(KUBECONFIG)) $(KUBECTL) apply --server-side=true --force-conflicts -f - .PHONY: install-networking-crds install-networking-crds: controller-gen ## Generate and install networking services CRDs (e.g., Domain) into CONTEXT diff --git a/config/overlays/nso/kustomization.yaml b/config/overlays/nso/kustomization.yaml index 7727e2f1..41c92a55 100644 --- a/config/overlays/nso/kustomization.yaml +++ b/config/overlays/nso/kustomization.yaml @@ -4,20 +4,19 @@ kind: Kustomization namespace: network-services-operator-system resources: - - namespace.yaml + # NSO's own deployment, from the clone that `make nso-clone` makes (NSO_DIR) + - ../../../dev/network-services-operator/config/default - leader-election-rbac.yaml - domain-rbac.yaml - configmap-rbac.yaml - secret-rbac.yaml -generatorOptions: - disableNameSuffixHash: true - +# Replace NSO's config in the same build, so that the manager mounts this one under the name +# NSO's bundle gives it, hashed or not, and restarts when it changes. configMapGenerator: - - name: network-services-operator-config + - name: config + behavior: replace files: - config.yaml # Use the upstream kubeconfig for downstreamResourceManagement.kubeconfigPath - kubeconfig=../../../dev/kind.upstream.kubeconfig - - diff --git a/config/overlays/nso/namespace.yaml b/config/overlays/nso/namespace.yaml deleted file mode 100644 index 7a52ea2e..00000000 --- a/config/overlays/nso/namespace.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: network-services-operator-system - From b10ae65c11111aded7d54384eeef1609a24f8afc Mon Sep 17 00:00:00 2001 From: Viktor Voytovych Date: Mon, 19 Oct 2026 23:59:43 +0300 Subject: [PATCH 2/2] fix: Stop the bootstrap when an NSO step fails The bootstrap ran its NSO steps joined with `;`, so only the last step's status counted. NSO's deploy always failed on its ServiceMonitor, because the kind upstream has no ServiceMonitor CRD, and nothing showed it. The NSO steps now run under `set -e`, as go-install-tool does, so a failed step stops the bootstrap. The bootstrap installs the Prometheus Operator CRDs first, at the version infra runs, and NSO deploys whole. --- Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Makefile b/Makefile index ad624128..a2326726 100644 --- a/Makefile +++ b/Makefile @@ -320,8 +320,10 @@ bootstrap-upstream: ## Create kind upstream and deploy replicator pointing to do CLUSTER=$(UPSTREAM_CLUSTER_NAME) OUT=dev/kind.upstream.kubeconfig $(MAKE) export-kind-kubeconfig-raw # Optionally build and deploy Network Services Operator into upstream @if [ "$(NSO_DEPLOY)" = "true" ]; then \ + set -e; \ echo "[bootstrap-upstream] Installing Kubernetes Gateway API CRDs ($(GATEWAY_API_VERSION))"; \ $(MAKE) install-gateway-api-crds CONTEXT=kind-$(UPSTREAM_CLUSTER_NAME) ; \ + $(MAKE) install-prometheus-operator-crds CONTEXT=kind-$(UPSTREAM_CLUSTER_NAME) ; \ $(MAKE) nso-deploy-upstream KUBECONFIG=$(abspath dev/kind.upstream.kubeconfig) ; \ else \ echo "[bootstrap-upstream] Skipping NSO deployment (NSO_DEPLOY=false). Only CRDs installed."; \ @@ -402,6 +404,8 @@ KUSTOMIZE_VERSION ?= v5.7.1 CONTROLLER_TOOLS_VERSION ?= v0.19.0 DEFAULTER_GEN_VERSION ?= v0.32.3 GATEWAY_API_VERSION ?= v1.1.0 +# The Prometheus Operator CRDs infra installs (NSO's config/default ships a ServiceMonitor) +PROMETHEUS_OPERATOR_VERSION ?= v0.81.0 #ENVTEST_VERSION is the version of controller-runtime release branch to fetch the envtest setup script (i.e. release-0.20) ENVTEST_VERSION ?= $(shell go list -m -f "{{ .Version }}" sigs.k8s.io/controller-runtime | awk -F'[v.]' '{printf "release-%d.%d", $$2, $$3}') @@ -512,6 +516,11 @@ install-gateway-api-crds: ## Install Kubernetes Gateway API CRDs into CONTEXT @test -n "$(CONTEXT)" || { echo "CONTEXT is required (e.g., kind-$(UPSTREAM_CLUSTER_NAME))"; exit 1; } $(KUBECTL) --context $(CONTEXT) apply -k "github.com/kubernetes-sigs/gateway-api/config/crd?ref=$(GATEWAY_API_VERSION)" +.PHONY: install-prometheus-operator-crds +install-prometheus-operator-crds: ## Install the Prometheus Operator CRDs into CONTEXT + @test -n "$(CONTEXT)" || { echo "CONTEXT is required (e.g., kind-$(UPSTREAM_CLUSTER_NAME))"; exit 1; } + $(KUBECTL) --context $(CONTEXT) apply --server-side -f "https://github.com/prometheus-operator/prometheus-operator/releases/download/$(PROMETHEUS_OPERATOR_VERSION)/stripped-down-crds.yaml" + # go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist # $1 - target path with name of binary # $2 - package url which can be installed