From 198df1df2ef351bc5c9e8030b0d837c4bbb62960 Mon Sep 17 00:00:00 2001 From: Jennifer Ubah Date: Tue, 1 Sep 2026 18:24:37 -0400 Subject: [PATCH 1/5] Update deployment with agent Assisted-By: Cursor AI Signed-off-by: Jennifer Ubah --- .gitignore | 1 + Makefile | 75 ++++++------ README.md | 4 +- deploy/.env.example | 45 ++++--- deploy/RUN.md | 159 ++++++------------------- deploy/compose.yaml | 135 ++++----------------- deploy/docs/environment-agent-kind.md | 164 ++++++++++++++++++++++++++ 7 files changed, 295 insertions(+), 288 deletions(-) create mode 100644 deploy/docs/environment-agent-kind.md diff --git a/.gitignore b/.gitignore index b871ece..3dc21ea 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ go.work.sum # env file .env +deploy/.kube/ # Editor/IDE # .vscode/ diff --git a/Makefile b/Makefile index cf897a3..c944ee8 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,11 @@ COMPOSE_PROJECT_NAME ?= control-plane COMPOSE_NETWORK := $(COMPOSE_PROJECT_NAME)_default PROFILES ?= AUTH ?= +UTILITIES_DIR ?= ../utilities +KIND_SCRIPTS_DIR ?= $(UTILITIES_DIR)/scripts/kind +COMPOSE_SCRIPTS_DIR ?= $(UTILITIES_DIR)/scripts/compose +KUBEVIRT_SCRIPTS_DIR ?= $(UTILITIES_DIR)/scripts/kubevirt +COMPOSE_NETWORKS ?= deploy_default $(COMPOSE_NETWORK) COMPOSE ?= $(shell command -v podman-compose >/dev/null 2>&1 && echo podman-compose || \ (command -v docker-compose >/dev/null 2>&1 && echo docker-compose || \ @@ -61,39 +66,39 @@ run-dev: compose-up: $(COMPOSE_DEPLOY) $(if $(filter true,$(AUTH)),--profile auth,) up -d --build -# Platform stack with optional service providers (see deploy/RUN.md). +# Platform stack + environment-agent profile (see deploy/RUN.md). # Optional: AUTH=true to also start Keycloak. -compose-up-with-providers: - $(COMPOSE_DEPLOY) $(if $(filter true,$(AUTH)),--profile auth,) --profile $(or $(PROFILES),providers) up -d --build - -# Tear down the compose stack. Kind (or other externals) joined to the compose -# network block "compose down" from removing it — disconnect them first. -# Network cleanup uses podman- or docker-specific commands (not portable flags). -compose-down: - @for network in deploy_default $(COMPOSE_NETWORK); do \ - if [ "$(CONTAINER_ENGINE)" = podman ]; then \ - if podman network exists "$$network" 2>/dev/null; then \ - for c in $$(podman ps -a --filter network=$$network -q 2>/dev/null); do \ - podman network disconnect -f "$$network" "$$c" 2>/dev/null || true; \ - done; \ - fi; \ - elif [ "$(CONTAINER_ENGINE)" = docker ]; then \ - if docker network inspect "$$network" >/dev/null 2>&1; then \ - for c in $$(docker ps -a --filter network=$$network -q 2>/dev/null); do \ - docker network disconnect "$$network" "$$c" --force 2>/dev/null || true; \ - done; \ - fi; \ - fi; \ - done; \ - COMPOSE_PROJECT_NAME=deploy $(COMPOSE_DEPLOY) down -v --remove-orphans 2>/dev/null || true; \ - $(COMPOSE_DEPLOY) down -v --remove-orphans; \ - for network in deploy_default $(COMPOSE_NETWORK); do \ - if [ "$(CONTAINER_ENGINE)" = podman ]; then \ - podman network rm -f "$$network" 2>/dev/null || true; \ - elif [ "$(CONTAINER_ENGINE)" = docker ]; then \ - docker network rm "$$network" 2>/dev/null || true; \ - fi; \ - done +compose-up-with-agent: + $(COMPOSE_DEPLOY) $(if $(filter true,$(AUTH)),--profile auth,) --profile environment-agent up -d --build + +# Local dev helpers (scripts in dcm-project/utilities — see deploy/docs/environment-agent-kind.md). +install-kubevirt: + bash $(KUBEVIRT_SCRIPTS_DIR)/install-kubevirt.sh + +kubeconfig-for-compose: + DEPLOY_ROOT="$(CURDIR)" bash $(KIND_SCRIPTS_DIR)/kubeconfig-for-compose.sh + +kind-connect: + COMPOSE_NETWORK=$(COMPOSE_NETWORK) CONTAINER_ENGINE=$(CONTAINER_ENGINE) \ + bash $(KIND_SCRIPTS_DIR)/kind-connect.sh + +kind-disconnect: + @COMPOSE_NETWORK=$(COMPOSE_NETWORK) CONTAINER_ENGINE=$(CONTAINER_ENGINE) \ + bash $(KIND_SCRIPTS_DIR)/kind-disconnect.sh || true + +disconnect-compose-networks: + @COMPOSE_NETWORKS="$(COMPOSE_NETWORKS)" CONTAINER_ENGINE=$(CONTAINER_ENGINE) \ + bash $(COMPOSE_SCRIPTS_DIR)/network-teardown.sh disconnect || true + +remove-compose-networks: + @COMPOSE_NETWORKS="$(COMPOSE_NETWORKS)" CONTAINER_ENGINE=$(CONTAINER_ENGINE) \ + bash $(COMPOSE_SCRIPTS_DIR)/network-teardown.sh remove || true + +# Tear down the compose stack. Disconnect Kind and other externals first so networks can be removed. +compose-down: kind-disconnect disconnect-compose-networks + @COMPOSE_PROJECT_NAME=deploy $(COMPOSE) -f $(COMPOSE_FILE) down -v --remove-orphans 2>/dev/null || true; \ + $(COMPOSE) -f $(COMPOSE_FILE) down -v --remove-orphans; \ + $(MAKE) remove-compose-networks image-build: $(CONTAINER_ENGINE) build -f Containerfile -t $(CONTAINER_IMAGE_NAME):$(CONTAINER_IMAGE_TAG) . @@ -127,6 +132,8 @@ test: tidy: go mod tidy -.PHONY: build build-gitops run run-dev compose-up compose-up-with-providers compose-down image-build \ - clean fmt vet lint test test-catalog test-placement test-policy test-sp test-gitops tidy subsystem-env \ +.PHONY: build build-gitops run run-dev compose-up compose-up-with-agent compose-up-with-providers compose-down \ + install-kubevirt kubeconfig-for-compose kind-connect kind-disconnect \ + disconnect-compose-networks remove-compose-networks \ + image-build clean fmt vet lint test test-catalog test-placement test-policy test-sp test-gitops tidy subsystem-env \ helm-chart-sync helm-chart-verify-sync helm-chart-verify-admin-subject helm-chart-verify helm-chart-verify-schema helm-chart-lint helm-chart-template helm-chart-check diff --git a/README.md b/README.md index 9985730..f0d977b 100644 --- a/README.md +++ b/README.md @@ -80,10 +80,10 @@ in shared-workflows for tag behavior and version conventions. Full-stack Compose and Helm packaging live under `deploy/`: -- **Compose:** control-plane, postgres, nats, keycloak, dcm-ui, and optional service providers +- **Compose:** control-plane, postgres, nats, keycloak, dcm-ui, and optional environment-agent (or legacy external SP profiles) - **Helm:** Kubernetes/OpenShift chart at `deploy/helm/dcm` (optional auth via `auth.enabled`) -See [deploy/RUN.md](deploy/RUN.md) for local stack usage, authentication, and service provider profiles. +See [deploy/RUN.md](deploy/RUN.md) for local stack usage, authentication, and the environment-agent profile. See [deploy/helm/dcm/README.md](deploy/helm/dcm/README.md) for cluster installs. Authentication is disabled by default (`AUTH_DISABLED=true`). The CLI forwards diff --git a/deploy/.env.example b/deploy/.env.example index 6a133b9..e609cf8 100644 --- a/deploy/.env.example +++ b/deploy/.env.example @@ -37,23 +37,30 @@ DB_PASSWORD=adminpass # ACM_CLUSTER_SP_AGENT_NAMESPACE= # See compose.override.example.yaml for OpenShift route exposure on three-tier SP -# K8s container service provider (profile: k8s-container) -# K8S_CONTAINER_SP_NAMESPACE=default -# K8S_CONTAINER_SP_KUBECONFIG=~/.kube/config -# K8S_CONTAINER_SP_NAME=k8s-container-provider -# K8S_CONTAINER_SP_EXTERNAL_SVC_TYPE=NodePort - -# K8s storage service provider (profile: storage) -# K8S_STORAGE_SP_NAMESPACE=default -# K8S_STORAGE_SP_KUBECONFIG=~/.kube/config -# K8S_STORAGE_SP_NAME=k8s-storage-provider -# K8S_STORAGE_SP_DEFAULT_STORAGE_CLASS= -# K8S_STORAGE_SP_DEFAULT_ACCESS_MODE=ReadWriteOnce - -# Three-tier demo app service provider (profile: three-tier) -# THREE_TIER_SP_NAME=three-tier-provider - -# KubeVirt service provider (profile: kubevirt) -# KUBEVIRT_KUBECONFIG=~/.kube/config -# KUBEVIRT_PROVIDER_NAME=kubevirt-service-provider +# Environment agent (profile: environment-agent) +# See deploy/docs/environment-agent-kind.md +# Full agent/SP example: github.com/dcm-project/environment-agent deploy/.env.example +# AGENT_NAME=local-agent +# Service types: container, vm, cluster, storage (comma-separated). +# AGENT_EMBEDDED_SPS=container,vm,cluster,storage +# AGENT_KUBECONFIG_HOST=.kube/config # written by make kubeconfig-for-compose +# SP_K8S_NAMESPACE=default +# SP_K8S_EXTERNAL_SVC_TYPE=NodePort # KUBERNETES_NAMESPACE=default +# SP_CLUSTER_NAMESPACE=clusters +# SP_PULL_SECRET= +# SP_BASE_DOMAIN=apps.example.com +# SP_STORAGE_NAMESPACE=default +# SP_K8S_DEFAULT_STORAGE_CLASS= +# SP_K8S_DEFAULT_ACCESS_MODE=ReadWriteOnce +# ENVIRONMENT_AGENT_VERSION=main + +# --- Service image versions --- +# Pin specific versions instead of "main". Valid values: +# main - most recent main build (default) +# v0.0.1 - final release (from git tag) +# v0.0.1-rc.3 - release candidate (from release branch) +# abc1234 - specific commit build (for local testing only) +# CONTROL_PLANE_VERSION=main +# ENVIRONMENT_AGENT_VERSION=main +# DCM_UI_VERSION=main diff --git a/deploy/RUN.md b/deploy/RUN.md index bf2aebe..1b7493e 100644 --- a/deploy/RUN.md +++ b/deploy/RUN.md @@ -3,13 +3,21 @@ ## Prerequisites - [Podman](https://podman.io/) or [Docker](https://www.docker.com/) (the Makefile auto-detects which engine is available) -- (Optional) A Kubernetes cluster with KubeVirt for the kubevirt-service-provider -- (Optional) A Kubernetes cluster for the k8s-container-service-provider -- (Optional) An OpenShift cluster with ACM/MCE and HyperShift for the acm-cluster-service-provider +- (Optional) [Kind](https://kind.sigs.k8s.io/) with KubeVirt for the environment-agent embedded `vm` SP +- (Optional) A Kubernetes cluster for environment-agent embedded `container` and `cluster` SPs +- (Optional) [utilities](https://github.com/dcm-project/utilities) repo as a sibling directory for Kind helper scripts (`../utilities`) ## Quick start -Start the core platform (postgres, nats, control-plane, and dcm-ui): +### With environment-agent (Service Providers) + +An [environment-agent](https://github.com/dcm-project/environment-agent) must be running and +registered with the control-plane in order to use Service Providers. Follow the guide, +[environment-agent-kind.md](docs/environment-agent-kind.md) for the full setup. + +### Control-plane and UI only + +If you only need the API and UI (no workload provisioning): ```bash cp deploy/.env.example deploy/.env @@ -41,121 +49,10 @@ The CLI forwards bearer tokens to the control-plane API. Run `dcm login` for int OIDC device authorization (Keycloak `dcm-cli` client), or set `DCM_TOKEN` / `--token` for CI and scripting. -## Running with service providers - -Service providers are behind compose profiles and do not start by default. - -### KubeVirt service provider - -To include the `kubevirt-service-provider`, activate the `kubevirt` profile. Each provider -mounts a host kubeconfig at `/kubeconfig` (default `~/.kube/config`; override with -`KUBEVIRT_KUBECONFIG` in `deploy/.env` or the shell). - -```bash -make compose-up-with-providers PROFILES=kubevirt -``` - -### K8s container service provider - -To include the `k8s-container-service-provider`, activate the `k8s-container` profile: - -```bash -make compose-up-with-providers PROFILES=k8s-container -``` - -If using Kind, see [K8s Container SP with Kind](docs/k8s-container-sp-kind.md) for additional network setup. - -Optionally override the provider name or external service type: - -```bash -export K8S_CONTAINER_SP_NAME=my-provider -export K8S_CONTAINER_SP_EXTERNAL_SVC_TYPE=LoadBalancer -``` - -### K8s storage service provider - -To include the `k8s-storage-service-provider`, activate the `storage` profile: - -```bash -make compose-up-with-providers PROFILES=storage -``` - -Optionally override the provider name, namespace, and default PVC behavior: - -```bash -export K8S_STORAGE_SP_NAME=my-storage-provider -export K8S_STORAGE_SP_NAMESPACE=default -export K8S_STORAGE_SP_DEFAULT_STORAGE_CLASS=ceph-rbd -export K8S_STORAGE_SP_DEFAULT_ACCESS_MODE=ReadWriteOnce -``` - -### ACM cluster service provider - -To include the `acm-cluster-service-provider`, set `ACM_CLUSTER_SP_PULL_SECRET` in -`deploy/.env` (base64-encoded `.dockerconfigjson`) and activate the `acm-cluster` profile: +## Running with Environment Agent -```bash -# In deploy/.env: -# ACM_CLUSTER_SP_PULL_SECRET= -make compose-up-with-providers PROFILES=acm-cluster -``` - -Optionally override the provider name, namespace, or base domain: - -```bash -export ACM_CLUSTER_SP_NAME=my-acm-provider -export ACM_CLUSTER_SP_NAMESPACE=clusters -export ACM_CLUSTER_SP_BASE_DOMAIN="apps.example.com" -``` - -For BareMetal provisioning, also set: - -```bash -export ACM_CLUSTER_SP_DEFAULT_INFRA_ENV="my-infra-env" -export ACM_CLUSTER_SP_AGENT_NAMESPACE="my-agent-namespace" -``` - -### Three-tier demo app service provider - -To include the `three-tier-demo-service-provider`, activate the `three-tier` profile: - -```bash -make compose-up-with-providers PROFILES=three-tier -``` - -When using Kind, complete the k8s-container setup (steps 1–5 in [K8s Container -SP with Kind](docs/k8s-container-sp-kind.md)) first. -For Pet Clinic usage, see [Three-Tier Demo App with Kind](docs/three-tier-app-kind.md). - -Optionally override the provider name or cluster namespace (`K8S_CONTAINER_SP_NAMESPACE` applies -to both k8s-container and three-tier SPs): - -```bash -export THREE_TIER_SP_NAME=my-provider -export K8S_CONTAINER_SP_NAMESPACE=default -``` - -### All providers - -To start all providers at once, run: - -```bash -make compose-up-with-providers -``` - -If the `acm-cluster` provider is included, set `ACM_CLUSTER_SP_PULL_SECRET` in -`deploy/.env` first. - -This defaults to the `providers` Compose profile (all service providers, including the -three-tier demo SP). To start a single provider instead, pass `PROFILES=`: - -```bash -make compose-up-with-providers PROFILES=kubevirt -make compose-up-with-providers PROFILES=k8s-container -make compose-up-with-providers PROFILES=storage -make compose-up-with-providers PROFILES=acm-cluster -make compose-up-with-providers PROFILES=three-tier -``` +See [environment-agent-kind.md](docs/environment-agent-kind.md) for Kind setup, the +`environment-agent` compose profile, configuration, and verification. ## Authentication @@ -165,8 +62,8 @@ using OIDC discovery (no external auth proxy required). A proxy-header fallback (`X-Auth-Proxy-Secret` + `X-Forwarded-User`) is also supported. Authentication is disabled by default (`AUTH_DISABLED=true`). When enabled, the CLI -(`dcm login` / bearer token) and direct JWT API calls work; service providers do not -forward authentication headers yet, so SP ↔ control-plane traffic may fail. +(`dcm login` / bearer token) and direct JWT API calls work; the environment-agent and legacy +external service providers do not forward authentication headers yet, so SP workflows may fail. To enable authentication (Compose): @@ -183,9 +80,9 @@ With service providers: `make compose-up-with-providers PROFILES=kubevirt AUTH=t For Helm chart installs, create the `dcm-auth` Secret and set `auth.enabled=true` — see [helm/dcm/README.md](helm/dcm/README.md#authentication). -> **Warning:** Service providers do not forward authentication headers yet, so enabling -> auth can break SP workflows. The CLI (`dcm login` / bearer token) and direct API -> calls with a valid Keycloak JWT work. +> **Warning:** The environment-agent and legacy external service providers do not forward +> authentication headers yet, so enabling auth can break SP workflows. The CLI (`dcm login` / +> bearer token) and direct API calls with a valid Keycloak JWT work. When enabled, the control-plane authenticates requests via two paths (tried in order): @@ -280,7 +177,21 @@ Database, auth, and ACM pull-secret credentials are defined in `deploy/.env.exam | `KUBERNETES_NAMESPACE` | `default` | Kubernetes namespace for KubeVirt VMs | | `KUBEVIRT_KUBECONFIG` | `~/.kube/config` | Host path to kubeconfig for the kubevirt-service-provider | | `KUBEVIRT_PROVIDER_NAME` | `kubevirt-service-provider` | Provider name and Compose service `container_name` | -| `K8S_CONTAINER_SP_KUBECONFIG` | `~/.kube/config` | Host path to kubeconfig for the k8s-container and three-tier service providers | +| `K8S_CONTAINER_SP_KUBECONFIG` | `~/.kube/config` | Host path to kubeconfig for the k8s-container and three-tier service providers | +| `AGENT_NAME` | `local-agent` | Agent name for environment-agent profile | +| `AGENT_ENVIRONMENT` | `dev` | Environment classification for environment-agent | +| `AGENT_COST` | `low` | Cost classification for environment-agent | +| `AGENT_PORT` | `8081` | Host port for environment-agent HTTP API | +| `AGENT_EMBEDDED_SPS` | `container,vm` | Embedded SP types for environment-agent: `container`, `vm`, `cluster` | +| `AGENT_KUBECONFIG_HOST` | `~/.kube/config` | Host kubeconfig bind mount; use `.kube/config` in `deploy/.env` with Kind (`make kubeconfig-for-compose`) | +| `SP_K8S_NAMESPACE` | `default` | Container SP workload namespace (environment-agent) | +| `SP_K8S_EXTERNAL_SVC_TYPE` | `NodePort` | Container SP external service type (environment-agent) | +| `SP_CLUSTER_NAMESPACE` | _(required for cluster SP)_ | ACM cluster namespace (environment-agent cluster SP) | +| `SP_PULL_SECRET` | _(required for cluster SP)_ | Base64-encoded dockerconfigjson for environment-agent cluster SP | +| `SP_BASE_DOMAIN` | _(none)_ | Base domain for hosted clusters (environment-agent cluster SP) | +| `ENVIRONMENT_AGENT_VERSION` | `main` | Image tag for environment-agent | +| `KUBEVIRT_PROVIDER_NAME` | `kubevirt-service-provider` | Provider name and Compose service `container_name` (legacy kubevirt profile) | +| `K8S_CONTAINER_SP_KUBECONFIG` | `~/.kube/config` | Path to kubeconfig on the host for the k8s-container-service-provider | | `K8S_CONTAINER_SP_NAMESPACE` | `default` | Kubernetes namespace for k8s containers | | `K8S_CONTAINER_SP_NAME` | `k8s-container-provider` | Provider name for the k8s-container-service-provider | | `K8S_CONTAINER_SP_EXTERNAL_SVC_TYPE` | `NodePort` | Kubernetes Service type for external ports (`NodePort` or `LoadBalancer`) | diff --git a/deploy/compose.yaml b/deploy/compose.yaml index f34762a..3deb96a 100644 --- a/deploy/compose.yaml +++ b/deploy/compose.yaml @@ -82,96 +82,6 @@ services: nats: condition: service_started - kubevirt-service-provider: - container_name: ${KUBEVIRT_PROVIDER_NAME:-kubevirt-service-provider} - profiles: ["providers", "kubevirt"] - image: quay.io/dcm-project/kubevirt-service-provider:${KUBEVIRT_SERVICE_PROVIDER_VERSION:-main} - pull_policy: always - environment: - NATS_URL: "nats://nats:4222" - SERVICE_MANAGER_ENDPOINT: *dcm-registration-url - PROVIDER_NAME: ${KUBEVIRT_PROVIDER_NAME:-kubevirt-service-provider} - PROVIDER_ENDPOINT: "http://${KUBEVIRT_PROVIDER_NAME:-kubevirt-service-provider}:8081/api/v1alpha1/vms" - KUBERNETES_NAMESPACE: ${KUBERNETES_NAMESPACE:-default} - KUBERNETES_KUBECONFIG: /kubeconfig - volumes: - - ${KUBEVIRT_KUBECONFIG:-~/.kube/config}:/kubeconfig:ro,z - depends_on: - control-plane: - condition: service_started - - k8s-container-service-provider: - profiles: ["providers", "k8s-container", "three-tier"] - image: quay.io/dcm-project/k8s-container-service-provider:${K8S_CONTAINER_SERVICE_PROVIDER_VERSION:-main} - pull_policy: always - environment: - SP_NAME: ${K8S_CONTAINER_SP_NAME:-k8s-container-provider} - SP_ENDPOINT: "http://k8s-container-service-provider:8080" - DCM_REGISTRATION_URL: *dcm-registration-url - SP_NATS_URL: "nats://nats:4222" - SP_K8S_NAMESPACE: ${K8S_CONTAINER_SP_NAMESPACE:-default} - SP_K8S_KUBECONFIG: /kubeconfig - SP_K8S_EXTERNAL_SVC_TYPE: ${K8S_CONTAINER_SP_EXTERNAL_SVC_TYPE:-NodePort} - expose: - - "8080" - volumes: - - ${K8S_CONTAINER_SP_KUBECONFIG:-~/.kube/config}:/kubeconfig:ro,z - depends_on: - control-plane: - condition: service_started - nats: - condition: service_started - - acm-cluster-service-provider: - profiles: ["providers", "acm-cluster"] - image: quay.io/dcm-project/acm-cluster-service-provider:${ACM_CLUSTER_SERVICE_PROVIDER_VERSION:-main} - pull_policy: always - env_file: .env - environment: - SP_NAME: ${ACM_CLUSTER_SP_NAME:-acm-cluster-sp} - SP_ENDPOINT: "http://acm-cluster-service-provider:8080" - DCM_REGISTRATION_URL: *dcm-registration-url - SP_NATS_URL: "nats://nats:4222" - SP_CLUSTER_NAMESPACE: ${ACM_CLUSTER_SP_NAMESPACE:-default} - SP_BASE_DOMAIN: ${ACM_CLUSTER_SP_BASE_DOMAIN:-} - SP_PULL_SECRET: ${ACM_CLUSTER_SP_PULL_SECRET:-} - SP_DEFAULT_INFRA_ENV: ${ACM_CLUSTER_SP_DEFAULT_INFRA_ENV:-} - SP_AGENT_NAMESPACE: ${ACM_CLUSTER_SP_AGENT_NAMESPACE:-} - KUBECONFIG: /kubeconfig - expose: - - "8080" - volumes: - - ${ACM_CLUSTER_SP_KUBECONFIG:-~/.kube/config}:/kubeconfig:ro,z - depends_on: - control-plane: - condition: service_started - nats: - condition: service_started - - k8s-storage-service-provider: - profiles: ["providers", "storage"] - image: quay.io/dcm-project/k8s-storage-service-provider:${K8S_STORAGE_SERVICE_PROVIDER_VERSION:-main} - pull_policy: always - environment: - SP_NAME: ${K8S_STORAGE_SP_NAME:-k8s-storage-provider} - SP_ENDPOINT: "http://k8s-storage-service-provider:8080" - SP_SERVER_ADDRESS: ":8080" - DCM_REGISTRATION_URL: *dcm-registration-url - SP_NATS_URL: "nats://nats:4222" - SP_K8S_NAMESPACE: ${K8S_STORAGE_SP_NAMESPACE:-default} - SP_K8S_KUBECONFIG: /kubeconfig - SP_K8S_DEFAULT_STORAGE_CLASS: ${K8S_STORAGE_SP_DEFAULT_STORAGE_CLASS:-} - SP_K8S_DEFAULT_ACCESS_MODE: ${K8S_STORAGE_SP_DEFAULT_ACCESS_MODE:-ReadWriteOnce} - expose: - - "8080" - volumes: - - ${K8S_STORAGE_SP_KUBECONFIG:-~/.kube/config}:/kubeconfig:ro,z - depends_on: - control-plane: - condition: service_started - nats: - condition: service_started - dcm-ui: image: quay.io/dcm-project/dcm-ui:${DCM_UI_VERSION:-main} pull_policy: always @@ -184,35 +94,42 @@ services: control-plane: condition: service_started - three-tier-demo-service-provider: - profiles: ["providers", "three-tier"] - image: quay.io/dcm-project/three-tier-app-demo-service-provider:${THREE_TIER_DEMO_SERVICE_PROVIDER_VERSION:-main} + environment-agent: + profiles: ["environment-agent"] + image: quay.io/dcm-project/environment-agent:${ENVIRONMENT_AGENT_VERSION:-main} pull_policy: always env_file: .env environment: - <<: *db-common - DB_NAME: three-tier-sp - CONTAINER_SP_URL: "http://k8s-container-service-provider:8080" - SP_NAME: ${THREE_TIER_SP_NAME:-three-tier-provider} - SP_ENDPOINT: "http://three-tier-demo-service-provider:8080" - DCM_REGISTRATION_URL: *dcm-registration-url - SP_NATS_URL: "nats://nats:4222" - SP_K8S_NAMESPACE: ${K8S_CONTAINER_SP_NAMESPACE:-default} - SP_K8S_KUBECONFIG: /kubeconfig - expose: - - "8080" + AGENT_NAME: ${AGENT_NAME:-local-agent} + AGENT_ENVIRONMENT: ${AGENT_ENVIRONMENT:-dev} + AGENT_COST: ${AGENT_COST:-low} + # Base URL only — the agent appends /api/v1alpha1/agents for registration. + DCM_REGISTRATION_URL: http://control-plane:8080 + AGENT_MESSAGING_URL: nats://nats:4222 + AGENT_EMBEDDED_SPS: ${AGENT_EMBEDDED_SPS:-} + AGENT_KUBECONFIG: /kubeconfig + SP_K8S_NAMESPACE: ${SP_K8S_NAMESPACE:-default} + SP_K8S_EXTERNAL_SVC_TYPE: ${SP_K8S_EXTERNAL_SVC_TYPE:-NodePort} + KUBERNETES_NAMESPACE: ${KUBERNETES_NAMESPACE:-default} + SP_CLUSTER_NAMESPACE: ${SP_CLUSTER_NAMESPACE:-} + SP_PULL_SECRET: ${SP_PULL_SECRET:-} + SP_BASE_DOMAIN: ${SP_BASE_DOMAIN:-} + SP_STORAGE_NAMESPACE: ${SP_STORAGE_NAMESPACE:-default} + SP_K8S_DEFAULT_STORAGE_CLASS: ${SP_K8S_DEFAULT_STORAGE_CLASS:-} + SP_K8S_DEFAULT_ACCESS_MODE: ${SP_K8S_DEFAULT_ACCESS_MODE:-ReadWriteOnce} + AGENT_SP_PERSISTENCE_PATH: /app/data/registrations.json + ports: + - "${AGENT_PORT:-8081}:8080" volumes: - - ${K8S_CONTAINER_SP_KUBECONFIG:-~/.kube/config}:/kubeconfig:ro,z + - ${AGENT_KUBECONFIG_HOST:-~/.kube/config}:/kubeconfig:ro,z + - environment_agent_data:/app/data depends_on: control-plane: condition: service_started nats: condition: service_started - k8s-container-service-provider: - condition: service_started - postgres: - condition: service_healthy volumes: postgres_data: {} nats_data: {} + environment_agent_data: {} diff --git a/deploy/docs/environment-agent-kind.md b/deploy/docs/environment-agent-kind.md new file mode 100644 index 0000000..3a41031 --- /dev/null +++ b/deploy/docs/environment-agent-kind.md @@ -0,0 +1,164 @@ +# Environment Agent with Kind + +Run the [environment-agent](https://github.com/dcm-project/environment-agent) alongside the +control-plane compose stack. The agent shares platform NATS, registers with the control-plane on +the compose network, and runs embedded Service Providers (container, vm, cluster, storage) in-process using +a kubeconfig to reach workloads on Kind. + +## Prerequisites + +- [Podman](https://podman.io/) or [Docker](https://www.docker.com/) (Makefile auto-detects) +- [Kind](https://kind.sigs.k8s.io/) and `kubectl` +- [utilities](https://github.com/dcm-project/utilities) repo as a sibling directory + (`../utilities`) for Kind helper scripts +- Kind and compose on the **same** container runtime + +## Quick start + +This guide uses **two compose steps**: + +1. **`make compose-up`** — platform only (creates `control-plane_default` for `kind-connect`). +2. **`make compose-up-with-agent`** — after Kind is wired. + +Most Kind prep (`install-kubevirt`, `kubeconfig-for-compose`) can run **before** `compose-up`. +Only **`make kind-connect`** must run after the platform stack is up (compose network must exist). + +### 1. Create a Kind cluster + +Use the same container runtime as compose (Podman example): + +```bash +KIND_EXPERIMENTAL_PROVIDER=podman kind create cluster --name dcm-local +kubectl config use-context kind-dcm-local +``` + +For in-cluster agent deploy on the same cluster, see the +[environment-agent in-cluster guide](https://github.com/dcm-project/environment-agent/blob/main/deploy/docs/in-cluster.md) +and create the cluster with `../utilities/scripts/kind/kind-local.yaml` (host NodePort mappings for +`k8s-verify`). + +### 2. Prepare the cluster + +From the control-plane repo root: + +```bash +make install-kubevirt # when vm is in AGENT_EMBEDDED_SPS +make kubeconfig-for-compose +``` + +Writes `deploy/.kube/config` (API URL `https://kubernetes:6443`). No compose stack required yet. + +### 3. Start the platform stack (without the agent) + +```bash +cp deploy/.env.example deploy/.env # optional; set agent vars in step 5 +make compose-up +``` + +Control-plane API: `http://localhost:8080`. DCM UI: `http://localhost:7007`. + +### 4. Connect Kind to compose + +Run after `make compose-up` so `control-plane_default` exists: + +```bash +make kind-connect +``` + +Override the utilities path when needed: + +```bash +make kind-connect KIND_SCRIPTS_DIR=/path/to/utilities/scripts/kind +``` + +### 5. Configure the agent + +Enable the SPs in `deploy/.env`. For example: + +```bash +AGENT_EMBEDDED_SPS=container,vm +AGENT_KUBECONFIG_HOST=.kube/config +``` + +### 6. Start the agent (`compose-up-with-agent`) + +```bash +make compose-up-with-agent +``` + +Brings up the environment-agent profile on the running platform stack (or starts platform + agent +together if the stack was stopped). + +Agent API: `http://localhost:8081`. + +### 7. Verify + +```bash +curl http://localhost:8080/api/v1alpha1/health +curl http://localhost:8080/api/v1alpha1/agents +curl http://localhost:8081/api/v1alpha1/health +curl http://localhost:8081/api/v1alpha1/providers +``` + +### 8. Teardown + +```bash +make compose-down # kind-disconnect, detach externals, compose down, remove networks +kind delete cluster --name dcm-local +``` + +## Makefile targets + +| Target | Purpose | +|--------|---------| +| `compose-up` | Platform stack (postgres, nats, keycloak, control-plane, dcm-ui) | +| `install-kubevirt` | Install KubeVirt on the current Kind cluster | +| `kubeconfig-for-compose` | Write `deploy/.kube/config` for the agent container | +| `kind-connect` | Join Kind to `control-plane_default` | +| `compose-up-with-agent` | Add/start environment-agent on the platform stack | +| `compose-down` | Kind disconnect, detach network members, compose down, remove networks | + +Scripts are under `UTILITIES_DIR` (default `../utilities`): + +- `scripts/kind/` — Kind networking +- `scripts/compose/` — compose network teardown +- `scripts/kubevirt/` — KubeVirt install + +See [utilities scripts/kind/README.md](https://github.com/dcm-project/utilities/blob/main/scripts/kind/README.md) +and [scripts/compose/README.md](https://github.com/dcm-project/utilities/blob/main/scripts/compose/README.md). + +## Configuration + +Copy `deploy/.env.example` to `deploy/.env` in this repo and set agent profile variables before +`compose-up-with-agent`. See [deploy/.env.example](../.env.example) for the variables wired into +`deploy/compose.yaml`. + +For the full catalog of agent and SP environment variables, see +[environment-agent deploy/.env.example](https://github.com/dcm-project/environment-agent/blob/main/deploy/.env.example). + +| Variable | Default | Description | +| --- | --- | --- | +| `AGENT_NAME` | `local-agent` | Agent name sent to DCM | +| `AGENT_ENVIRONMENT` | `dev` | Environment classification | +| `AGENT_COST` | `low` | Cost classification | +| `AGENT_PORT` | `8081` | Host port for agent HTTP API | +| `AGENT_EMBEDDED_SPS` | `container,vm` | Embedded SP types: `container`, `vm`, `cluster` | +| `AGENT_KUBECONFIG_HOST` | `~/.kube/config` | Host kubeconfig bind mount; use `.kube/config` with Kind (`make kubeconfig-for-compose`) | +| `SP_K8S_NAMESPACE` | `default` | Container SP workload namespace | +| `SP_K8S_EXTERNAL_SVC_TYPE` | `NodePort` | Container SP external service type | +| `KUBERNETES_NAMESPACE` | `default` | VM SP workload namespace | +| `ENVIRONMENT_AGENT_VERSION` | `main` | Agent image tag | + +`DCM_REGISTRATION_URL` is set to `http://control-plane:8080` in compose (base URL only and the agent +appends `/api/v1alpha1/agents`). `AGENT_MESSAGING_URL` is `nats://nats:4222`. + +## Why Kind networking is needed + +| Problem | Cause | +|---------|-------| +| Agent container can't reach Kind's IP | Kind and compose run on separate container networks | +| Agent uses `127.0.0.1:` | Default kubeconfig targets the host-side port mapping | +| TLS error with arbitrary hostname | API server cert only includes specific SANs | + +`make kind-connect` joins Kind to the compose network with alias `kubernetes` (a cert SAN). +`make kubeconfig-for-compose` rewrites the API server URL to `https://kubernetes:6443`. From 63f92d543ae61cf35dff49770a8c4fab7ac59313 Mon Sep 17 00:00:00 2001 From: Jennifer Ubah Date: Mon, 7 Sep 2026 11:22:24 -0400 Subject: [PATCH 2/5] Update name Assisted-By: Cursor AI Signed-off-by: Jennifer Ubah --- deploy/.env.example | 5 ++--- deploy/RUN.md | 8 ++++++-- deploy/compose.yaml | 6 +++--- deploy/docs/environment-agent-kind.md | 13 ++++++++++--- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/deploy/.env.example b/deploy/.env.example index e609cf8..3001613 100644 --- a/deploy/.env.example +++ b/deploy/.env.example @@ -41,12 +41,11 @@ DB_PASSWORD=adminpass # See deploy/docs/environment-agent-kind.md # Full agent/SP example: github.com/dcm-project/environment-agent deploy/.env.example # AGENT_NAME=local-agent -# Service types: container, vm, cluster, storage (comma-separated). # AGENT_EMBEDDED_SPS=container,vm,cluster,storage # AGENT_KUBECONFIG_HOST=.kube/config # written by make kubeconfig-for-compose -# SP_K8S_NAMESPACE=default +# SP_CONTAINER_NAMESPACE=default # SP_K8S_EXTERNAL_SVC_TYPE=NodePort -# KUBERNETES_NAMESPACE=default +# SP_VM_NAMESPACE=default # SP_CLUSTER_NAMESPACE=clusters # SP_PULL_SECRET= # SP_BASE_DOMAIN=apps.example.com diff --git a/deploy/RUN.md b/deploy/RUN.md index 1b7493e..8f46adf 100644 --- a/deploy/RUN.md +++ b/deploy/RUN.md @@ -182,13 +182,17 @@ Database, auth, and ACM pull-secret credentials are defined in `deploy/.env.exam | `AGENT_ENVIRONMENT` | `dev` | Environment classification for environment-agent | | `AGENT_COST` | `low` | Cost classification for environment-agent | | `AGENT_PORT` | `8081` | Host port for environment-agent HTTP API | -| `AGENT_EMBEDDED_SPS` | `container,vm` | Embedded SP types for environment-agent: `container`, `vm`, `cluster` | +| `AGENT_EMBEDDED_SPS` | `container,vm` | Embedded SP types for environment-agent: `container`, `vm`, `cluster`, `storage` | | `AGENT_KUBECONFIG_HOST` | `~/.kube/config` | Host kubeconfig bind mount; use `.kube/config` in `deploy/.env` with Kind (`make kubeconfig-for-compose`) | -| `SP_K8S_NAMESPACE` | `default` | Container SP workload namespace (environment-agent) | +| `SP_CONTAINER_NAMESPACE` | `default` | Container SP workload namespace (environment-agent) | | `SP_K8S_EXTERNAL_SVC_TYPE` | `NodePort` | Container SP external service type (environment-agent) | +| `SP_VM_NAMESPACE` | `default` | VM SP workload namespace (environment-agent) | | `SP_CLUSTER_NAMESPACE` | _(required for cluster SP)_ | ACM cluster namespace (environment-agent cluster SP) | | `SP_PULL_SECRET` | _(required for cluster SP)_ | Base64-encoded dockerconfigjson for environment-agent cluster SP | | `SP_BASE_DOMAIN` | _(none)_ | Base domain for hosted clusters (environment-agent cluster SP) | +| `SP_STORAGE_NAMESPACE` | `default` | Storage SP workload namespace (environment-agent) | +| `SP_K8S_DEFAULT_STORAGE_CLASS` | _(none)_ | Default storage class for environment-agent storage SP | +| `SP_K8S_DEFAULT_ACCESS_MODE` | `ReadWriteOnce` | Default PVC access mode for environment-agent storage SP | | `ENVIRONMENT_AGENT_VERSION` | `main` | Image tag for environment-agent | | `KUBEVIRT_PROVIDER_NAME` | `kubevirt-service-provider` | Provider name and Compose service `container_name` (legacy kubevirt profile) | | `K8S_CONTAINER_SP_KUBECONFIG` | `~/.kube/config` | Path to kubeconfig on the host for the k8s-container-service-provider | diff --git a/deploy/compose.yaml b/deploy/compose.yaml index 3deb96a..d458a98 100644 --- a/deploy/compose.yaml +++ b/deploy/compose.yaml @@ -107,10 +107,10 @@ services: DCM_REGISTRATION_URL: http://control-plane:8080 AGENT_MESSAGING_URL: nats://nats:4222 AGENT_EMBEDDED_SPS: ${AGENT_EMBEDDED_SPS:-} - AGENT_KUBECONFIG: /kubeconfig - SP_K8S_NAMESPACE: ${SP_K8S_NAMESPACE:-default} + SP_DEFAULT_KUBECONFIG: /kubeconfig + SP_CONTAINER_NAMESPACE: ${SP_CONTAINER_NAMESPACE:-default} SP_K8S_EXTERNAL_SVC_TYPE: ${SP_K8S_EXTERNAL_SVC_TYPE:-NodePort} - KUBERNETES_NAMESPACE: ${KUBERNETES_NAMESPACE:-default} + SP_VM_NAMESPACE: ${SP_VM_NAMESPACE:-default} SP_CLUSTER_NAMESPACE: ${SP_CLUSTER_NAMESPACE:-} SP_PULL_SECRET: ${SP_PULL_SECRET:-} SP_BASE_DOMAIN: ${SP_BASE_DOMAIN:-} diff --git a/deploy/docs/environment-agent-kind.md b/deploy/docs/environment-agent-kind.md index 3a41031..6ff1354 100644 --- a/deploy/docs/environment-agent-kind.md +++ b/deploy/docs/environment-agent-kind.md @@ -142,11 +142,18 @@ For the full catalog of agent and SP environment variables, see | `AGENT_ENVIRONMENT` | `dev` | Environment classification | | `AGENT_COST` | `low` | Cost classification | | `AGENT_PORT` | `8081` | Host port for agent HTTP API | -| `AGENT_EMBEDDED_SPS` | `container,vm` | Embedded SP types: `container`, `vm`, `cluster` | +| `AGENT_EMBEDDED_SPS` | `container,vm` | Embedded SP types: `container`, `vm`, `cluster`, `storage` | | `AGENT_KUBECONFIG_HOST` | `~/.kube/config` | Host kubeconfig bind mount; use `.kube/config` with Kind (`make kubeconfig-for-compose`) | -| `SP_K8S_NAMESPACE` | `default` | Container SP workload namespace | +| `SP_DEFAULT_KUBECONFIG` | `/kubeconfig` | In-container path (set in `compose.yaml`; do not set in `.env`) | +| `SP_CONTAINER_NAMESPACE` | `default` | Container SP workload namespace | | `SP_K8S_EXTERNAL_SVC_TYPE` | `NodePort` | Container SP external service type | -| `KUBERNETES_NAMESPACE` | `default` | VM SP workload namespace | +| `SP_VM_NAMESPACE` | `default` | VM SP workload namespace | +| `SP_CLUSTER_NAMESPACE` | _(required for cluster SP)_ | ACM cluster namespace | +| `SP_PULL_SECRET` | _(required for cluster SP)_ | Base64-encoded dockerconfigjson | +| `SP_BASE_DOMAIN` | _(none)_ | Base domain for hosted clusters | +| `SP_STORAGE_NAMESPACE` | `default` | Storage SP workload namespace | +| `SP_K8S_DEFAULT_STORAGE_CLASS` | _(none)_ | Default storage class for storage SP | +| `SP_K8S_DEFAULT_ACCESS_MODE` | `ReadWriteOnce` | Default PVC access mode for storage SP | | `ENVIRONMENT_AGENT_VERSION` | `main` | Agent image tag | `DCM_REGISTRATION_URL` is set to `http://control-plane:8080` in compose (base URL only and the agent From 908b8e9215d54b135d5325d03aeb814565f1dad7 Mon Sep 17 00:00:00 2001 From: Jennifer Ubah Date: Wed, 9 Sep 2026 09:47:07 -0400 Subject: [PATCH 3/5] Fix doc + remove legacy providers Assisted-By: Cursor AI Signed-off-by: Jennifer Ubah --- Makefile | 2 +- README.md | 2 +- deploy/.env.example | 5 +- deploy/RUN.md | 41 +--- deploy/compose.override.example.yaml | 17 -- deploy/compose.yaml | 2 + deploy/docs/environment-agent-kind.md | 14 +- deploy/docs/k8s-container-sp-kind.md | 97 --------- deploy/docs/three-tier-app-kind.md | 272 -------------------------- 9 files changed, 23 insertions(+), 429 deletions(-) delete mode 100644 deploy/compose.override.example.yaml delete mode 100644 deploy/docs/k8s-container-sp-kind.md delete mode 100644 deploy/docs/three-tier-app-kind.md diff --git a/Makefile b/Makefile index c944ee8..2cb61ce 100644 --- a/Makefile +++ b/Makefile @@ -132,7 +132,7 @@ test: tidy: go mod tidy -.PHONY: build build-gitops run run-dev compose-up compose-up-with-agent compose-up-with-providers compose-down \ +.PHONY: build build-gitops run run-dev compose-up compose-up-with-agent compose-down \ install-kubevirt kubeconfig-for-compose kind-connect kind-disconnect \ disconnect-compose-networks remove-compose-networks \ image-build clean fmt vet lint test test-catalog test-placement test-policy test-sp test-gitops tidy subsystem-env \ diff --git a/README.md b/README.md index f0d977b..b96ba85 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ in shared-workflows for tag behavior and version conventions. Full-stack Compose and Helm packaging live under `deploy/`: -- **Compose:** control-plane, postgres, nats, keycloak, dcm-ui, and optional environment-agent (or legacy external SP profiles) +- **Compose:** control-plane, postgres, nats, keycloak, dcm-ui, and optional environment-agent profile - **Helm:** Kubernetes/OpenShift chart at `deploy/helm/dcm` (optional auth via `auth.enabled`) See [deploy/RUN.md](deploy/RUN.md) for local stack usage, authentication, and the environment-agent profile. diff --git a/deploy/.env.example b/deploy/.env.example index 3001613..fc91e69 100644 --- a/deploy/.env.example +++ b/deploy/.env.example @@ -37,11 +37,10 @@ DB_PASSWORD=adminpass # ACM_CLUSTER_SP_AGENT_NAMESPACE= # See compose.override.example.yaml for OpenShift route exposure on three-tier SP -# Environment agent (profile: environment-agent) +# Environment agent (profile: environment-agent) — required when using the agent profile # See deploy/docs/environment-agent-kind.md -# Full agent/SP example: github.com/dcm-project/environment-agent deploy/.env.example # AGENT_NAME=local-agent -# AGENT_EMBEDDED_SPS=container,vm,cluster,storage +# AGENT_EMBEDDED_SPS=container,vm # required; compose has no default (e.g. container, vm, cluster, storage) # AGENT_KUBECONFIG_HOST=.kube/config # written by make kubeconfig-for-compose # SP_CONTAINER_NAMESPACE=default # SP_K8S_EXTERNAL_SVC_TYPE=NodePort diff --git a/deploy/RUN.md b/deploy/RUN.md index 8f46adf..1911c1b 100644 --- a/deploy/RUN.md +++ b/deploy/RUN.md @@ -62,8 +62,8 @@ using OIDC discovery (no external auth proxy required). A proxy-header fallback (`X-Auth-Proxy-Secret` + `X-Forwarded-User`) is also supported. Authentication is disabled by default (`AUTH_DISABLED=true`). When enabled, the CLI -(`dcm login` / bearer token) and direct JWT API calls work; the environment-agent and legacy -external service providers do not forward authentication headers yet, so SP workflows may fail. +(`dcm login` / bearer token) and direct JWT API calls work; the environment-agent does not +forward authentication headers yet, so SP workflows may fail. To enable authentication (Compose): @@ -80,9 +80,9 @@ With service providers: `make compose-up-with-providers PROFILES=kubevirt AUTH=t For Helm chart installs, create the `dcm-auth` Secret and set `auth.enabled=true` — see [helm/dcm/README.md](helm/dcm/README.md#authentication). -> **Warning:** The environment-agent and legacy external service providers do not forward -> authentication headers yet, so enabling auth can break SP workflows. The CLI (`dcm login` / -> bearer token) and direct API calls with a valid Keycloak JWT work. +> **Warning:** The environment-agent does not forward authentication headers yet, so enabling +> auth can break SP workflows. The CLI (`dcm login` / bearer token) and direct API calls with a +> valid Keycloak JWT work. When enabled, the control-plane authenticates requests via two paths (tried in order): @@ -154,7 +154,7 @@ make compose-down ``` This stops all compose services and removes volumes. If Kind was connected to -the compose network (see [k8s-container-sp-kind.md](docs/k8s-container-sp-kind.md)), +the compose network (see [environment-agent-kind.md](docs/environment-agent-kind.md)), `compose-down` disconnects external containers and removes both `control-plane_default` and legacy `deploy_default` networks. @@ -174,15 +174,11 @@ Database, auth, and ACM pull-secret credentials are defined in `deploy/.env.exam | `POSTGRES_USER` / `POSTGRES_PASSWORD` | _(in `.env.example`) | PostgreSQL credentials (also `DB_USER`, `DB_PASS`, `DB_PASSWORD`) | | `KEYCLOAK_ADMIN_PASSWORD` | _(in `.env.example`) | Keycloak admin console password | | `DCM_DEV_USER_PASSWORD` | _(in `.env.example`) | Password for the `dcm-admin` dev user in Keycloak | -| `KUBERNETES_NAMESPACE` | `default` | Kubernetes namespace for KubeVirt VMs | -| `KUBEVIRT_KUBECONFIG` | `~/.kube/config` | Host path to kubeconfig for the kubevirt-service-provider | -| `KUBEVIRT_PROVIDER_NAME` | `kubevirt-service-provider` | Provider name and Compose service `container_name` | -| `K8S_CONTAINER_SP_KUBECONFIG` | `~/.kube/config` | Host path to kubeconfig for the k8s-container and three-tier service providers | | `AGENT_NAME` | `local-agent` | Agent name for environment-agent profile | | `AGENT_ENVIRONMENT` | `dev` | Environment classification for environment-agent | | `AGENT_COST` | `low` | Cost classification for environment-agent | | `AGENT_PORT` | `8081` | Host port for environment-agent HTTP API | -| `AGENT_EMBEDDED_SPS` | `container,vm` | Embedded SP types for environment-agent: `container`, `vm`, `cluster`, `storage` | +| `AGENT_EMBEDDED_SPS` | _(empty)_ | **Required in `deploy/.env`** when using the agent profile. Comma-separated: `container`, `vm`, `cluster`, `storage` | | `AGENT_KUBECONFIG_HOST` | `~/.kube/config` | Host kubeconfig bind mount; use `.kube/config` in `deploy/.env` with Kind (`make kubeconfig-for-compose`) | | `SP_CONTAINER_NAMESPACE` | `default` | Container SP workload namespace (environment-agent) | | `SP_K8S_EXTERNAL_SVC_TYPE` | `NodePort` | Container SP external service type (environment-agent) | @@ -194,30 +190,7 @@ Database, auth, and ACM pull-secret credentials are defined in `deploy/.env.exam | `SP_K8S_DEFAULT_STORAGE_CLASS` | _(none)_ | Default storage class for environment-agent storage SP | | `SP_K8S_DEFAULT_ACCESS_MODE` | `ReadWriteOnce` | Default PVC access mode for environment-agent storage SP | | `ENVIRONMENT_AGENT_VERSION` | `main` | Image tag for environment-agent | -| `KUBEVIRT_PROVIDER_NAME` | `kubevirt-service-provider` | Provider name and Compose service `container_name` (legacy kubevirt profile) | -| `K8S_CONTAINER_SP_KUBECONFIG` | `~/.kube/config` | Path to kubeconfig on the host for the k8s-container-service-provider | -| `K8S_CONTAINER_SP_NAMESPACE` | `default` | Kubernetes namespace for k8s containers | -| `K8S_CONTAINER_SP_NAME` | `k8s-container-provider` | Provider name for the k8s-container-service-provider | -| `K8S_CONTAINER_SP_EXTERNAL_SVC_TYPE` | `NodePort` | Kubernetes Service type for external ports (`NodePort` or `LoadBalancer`) | -| `K8S_STORAGE_SP_KUBECONFIG` | `~/.kube/config` | Host path to kubeconfig for the k8s-storage-service-provider | -| `K8S_STORAGE_SP_NAMESPACE` | `default` | Kubernetes namespace used by the k8s-storage-service-provider | -| `K8S_STORAGE_SP_NAME` | `k8s-storage-provider` | Provider name for the k8s-storage-service-provider | -| `K8S_STORAGE_SP_DEFAULT_STORAGE_CLASS` | _(empty)_ | Optional fallback StorageClass when request hints do not set one | -| `K8S_STORAGE_SP_DEFAULT_ACCESS_MODE` | `ReadWriteOnce` | Optional fallback access mode when request hints do not set one | -| `ACM_CLUSTER_SP_KUBECONFIG` | `~/.kube/config` | Host path to kubeconfig for the acm-cluster-service-provider | -| `ACM_CLUSTER_SP_NAMESPACE` | `default` | Kubernetes namespace for ACM hosted clusters | -| `ACM_CLUSTER_SP_NAME` | `acm-cluster-sp` | Provider name for the acm-cluster-service-provider | -| `ACM_CLUSTER_SP_BASE_DOMAIN` | _(none)_ | Base DNS domain for hosted clusters; can be overridden per-request via `provider_hints.acm.base_domain` | -| `ACM_CLUSTER_SP_PULL_SECRET` | _(in `.env`) | Base64-encoded dockerconfigjson pull secret for ACM hosted clusters (required for `acm-cluster` profile) | -| `ACM_CLUSTER_SP_DEFAULT_INFRA_ENV` | _(none)_ | **BareMetal only.** Default InfraEnv name; can be overridden per-request via `provider_hints.acm.infra_env` | -| `ACM_CLUSTER_SP_AGENT_NAMESPACE` | _(none)_ | **BareMetal only.** Namespace where Agent resources are located | | `CONTROL_PLANE_VERSION` | `main` | Image tag for control-plane monolith | -| `KUBEVIRT_SERVICE_PROVIDER_VERSION` | `main` | Image tag for kubevirt-service-provider | -| `K8S_CONTAINER_SERVICE_PROVIDER_VERSION` | `main` | Image tag for k8s-container-service-provider | -| `K8S_STORAGE_SERVICE_PROVIDER_VERSION` | `main` | Image tag for k8s-storage-service-provider | -| `ACM_CLUSTER_SERVICE_PROVIDER_VERSION` | `main` | Image tag for acm-cluster-service-provider | -| `THREE_TIER_DEMO_SERVICE_PROVIDER_VERSION` | `main` | Image tag for three-tier-demo-service-provider | -| `THREE_TIER_SP_NAME` | `three-tier-provider` | Provider name for the three-tier-demo-service-provider | | `DCM_UI_VERSION` | `main` | Image tag for dcm-ui | See [Image versions](../README.md#image-versions) in the README for available tag formats and how to update. diff --git a/deploy/compose.override.example.yaml b/deploy/compose.override.example.yaml deleted file mode 100644 index 58c91c5..0000000 --- a/deploy/compose.override.example.yaml +++ /dev/null @@ -1,17 +0,0 @@ -# OpenShift: Route-based web exposure for three-tier-demo-service-provider. -# For Kind / default kubernetes exposure, do not install an override (remove -# deploy/compose.override.yaml if present). -# -# cp deploy/compose.override.example.yaml deploy/compose.override.yaml -# -# Match SP_OPENSHIFT_ROUTE_NAMESPACE to the k8s container SP namespace (same as -# K8S_CONTAINER_SP_NAMESPACE in .env). See deploy/docs/three-tier-app-kind.md. - -services: - three-tier-demo-service-provider: - environment: - SP_WEB_EXPOSURE: openshift - SP_OPENSHIFT_ROUTE_NAMESPACE: ${K8S_CONTAINER_SP_NAMESPACE:-default} - SP_OPENSHIFT_KUBECONFIG: /openshift-kubeconfig - volumes: - - ${KUBECONFIG:-$HOME/.kube/config}:/openshift-kubeconfig:ro,z diff --git a/deploy/compose.yaml b/deploy/compose.yaml index d458a98..471036c 100644 --- a/deploy/compose.yaml +++ b/deploy/compose.yaml @@ -81,6 +81,8 @@ services: condition: service_healthy nats: condition: service_started + keycloak: + condition: service_healthy dcm-ui: image: quay.io/dcm-project/dcm-ui:${DCM_UI_VERSION:-main} diff --git a/deploy/docs/environment-agent-kind.md b/deploy/docs/environment-agent-kind.md index 6ff1354..40f5501 100644 --- a/deploy/docs/environment-agent-kind.md +++ b/deploy/docs/environment-agent-kind.md @@ -51,12 +51,14 @@ Writes `deploy/.kube/config` (API URL `https://kubernetes:6443`). No compose sta ### 3. Start the platform stack (without the agent) ```bash -cp deploy/.env.example deploy/.env # optional; set agent vars in step 5 +cp deploy/.env.example deploy/.env make compose-up ``` Control-plane API: `http://localhost:8080`. DCM UI: `http://localhost:7007`. +Set agent variables in `deploy/.env` before starting the agent (step 6). + ### 4. Connect Kind to compose Run after `make compose-up` so `control-plane_default` exists: @@ -73,13 +75,17 @@ make kind-connect KIND_SCRIPTS_DIR=/path/to/utilities/scripts/kind ### 5. Configure the agent -Enable the SPs in `deploy/.env`. For example: +**Required:** set `AGENT_EMBEDDED_SPS` in `deploy/.env`. Compose does not default this — an unset +value means no embedded service providers. ```bash -AGENT_EMBEDDED_SPS=container,vm +AGENT_EMBEDDED_SPS=container AGENT_KUBECONFIG_HOST=.kube/config ``` +Add `vm`, `cluster`, or `storage` as needed (e.g. `container,vm`). Run `make install-kubevirt` +when `vm` is included. + ### 6. Start the agent (`compose-up-with-agent`) ```bash @@ -142,7 +148,7 @@ For the full catalog of agent and SP environment variables, see | `AGENT_ENVIRONMENT` | `dev` | Environment classification | | `AGENT_COST` | `low` | Cost classification | | `AGENT_PORT` | `8081` | Host port for agent HTTP API | -| `AGENT_EMBEDDED_SPS` | `container,vm` | Embedded SP types: `container`, `vm`, `cluster`, `storage` | +| `AGENT_EMBEDDED_SPS` | _empty_ (set in `deploy/.env`) | **Required** for the agent profile. Comma-separated: `container`, `vm`, `cluster`, `storage` | | `AGENT_KUBECONFIG_HOST` | `~/.kube/config` | Host kubeconfig bind mount; use `.kube/config` with Kind (`make kubeconfig-for-compose`) | | `SP_DEFAULT_KUBECONFIG` | `/kubeconfig` | In-container path (set in `compose.yaml`; do not set in `.env`) | | `SP_CONTAINER_NAMESPACE` | `default` | Container SP workload namespace | diff --git a/deploy/docs/k8s-container-sp-kind.md b/deploy/docs/k8s-container-sp-kind.md deleted file mode 100644 index 09636af..0000000 --- a/deploy/docs/k8s-container-sp-kind.md +++ /dev/null @@ -1,97 +0,0 @@ -# K8s Container Service Provider with Kind - -When Kind runs with Podman, its API server lives on a separate -Podman network. The compose services can't reach it by default. - -## Setup (one-time, until containers are recreated) - -### 1. Create the Kind cluster - -```bash -KIND_EXPERIMENTAL_PROVIDER=podman kind create cluster -``` - -This creates a container named `kind-control-plane`. -If you use `--name `, the container will be `-control-plane`. - -### 2. Start the compose services - -This must be done **before** step 3 so the compose network exists. - -```bash -podman compose -f deploy/compose.yaml --profile k8s-container up -d -``` - -### 3. Connect Kind to the compose network - -Connect the Kind control-plane container to the compose network with -an alias that matches a SAN in Kind's API server certificate. - -To list valid SANs: - -```bash -podman exec kind-control-plane \ - openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text \ - | grep -A1 "Subject Alternative Name" -``` - -Use `kubernetes` as the alias (short, always present in the SAN list): - -```bash -podman network connect \ - --alias kubernetes \ - deploy_default \ - kind-control-plane -``` - -> **Note:** `make compose-up` sets `COMPOSE_PROJECT_NAME=control-plane`, so the -> network is `deploy_default`. Verify with `podman network ls`. -> `make compose-down` disconnects Kind and removes the network automatically. - -### 4. Generate a kubeconfig that uses the alias - -```bash -kubectl config view --minify --flatten --context kind-kind \ - | sed -E 's|https://[^:]+:[0-9]+|https://kubernetes:6443|' \ - > kubeconfig.yaml -``` - -Kind maps the API server to a random host port (e.g. `44615`), but -container-to-container traffic uses port `6443` directly. - -### 5. Point the SP to the generated kubeconfig - -The compose file mounts `${K8S_CONTAINER_SP_KUBECONFIG:-~/.kube/config}` into the -SP container. Set the variable to the generated file and restart: - -```bash -export K8S_CONTAINER_SP_KUBECONFIG="$(pwd)/kubeconfig.yaml" -podman compose -f deploy/compose.yaml --profile k8s-container up -d -``` - -### External service type - -The SP requires `SP_K8S_EXTERNAL_SVC_TYPE` to determine the Kubernetes Service -type for ports with `external` visibility. Valid values: - -| Value | Use case | -|---|---| -| `NodePort` | Default. Works out of the box with Kind and bare-metal clusters. | -| `LoadBalancer` | Cloud environments with a load-balancer controller (e.g., AWS, GCP) or clusters running MetalLB. | - -The compose file defaults to `NodePort`. Override it with: - -```bash -export K8S_CONTAINER_SP_EXTERNAL_SVC_TYPE=LoadBalancer -``` - -## Why this is needed - -| Problem | Cause | -|---|---| -| SP container can't reach Kind's IP | That IP belongs to Kind's network; compose services are on `deploy_default` | -| SP connects to `127.0.0.1:` | Kind's default kubeconfig uses the host-side port mapping, unreachable from other containers | -| TLS error using arbitrary hostname | The API server certificate only includes specific SANs | - -Connecting Kind to the compose network with a certificate-valid alias -and generating a kubeconfig that targets it solves all three. diff --git a/deploy/docs/three-tier-app-kind.md b/deploy/docs/three-tier-app-kind.md deleted file mode 100644 index 11a2f6b..0000000 --- a/deploy/docs/three-tier-app-kind.md +++ /dev/null @@ -1,272 +0,0 @@ -# Three-Tier Demo App Service Provider with Kind - -The Three-Tier Demo App Service Provider (SP) is a DCM plugin that provisions a Pet Clinic application -into a Kubernetes cluster. It requires the k8s-container-service-provider to be configured and running. - -## Setup (one-time, until containers are recreated) - -### CLI or curl - -In the Compose setup from this repo, the control-plane API is **http://localhost:8080** by default. The -sections below give **`dcm`** ([CLI repo](https://github.com/dcm-project/cli)) and **`curl`** for the -same operations. They are equivalent, so use whichever you prefer. -Build or install **`dcm`** per the [CLI README](https://github.com/dcm-project/cli/blob/main/README.md). -Set the control-plane API URL in **`~/.dcm/config.yaml`** (`control-plane-url`) or via -**`DCM_CONTROL_PLANE_URL`** if the API is not on localhost:8080 (default). - -### Prerequisites - -Before starting the three-tier SP, you must complete the k8s-container-service-provider setup: - -1. Follow steps 1–5 in [k8s-container-sp-kind.md](k8s-container-sp-kind.md) to set up: - - A Kind cluster connected to the Compose network - - A kubeconfig configured to use the `kubernetes` alias - - The k8s-container-service-provider running and healthy - -Verify the setup: - -```bash -dcm sp provider list -``` - -Or: - -```bash -curl -s http://localhost:8080/api/v1alpha1/providers | jq '.providers[] | {name, health_status}' -``` - -> **Note:** The response should include `k8s-container-provider` in the list of available providers. - -### 1. Start the three-tier SP - -Using the Makefile (recommended): - -```bash -export K8S_CONTAINER_SP_KUBECONFIG="$(pwd)/kubeconfig.yaml" -make compose-up-with-providers PROFILES=three-tier -``` - -Or the same compose invocation without Make: - -```bash -export K8S_CONTAINER_SP_KUBECONFIG="$(pwd)/kubeconfig.yaml" -podman compose --profile three-tier up -d -``` - -> **Note:** The three-tier profile automatically includes the k8s-container-service-provider -> as a dependency. Both services will start together. - -Verify it is running: - -```bash -podman ps --format "table {{.Names}}\t{{.Status}}" | grep -E 'three-tier|k8s-container' -``` - -Check the SP is registered with DCM: - -```bash -dcm sp provider list -``` - -Or: - -```bash -curl -s http://localhost:8080/api/v1alpha1/providers | jq '.providers[] | select(.name | contains("three-tier"))' -``` - -Note the provider’s `name` (by default `three-tier-provider` unless you changed `THREE_TIER_SP_NAME` in Compose). - -### 2. Provision the Pet Clinic application - -Register a placement policy once, then create a catalog item instance via the -control-plane API (**`dcm`** or **`curl`**). The **First time only (policy)** note sits next to the commands in each subsection. - -#### With DCM CLI - -Create a folder and both YAML files there (copy and paste the whole block): - -```bash -mkdir -p /tmp/dcm-petclinic - -cat > /tmp/dcm-petclinic/three-tier-placement.yaml <<'EOF' -display_name: Three-tier placement -policy_type: GLOBAL -enabled: true -priority: 100 -rego_code: | - package policies.three_tier_default - - main := { - "rejected": false, - "selected_provider": "three-tier-provider" - } if { - input.spec.service_type == "three-tier-app-demo" - } -EOF - -cat > /tmp/dcm-petclinic/my-petclinic.yaml <<'EOF' -api_version: v1alpha1 -display_name: my-petclinic -spec: - catalog_item_id: pet-clinic - user_values: - - path: database.engine - value: postgres - - path: database.version - value: "18" -EOF -``` - -**`three-tier-placement.yaml`** is a placement policy so Policy Manager routes **`three-tier-app-demo`** to -**`three-tier-provider`**. **`my-petclinic.yaml`** is the catalog instance (Pet Clinic item and DB -settings). - -**Control-plane URL:** This repo does not ship a DCM config file. The CLI defaults to -`http://localhost:8080`, which matches this compose stack; **no config file is required** for -that case. Otherwise set `export DCM_CONTROL_PLANE_URL=…` for the session, or create -`~/.dcm/config.yaml`: - -```yaml -control-plane-url: http://localhost:8080 -``` - -If Policy Manager has never been configured, add the rule below so the -platform selects your three-tier provider (same `name` as in step **1**, usually `three-tier-provider`). -Without it, the instance create call can fail with `policy response missing selected provider`. - -Rego sees the instance **`spec`** as **`input.spec`**. This example matches -`service_type == "three-tier-app-demo"`; other service types skip this policy. - -```bash -dcm policy create --from-file /tmp/dcm-petclinic/three-tier-placement.yaml --id three-tier-placement -``` - -Then provision the three tier demo app: - -```bash -dcm catalog item list -dcm catalog instance create --from-file /tmp/dcm-petclinic/my-petclinic.yaml -``` - -#### With `curl` - -**First time only (policy):** Same placement rule as above. POST the policy below only if it is not -already present (duplicate returns **409**). - -```bash -curl -s -X POST 'http://localhost:8080/api/v1alpha1/policies?id=three-tier-placement' \ - -H 'Content-Type: application/json' \ - -d @- <<'JSON' -{ - "display_name": "Three-tier placement", - "policy_type": "GLOBAL", - "enabled": true, - "priority": 100, - "rego_code": "package policies.three_tier_default\n\nmain := {\n \"rejected\": false,\n \"selected_provider\": \"three-tier-provider\"\n} if {\n input.spec.service_type == \"three-tier-app-demo\"\n}\n" -} -JSON -``` - -List catalog items to find the Pet Clinic offering: - -```bash -curl -s http://localhost:8080/api/v1alpha1/catalog-items | jq . -``` - -> **Note:** Look for a catalog item with a `display_name` that indicates a Pet Clinic service. Note its `uid` value. - -Create a catalog item instance: - -```bash -curl -sS -X POST http://localhost:8080/api/v1alpha1/catalog-item-instances \ - -H "Content-Type: application/json" \ - -d '{ - "api_version": "v1alpha1", - "display_name": "my-petclinic", - "spec": { - "catalog_item_id": "pet-clinic", - "user_values": [ - { "path": "database.engine", "value": "postgres" }, - { "path": "database.version", "value": "18" } - ] - } -}' -``` - -> **Note:** Catalog Manager only applies `user_values` whose `path` matches an **editable** field on -> that catalog item. For the seeded Pet Clinic offering (`pet-clinic`), only **`database.engine`** -> and **`database.version`** are editable; app and web images use the catalog defaults. - -### 3. Verify the Pet Clinic application is running - -Monitor the Pet Clinic deployment in Kubernetes: - -```bash -kubectl get pods -n default -``` - -Wait for the Pet Clinic pod(s) to reach `Running` status. - -Find the services: - -```bash -kubectl get svc -n default -``` - -The **web** tier is a Service whose name ends with `-web` (HTTP). On Kind, that Service is usually **ClusterIP** only, so your browser cannot reach it directly from the host. Forward a local port to it (adjust the service name and ports to match `kubectl get svc`; web often uses port **80**): - -```bash -kubectl port-forward -n default svc/-web 8080:80 -``` - -Then open **http://localhost:8080** in a browser. -Use **Ctrl+C** in the terminal to stop forwarding. - -## Troubleshooting - -### The three-tier SP fails to start - -If **`compose up`** errors or a container exits, inspect: - -```bash -podman compose --profile three-tier ps -podman ps -a --format "{{.Names}}\t{{.Status}}" | grep -i three-tier -podman compose --profile three-tier logs --tail=80 three-tier-demo-service-provider -podman compose --profile three-tier logs --tail=80 k8s-container-service-provider -``` - -Then check logs for a specific container name if needed: - -```bash -podman logs -``` - -Common issues: - -- **Kubeconfig not mounted correctly:** Verify `K8S_CONTAINER_SP_KUBECONFIG` is set and the file exists. -- **k8s-container-service-provider not running:** Ensure the k8s-container-service-provider is healthy. -- **NATS or Postgres not ready:** Check that `nats` and `postgres` services are running. - -### Pet Clinic pod fails to start - -Check the pod events: - -```bash -kubectl describe pod -n default -``` - -Check logs: - -```bash -kubectl logs -n default -``` - -### Typical errors and causes - -| Problem | Cause | -|---|---| -| `policy response missing selected provider` | No enabled Policy Manager policy sets `selected_provider`, or the value does not match a registered provider `name`. Add the policy in step **2**. | -| `provider '…' is not in ready state (not_ready)` | Service Provider Manager periodically GETs `{endpoint}/health`. If that fails repeatedly, the provider becomes `not_ready` and SPRM rejects provisioning. Ensure the three-tier process responds with 2xx on that path (the demo SP redirects `/health` to `/api/v1alpha1/health`), then wait for the next health check cycle or restart the stack. Verify with `GET /api/v1alpha1/providers` and `health_status: "ready"`. | -| Three-tier SP cannot provision apps without k8s-container-service-provider | The three-tier SP is a high-level orchestration layer that delegates resource provisioning to a k8s-container-service-provider | -| App is unreachable from the host | Kind often exposes the web Service as ClusterIP only. Use `kubectl port-forward` to the **`-web`** Service (step **3**). | -| Deployment hangs or fails | Missing environment variables or unhealthy dependencies (NATS, Postgres, k8s-container-service-provider) | From e7eba692efab63da6682404672cff01c789430bc Mon Sep 17 00:00:00 2001 From: Jennifer Ubah Date: Wed, 23 Sep 2026 10:27:48 -0400 Subject: [PATCH 4/5] Remove dead code, duplicates + new field Assisted-By: Cursor AI Signed-off-by: Jennifer Ubah --- deploy/.env.example | 26 +++----------------------- deploy/RUN.md | 1 + 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/deploy/.env.example b/deploy/.env.example index fc91e69..f740a5c 100644 --- a/deploy/.env.example +++ b/deploy/.env.example @@ -18,27 +18,8 @@ DB_PASSWORD=adminpass # AUTH_JWT_AUDIENCE=dcm-api # DCM_ADMIN_SUBJECT=56deb662-4820-5d83-b828-f4beb11a5fa7 -# === Optional knobs (image versions, SP profiles, ...) === -# CONTROL_PLANE_VERSION=main -# KUBEVIRT_SERVICE_PROVIDER_VERSION=main -# K8S_CONTAINER_SERVICE_PROVIDER_VERSION=main -# K8S_STORAGE_SERVICE_PROVIDER_VERSION=main -# ACM_CLUSTER_SERVICE_PROVIDER_VERSION=main -# THREE_TIER_DEMO_SERVICE_PROVIDER_VERSION=main -# DCM_UI_VERSION=main - -# ACM cluster service provider (profile: acm-cluster) -# ACM_CLUSTER_SP_PULL_SECRET= -# ACM_CLUSTER_SP_NAME=acm-cluster-sp -# ACM_CLUSTER_SP_BASE_DOMAIN=apps.example.com -# ACM_CLUSTER_SP_NAMESPACE=default -# ACM_CLUSTER_SP_KUBECONFIG=~/.kube/config -# ACM_CLUSTER_SP_DEFAULT_INFRA_ENV= -# ACM_CLUSTER_SP_AGENT_NAMESPACE= -# See compose.override.example.yaml for OpenShift route exposure on three-tier SP - -# Environment agent (profile: environment-agent) — required when using the agent profile -# See deploy/docs/environment-agent-kind.md +# === Environment agent (profile: environment-agent) === +# Required when using the agent profile. See deploy/docs/environment-agent-kind.md # AGENT_NAME=local-agent # AGENT_EMBEDDED_SPS=container,vm # required; compose has no default (e.g. container, vm, cluster, storage) # AGENT_KUBECONFIG_HOST=.kube/config # written by make kubeconfig-for-compose @@ -51,9 +32,8 @@ DB_PASSWORD=adminpass # SP_STORAGE_NAMESPACE=default # SP_K8S_DEFAULT_STORAGE_CLASS= # SP_K8S_DEFAULT_ACCESS_MODE=ReadWriteOnce -# ENVIRONMENT_AGENT_VERSION=main -# --- Service image versions --- +# === Service image versions === # Pin specific versions instead of "main". Valid values: # main - most recent main build (default) # v0.0.1 - final release (from git tag) diff --git a/deploy/RUN.md b/deploy/RUN.md index 1911c1b..fe081c5 100644 --- a/deploy/RUN.md +++ b/deploy/RUN.md @@ -180,6 +180,7 @@ Database, auth, and ACM pull-secret credentials are defined in `deploy/.env.exam | `AGENT_PORT` | `8081` | Host port for environment-agent HTTP API | | `AGENT_EMBEDDED_SPS` | _(empty)_ | **Required in `deploy/.env`** when using the agent profile. Comma-separated: `container`, `vm`, `cluster`, `storage` | | `AGENT_KUBECONFIG_HOST` | `~/.kube/config` | Host kubeconfig bind mount; use `.kube/config` in `deploy/.env` with Kind (`make kubeconfig-for-compose`) | +| `SP_DEFAULT_KUBECONFIG` | `/kubeconfig` | In-container kubeconfig path for embedded SPs (set in `compose.yaml`; do not set in `.env`) | | `SP_CONTAINER_NAMESPACE` | `default` | Container SP workload namespace (environment-agent) | | `SP_K8S_EXTERNAL_SVC_TYPE` | `NodePort` | Container SP external service type (environment-agent) | | `SP_VM_NAMESPACE` | `default` | VM SP workload namespace (environment-agent) | From 5ac7812808a7f7fe768441c48bc5941fb69706f7 Mon Sep 17 00:00:00 2001 From: Jennifer Ubah Date: Wed, 23 Sep 2026 10:32:13 -0400 Subject: [PATCH 5/5] Update docs Assisted-By: Cursor AI Signed-off-by: Jennifer Ubah --- Makefile | 1 - README.md | 2 +- deploy/RUN.md | 2 +- deploy/compose.yaml | 2 +- deploy/docs/environment-agent-kind.md | 11 +++-------- 5 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 2cb61ce..6f57921 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,6 @@ COMPOSE_ENV_FILE := deploy/.env COMPOSE_DEPLOY := $(COMPOSE) --env-file $(COMPOSE_ENV_FILE) -f $(COMPOSE_FILE) COMPOSE_PROJECT_NAME ?= control-plane COMPOSE_NETWORK := $(COMPOSE_PROJECT_NAME)_default -PROFILES ?= AUTH ?= UTILITIES_DIR ?= ../utilities KIND_SCRIPTS_DIR ?= $(UTILITIES_DIR)/scripts/kind diff --git a/README.md b/README.md index b96ba85..851de45 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ make compose-down # stop stack and remove volumes Compose credentials live in `deploy/.env` (copy from `deploy/.env.example`). Keycloak uses the `auth` compose profile — `make compose-up AUTH=true` after uncommenting the auth block -in `.env`. With providers: `make compose-up-with-providers PROFILES=kubevirt AUTH=true`. +in `.env`. With the environment-agent: `make compose-up-with-agent AUTH=true`. Subsystem tests use the shared `test/subsystem/.env.example` file. Policy evaluation and placement provisioning run in-process in the monolith diff --git a/deploy/RUN.md b/deploy/RUN.md index fe081c5..161e232 100644 --- a/deploy/RUN.md +++ b/deploy/RUN.md @@ -75,7 +75,7 @@ make compose-up AUTH=true Auth credentials live only in `deploy/.env` (see `deploy/.env.example`). Keycloak does not start with `make compose-up`; pass `AUTH=true` when auth is enabled in `.env`. -With service providers: `make compose-up-with-providers PROFILES=kubevirt AUTH=true`. +With the environment-agent: `make compose-up-with-agent AUTH=true`. For Helm chart installs, create the `dcm-auth` Secret and set `auth.enabled=true` — see [helm/dcm/README.md](helm/dcm/README.md#authentication). diff --git a/deploy/compose.yaml b/deploy/compose.yaml index 471036c..409f9e5 100644 --- a/deploy/compose.yaml +++ b/deploy/compose.yaml @@ -4,7 +4,7 @@ # Local dev: `make compose-up` builds control-plane from the repo Containerfile. # # Credentials: copy deploy/.env.example to deploy/.env before starting (see deploy/RUN.md). -# Keycloak uses profile "auth" — pass AUTH=true to make compose-up / compose-up-with-providers. +# Keycloak uses profile "auth" — pass AUTH=true to make compose-up / compose-up-with-agent. x-db-common: &db-common DB_TYPE: pgsql diff --git a/deploy/docs/environment-agent-kind.md b/deploy/docs/environment-agent-kind.md index 40f5501..725331f 100644 --- a/deploy/docs/environment-agent-kind.md +++ b/deploy/docs/environment-agent-kind.md @@ -75,15 +75,10 @@ make kind-connect KIND_SCRIPTS_DIR=/path/to/utilities/scripts/kind ### 5. Configure the agent -**Required:** set `AGENT_EMBEDDED_SPS` in `deploy/.env`. Compose does not default this — an unset -value means no embedded service providers. +**Required:** set `AGENT_EMBEDDED_SPS` in `deploy/.env` (created in step 3). There is no default value +and an unset value means no embedded service providers. -```bash -AGENT_EMBEDDED_SPS=container -AGENT_KUBECONFIG_HOST=.kube/config -``` - -Add `vm`, `cluster`, or `storage` as needed (e.g. `container,vm`). Run `make install-kubevirt` +Add `vm`, `cluster`, `container` or `storage` as needed (e.g. `container,vm`). Run `make install-kubevirt` when `vm` is included. ### 6. Start the agent (`compose-up-with-agent`)