diff --git a/.env.example b/.env.example
index 787ecce..c8e2347 100644
--- a/.env.example
+++ b/.env.example
@@ -29,10 +29,7 @@
# 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)
-# PLACEMENT_MANAGER_VERSION=main
-# SERVICE_PROVIDER_MANAGER_VERSION=main
-# CATALOG_MANAGER_VERSION=main
-# POLICY_MANAGER_VERSION=main
+# CONTROL_PLANE_VERSION=main
# KUBEVIRT_SERVICE_PROVIDER_VERSION=main
# K8S_CONTAINER_SERVICE_PROVIDER_VERSION=main
# ACM_CLUSTER_SERVICE_PROVIDER_VERSION=main
diff --git a/Makefile b/Makefile
index 01d707e..860e6d3 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@ check-config:
$(ENGINE) rm -f gateway-validate > /dev/null 2>&1 || \
{ echo "Config validation failed:"; $(ENGINE) logs gateway-validate 2>&1; $(ENGINE) rm -f gateway-validate > /dev/null 2>&1; exit 1; }
-# Run full stack (gateway + managers) via Compose. Pulls images and starts the stack.
+# Run full stack (gateway + control-plane) via Compose. Pulls images and starts the stack.
run:
$(ENGINE) compose up -d
diff --git a/README.md b/README.md
index 32b9a83..e356e47 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ Central clearing house for the DCM control plane: single entry point (ingress) a
## Overview
-- **Ingress:** Clients and frontends send REST requests to the gateway; the gateway routes them to internal managers (ServiceProviderManager, PlacementManager, PolicyManager, CatalogManager).
+- **Ingress:** Clients and frontends send REST requests to the gateway; the gateway routes them to the **control-plane** monolith (`quay.io/dcm-project/control-plane`).
- **Egress:** Outbound calls from DCM to external systems are intended to go through the gateway (see [Egress](#egress) below). Placeholders only in this deliverable.
- **Stateless:** No server-side sessions; each request is independent.
- **Auth:** Not in scope for the first deliverable; Keycloak (or another IdP) will be added later.
@@ -12,10 +12,7 @@ Central clearing house for the DCM control plane: single entry point (ingress) a
```mermaid
flowchart LR
Client --> Gateway["API Gateway
Traefik :9080"]
- Gateway --> SPM["ServiceProviderManager
service-provider-manager:8080"]
- Gateway --> Catalog["CatalogManager
catalog-manager:8080"]
- Gateway --> Policy["PolicyManager
policy-manager:8080"]
- Gateway --> Placement["PlacementManager
placement-manager:8080"]
+ Gateway --> CP["control-plane
catalog + policy + placement + SP :8080"]
```
## Running the gateway
@@ -30,7 +27,7 @@ flowchart LR
make validate-config
```
-### Run locally (gateway and managers)
+### Run locally (gateway and control-plane)
From the `api-gateway` directory, start the **default** Compose stack:
@@ -39,8 +36,8 @@ cd api-gateway
make run
```
-`make run` is equivalent to `podman compose up -d` or `docker compose up -d` (whichever engine you use).
-It starts **Traefik**, **PostgreSQL**, **NATS**, and the four **managers** (ServiceProviderManager, CatalogManager, PolicyManager, PlacementManager).
+`make run` is equivalent to `podman compose up -d` or `docker compose up -d` (whichever engine you use).
+It starts **Traefik**, **PostgreSQL**, **NATS**, and **control-plane** (monolith on `:8080`).
It does **not** start the optional **service provider** containers (`kubevirt-service-provider`, `k8s-container-service-provider`, `acm-cluster-service-provider`).
Those services are declared with [Compose profiles](https://docs.docker.com/compose/how-tos/profiles/) in `compose.yaml` (`kubevirt`, `k8s-container`, `acm-cluster`, or `providers`
@@ -53,7 +50,8 @@ The gateway is at `http://localhost:9080`. Stop with `make compose-down`. To run
### Image versions
-Each DCM manager image defaults to `:main` but can be pinned to a specific version via environment variables in `.env`.
+The control-plane image defaults to `:main` but can be pinned via `CONTROL_PLANE_VERSION` in `.env`.
+Requires [control-plane](https://github.com/dcm-project/control-plane) image on Quay (see control-plane PR for CI push).
#### Available tag formats
@@ -73,18 +71,14 @@ Browse available tags for a service at `https://quay.io/repository/dcm-project/<
Set the corresponding variable in `.env` (see `.env.example` for the full list):
```bash
-PLACEMENT_MANAGER_VERSION=v0.0.1
-CATALOG_MANAGER_VERSION=v0.0.1-rc.3
+CONTROL_PLANE_VERSION=v0.0.1
```
-Omitting a variable (or leaving it commented out) defaults to `main`.
+Omitting the variable defaults to `main`.
| Variable | Service |
|---|---|
-| `SERVICE_PROVIDER_MANAGER_VERSION` | service-provider-manager |
-| `CATALOG_MANAGER_VERSION` | catalog-manager |
-| `POLICY_MANAGER_VERSION` | policy-manager |
-| `PLACEMENT_MANAGER_VERSION` | placement-manager |
+| `CONTROL_PLANE_VERSION` | control-plane monolith |
| `KUBEVIRT_SERVICE_PROVIDER_VERSION` | kubevirt-service-provider (`kubevirt` or `providers` profile) |
| `K8S_CONTAINER_SERVICE_PROVIDER_VERSION` | k8s-container-service-provider (`k8s-container` or `providers` profile) |
| `ACM_CLUSTER_SERVICE_PROVIDER_VERSION` | acm-cluster-service-provider (`acm-cluster` or `providers` profile) |
@@ -102,11 +96,11 @@ podman compose config | grep "quay.io/dcm-project"
1. Check available tags on [quay.io/dcm-project](https://quay.io/organization/dcm-project) for the service you want to update.
2. Set the version variable in `.env`:
```bash
- PLACEMENT_MANAGER_VERSION=v0.0.1
+ CONTROL_PLANE_VERSION=v0.0.1
```
3. Restart the stack to pull the new image:
```bash
- make run # core stack (gateway + managers)
+ make run # core stack (gateway + control-plane)
make run-with-providers # or, if running with service providers
```
@@ -137,7 +131,7 @@ Then mount the ConfigMap into the Traefik pod at `/etc/traefik/traefik.yml` and
### Testing locally
-1. **Validate and start the core stack (gateway + managers)**
+1. **Validate and start the core stack (gateway + control-plane)**
```bash
make validate-config
make run
@@ -149,29 +143,27 @@ Then mount the ConfigMap into the Traefik pod at `/etc/traefik/traefik.yml` and
```bash
curl -s http://localhost:9080/ping
```
-3. **Health checks (gateway + managers)**
- After `make run`, the health endpoints only cover the four managers that are part of the default stack.
- For example: `curl -s http://localhost:9080/api/v1alpha1/health/providers`. Stop with `make compose-down`.
+3. **Health checks (gateway + control-plane)**
+ After `make run`, legacy per-domain health paths still work and map to the monolith health endpoint. For example: `curl -s http://localhost:9080/api/v1alpha1/health/providers` or `curl -s http://localhost:9080/api/v1alpha1/health`. Stop with `make compose-down`.
## Route mapping
-| Path prefix | Backend |
-|------------------------------------------|------------------------|
-| `/api/v1alpha1/health/providers` | ServiceProviderManager |
-| `/api/v1alpha1/health/catalog` | CatalogManager |
-| `/api/v1alpha1/health/policies` | PolicyManager |
-| `/api/v1alpha1/health/placement` | PlacementManager |
-| `/api/v1alpha1/providers` | ServiceProviderManager |
-| `/api/v1alpha1/service-type-instances` | ServiceProviderManager |
-| `/api/v1alpha1/service-types` | CatalogManager |
-| `/api/v1alpha1/catalog-items` | CatalogManager |
-| `/api/v1alpha1/catalog-item-instances` | CatalogManager |
-| `/api/v1alpha1/policies` | PolicyManager |
-| `/api/v1alpha1/resources` | PlacementManager |
-
-Health paths above are GET-only; other paths support multiple methods (GET, POST, PUT, PATCH, DELETE as per the API). The `catalog-item-instances` prefix also covers AEP custom methods such as `POST /api/v1alpha1/catalog-item-instances/{id}:rehydrate`. See `config/dynamic/routes.yml` for the full list.
-
-**Health:** Backend health is exposed through the gateway. Use `GET /api/v1alpha1/health/providers`, `/health/catalog`, `/health/policies`, `/health/placement` to check each manager (e.g. `curl http://localhost:9080/api/v1alpha1/health/catalog`). Traefik also exposes `GET /ping` for the gateway process only.
+| Path prefix | Backend |
+|------------------------------------------|----------------|
+| `/api/v1alpha1/health` | control-plane |
+| `/api/v1alpha1/health/providers` | control-plane |
+| `/api/v1alpha1/health/catalog` | control-plane |
+| `/api/v1alpha1/health/policies` | control-plane |
+| `/api/v1alpha1/providers` | control-plane |
+| `/api/v1alpha1/service-type-instances` | control-plane |
+| `/api/v1alpha1/service-types` | control-plane |
+| `/api/v1alpha1/catalog-items` | control-plane |
+| `/api/v1alpha1/catalog-item-instances` | control-plane |
+| `/api/v1alpha1/policies` | control-plane |
+
+Placement `/resources` and policy evaluation HTTP are **not** exposed; provisioning runs in-process inside control-plane.
+
+Health paths above are GET-only; other paths support multiple methods. The `catalog-item-instances` prefix also covers `POST ...:rehydrate`. See `config/dynamic/routes.yml` for the full list. Traefik exposes `GET /ping` for the gateway process only.
## Egress
diff --git a/RUN.md b/RUN.md
index 00df695..6df4a09 100644
--- a/RUN.md
+++ b/RUN.md
@@ -9,7 +9,7 @@
## Quick start
-Start all core services (gateway, postgres, nats, and all managers):
+Start all core services (gateway, postgres, nats, and control-plane):
```bash
make run
@@ -135,12 +135,14 @@ podman compose ps # or: docker compose ps
Check health endpoints through the gateway:
```bash
+curl http://localhost:9080/api/v1alpha1/health
curl http://localhost:9080/api/v1alpha1/health/providers
curl http://localhost:9080/api/v1alpha1/health/catalog
curl http://localhost:9080/api/v1alpha1/health/policies
-curl http://localhost:9080/api/v1alpha1/health/placement
```
+Legacy per-domain health paths map to the monolith `GET /api/v1alpha1/health`.
+
Check health endpoint through DCM UI:
```bash
@@ -173,10 +175,7 @@ make compose-down
| `ACM_CLUSTER_SP_PULL_SECRET` | _(required)_ | Base64-encoded dockerconfigjson pull secret for ACM hosted clusters |
| `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 |
-| `SERVICE_PROVIDER_MANAGER_VERSION` | `main` | Image tag for service-provider-manager |
-| `CATALOG_MANAGER_VERSION` | `main` | Image tag for catalog-manager |
-| `POLICY_MANAGER_VERSION` | `main` | Image tag for policy-manager |
-| `PLACEMENT_MANAGER_VERSION` | `main` | Image tag for placement-manager |
+| `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 |
| `ACM_CLUSTER_SERVICE_PROVIDER_VERSION` | `main` | Image tag for acm-cluster-service-provider |
diff --git a/compose.yaml b/compose.yaml
index b5eec77..1ad305d 100644
--- a/compose.yaml
+++ b/compose.yaml
@@ -1,12 +1,10 @@
-# DCM API Gateway and managers. Manager images are pulled from quay.io/dcm-project.
+# DCM API Gateway and control-plane monolith. Image from quay.io/dcm-project/control-plane.
#
-# Image versions: each manager defaults to :main. Pin specific versions by
-# setting _VERSION in .env (see .env.example).
+# Image version: defaults to :main. Pin with CONTROL_PLANE_VERSION in .env.
#
# Credentials: set POSTGRES_USER and POSTGRES_PASSWORD in the environment or in
# a .env file (see .env.example). Defaults are for local dev only.
-# Shared DB connection env (YAML anchor); services merge it with <<: *db-common and add DB_NAME.
x-db-common: &db-common
DB_TYPE: pgsql
DB_HOST: postgres
@@ -15,6 +13,8 @@ x-db-common: &db-common
DB_PASS: ${POSTGRES_PASSWORD:-adminpass}
DB_PASSWORD: ${POSTGRES_PASSWORD:-adminpass}
+x-dcm-registration-url: &dcm-registration-url "http://control-plane:8080/api/v1alpha1"
+
services:
gateway:
image: docker.io/traefik:v3.4
@@ -26,10 +26,7 @@ services:
- ./config/traefik.yml:/etc/traefik/traefik.yml:ro,z
- ./config/dynamic:/etc/traefik/dynamic:ro,z
depends_on:
- service-provider-manager: { condition: service_started }
- catalog-manager: { condition: service_started }
- policy-manager: { condition: service_started }
- placement-manager: { condition: service_started }
+ control-plane: { condition: service_started }
postgres:
image: docker.io/library/postgres:16-alpine
@@ -57,45 +54,20 @@ services:
volumes:
- nats_data:/data
- service-provider-manager:
- image: quay.io/dcm-project/service-provider-manager:${SERVICE_PROVIDER_MANAGER_VERSION:-main}
- pull_policy: always
- environment:
- <<: *db-common
- DB_NAME: service-provider
- SVC_ADDRESS: ":8080"
- NATS_URL: "nats://nats:4222"
- expose:
- - "8080"
- depends_on:
- postgres: { condition: service_healthy }
- nats: { condition: service_started }
-
- catalog-manager:
- image: quay.io/dcm-project/catalog-manager:${CATALOG_MANAGER_VERSION:-main}
- pull_policy: always
- environment:
- <<: *db-common
- BIND_ADDRESS: ":8080"
- DB_NAME: catalog-manager
- PLACEMENT_MANAGER_URL: "http://placement-manager:8080"
- expose:
- - "8080"
- depends_on:
- postgres: { condition: service_healthy }
-
- policy-manager:
- image: quay.io/dcm-project/policy-manager:${POLICY_MANAGER_VERSION:-main}
+ control-plane:
+ image: quay.io/dcm-project/control-plane:${CONTROL_PLANE_VERSION:-main}
pull_policy: always
environment:
<<: *db-common
BIND_ADDRESS: ":8080"
+ DB_NAME: control-plane
LOG_LEVEL: info
- DB_NAME: policy-manager
+ NATS_URL: "nats://nats:4222"
expose:
- "8080"
depends_on:
postgres: { condition: service_healthy }
+ nats: { condition: service_started }
kubevirt-service-provider:
container_name: ${KUBEVIRT_PROVIDER_NAME:-kubevirt-service-provider}
@@ -104,7 +76,7 @@ services:
pull_policy: always
environment:
NATS_URL: "nats://nats:4222"
- SERVICE_MANAGER_ENDPOINT: "http://service-provider-manager:8080/api/v1alpha1"
+ 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: ${KUBEVIRT_NAMESPACE:-default}
@@ -112,21 +84,7 @@ services:
volumes:
- ${KUBEVIRT_KUBECONFIG:-~/.kube/config}:/kubeconfig:ro,z
depends_on:
- service-provider-manager: { condition: service_started }
-
- placement-manager:
- image: quay.io/dcm-project/placement-manager:${PLACEMENT_MANAGER_VERSION:-main}
- pull_policy: always
- environment:
- <<: *db-common
- BIND_ADDRESS: ":8080"
- DB_NAME: placement-manager
- POLICY_MANAGER_EVALUATION_URL: "http://policy-manager:8081"
- SP_RESOURCE_MANAGER_URL: "http://service-provider-manager:8080"
- expose:
- - "8080"
- depends_on:
- postgres: { condition: service_healthy }
+ control-plane: { condition: service_started }
k8s-container-service-provider:
profiles: ["providers", "k8s-container", "three-tier"]
@@ -135,7 +93,7 @@ services:
environment:
SP_NAME: ${K8S_CONTAINER_SP_NAME:-k8s-container-provider}
SP_ENDPOINT: "http://k8s-container-service-provider:8080"
- DCM_REGISTRATION_URL: "http://service-provider-manager:8080/api/v1alpha1"
+ DCM_REGISTRATION_URL: *dcm-registration-url
SP_NATS_URL: "nats://nats:4222"
SP_K8S_NAMESPACE: ${K8S_CONTAINER_SP_NAMESPACE:-default}
SP_K8S_KUBECONFIG: /kubeconfig
@@ -145,7 +103,7 @@ services:
volumes:
- ${K8S_CONTAINER_SP_KUBECONFIG:-~/.kube/config}:/kubeconfig:ro,z
depends_on:
- service-provider-manager: { condition: service_started }
+ control-plane: { condition: service_started }
nats: { condition: service_started }
acm-cluster-service-provider:
@@ -155,13 +113,11 @@ services:
environment:
SP_NAME: ${ACM_CLUSTER_SP_NAME:-acm-cluster-sp}
SP_ENDPOINT: "http://acm-cluster-service-provider:8080"
- DCM_REGISTRATION_URL: "http://service-provider-manager:8080/api/v1alpha1"
+ 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}
- # BareMetal platform only — not used by KubeVirt.
- # Can be omitted when SP_ENABLED_PLATFORMS=kubevirt.
SP_DEFAULT_INFRA_ENV: ${ACM_CLUSTER_SP_DEFAULT_INFRA_ENV}
SP_AGENT_NAMESPACE: ${ACM_CLUSTER_SP_AGENT_NAMESPACE}
KUBECONFIG: /kubeconfig
@@ -170,7 +126,7 @@ services:
volumes:
- ${ACM_CLUSTER_SP_KUBECONFIG:-~/.kube/config}:/kubeconfig:ro,z
depends_on:
- service-provider-manager: { condition: service_started }
+ control-plane: { condition: service_started }
nats: { condition: service_started }
dcm-ui:
@@ -194,7 +150,7 @@ services:
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: "http://service-provider-manager:8080/api/v1alpha1"
+ DCM_REGISTRATION_URL: *dcm-registration-url
SP_NATS_URL: "nats://nats:4222"
SP_K8S_NAMESPACE: ${K8S_CONTAINER_SP_NAMESPACE:-default}
SP_K8S_KUBECONFIG: /kubeconfig
@@ -203,7 +159,7 @@ services:
volumes:
- ${K8S_CONTAINER_SP_KUBECONFIG:-~/.kube/config}:/kubeconfig:ro,z
depends_on:
- service-provider-manager: { condition: service_started }
+ control-plane: { condition: service_started }
nats: { condition: service_started }
k8s-container-service-provider: { condition: service_started }
postgres: { condition: service_healthy }
diff --git a/config/dynamic/routes.yml b/config/dynamic/routes.yml
index 865831f..8035f6a 100644
--- a/config/dynamic/routes.yml
+++ b/config/dynamic/routes.yml
@@ -1,96 +1,95 @@
http:
routers:
- # ── Health endpoints (GET only) ───────────────────────────────────
+ # ── Health endpoints (GET only; legacy paths → monolith /health) ──
health-providers:
rule: "Path(`/api/v1alpha1/health/providers`) && Method(`GET`)"
- service: service-provider-manager
+ service: control-plane
entryPoints: [web]
middlewares: [strip-health-suffix]
health-catalog:
rule: "Path(`/api/v1alpha1/health/catalog`) && Method(`GET`)"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
middlewares: [strip-health-suffix]
health-policies:
rule: "Path(`/api/v1alpha1/health/policies`) && Method(`GET`)"
- service: policy-manager
+ service: control-plane
entryPoints: [web]
middlewares: [strip-health-suffix]
- health-placement:
- rule: "Path(`/api/v1alpha1/health/placement`) && Method(`GET`)"
- service: placement-manager
+ health:
+ rule: "Path(`/api/v1alpha1/health`) && Method(`GET`)"
+ service: control-plane
entryPoints: [web]
- middlewares: [strip-health-suffix]
# ── ServiceProviderManager ────────────────────────────────────────
providers-collection:
rule: "Path(`/api/v1alpha1/providers`) && (Method(`GET`) || Method(`POST`))"
- service: service-provider-manager
+ service: control-plane
entryPoints: [web]
providers-resource:
rule: "PathRegexp(`^/api/v1alpha1/providers/[^/:]+$`) && (Method(`GET`) || Method(`PUT`) || Method(`DELETE`))"
- service: service-provider-manager
+ service: control-plane
entryPoints: [web]
service-type-instances-collection:
rule: "Path(`/api/v1alpha1/service-type-instances`) && Method(`GET`)"
- service: service-provider-manager
+ service: control-plane
entryPoints: [web]
service-type-instances-resource:
rule: "PathRegexp(`^/api/v1alpha1/service-type-instances/[^/:]+$`) && Method(`GET`)"
- service: service-provider-manager
+ service: control-plane
entryPoints: [web]
# ── CatalogManager ────────────────────────────────────────────────
service-types-collection:
rule: "Path(`/api/v1alpha1/service-types`) && Method(`GET`)"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
service-types-resource:
rule: "PathRegexp(`^/api/v1alpha1/service-types/[^/:]+$`) && Method(`GET`)"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
catalog-items-collection:
rule: "Path(`/api/v1alpha1/catalog-items`) && (Method(`GET`) || Method(`POST`))"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
catalog-items-resource:
rule: "PathRegexp(`^/api/v1alpha1/catalog-items/[^/:]+$`) && (Method(`GET`) || Method(`PATCH`) || Method(`DELETE`))"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
catalog-item-instances-collection:
rule: "Path(`/api/v1alpha1/catalog-item-instances`) && (Method(`GET`) || Method(`POST`))"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
catalog-item-instances-resource:
rule: "PathRegexp(`^/api/v1alpha1/catalog-item-instances/[^/:]+$`) && (Method(`GET`) || Method(`DELETE`))"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
catalog-item-instances-rehydrate:
rule: "PathRegexp(`^/api/v1alpha1/catalog-item-instances/[^/]+:rehydrate$`) && Method(`POST`)"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
# ── PolicyManager ─────────────────────────────────────────────────
policies-collection:
rule: "Path(`/api/v1alpha1/policies`) && (Method(`GET`) || Method(`POST`))"
- service: policy-manager
+ service: control-plane
entryPoints: [web]
policies-resource:
rule: "PathRegexp(`^/api/v1alpha1/policies/[^/:]+$`) && (Method(`GET`) || Method(`PATCH`) || Method(`DELETE`))"
- service: policy-manager
+ service: control-plane
entryPoints: [web]
middlewares:
@@ -100,22 +99,7 @@ http:
replacement: "/api/v1alpha1/health"
services:
- service-provider-manager:
- loadBalancer:
- servers:
- - url: "http://service-provider-manager:8080"
-
- catalog-manager:
- loadBalancer:
- servers:
- - url: "http://catalog-manager:8080"
-
- policy-manager:
- loadBalancer:
- servers:
- - url: "http://policy-manager:8080"
-
- placement-manager:
+ control-plane:
loadBalancer:
servers:
- - url: "http://placement-manager:8080"
+ - url: "http://control-plane:8080"
diff --git a/hack/postgres-init/01-create-databases.sql b/hack/postgres-init/01-create-databases.sql
index 363cb86..640b1a9 100644
--- a/hack/postgres-init/01-create-databases.sql
+++ b/hack/postgres-init/01-create-databases.sql
@@ -1,6 +1,2 @@
--- Create databases for all managers. Same approach for each; POSTGRES_DB is "postgres" (bootstrap only).
-CREATE DATABASE "service-provider";
-CREATE DATABASE "policy-manager";
-CREATE DATABASE "catalog-manager";
-CREATE DATABASE "placement-manager";
+CREATE DATABASE "control-plane";
CREATE DATABASE "three-tier-sp";
diff --git a/helm/dcm/templates/acm-cluster-service-provider.yaml b/helm/dcm/templates/acm-cluster-service-provider.yaml
index 4370723..8766345 100644
--- a/helm/dcm/templates/acm-cluster-service-provider.yaml
+++ b/helm/dcm/templates/acm-cluster-service-provider.yaml
@@ -40,7 +40,7 @@ spec:
- name: SP_ENDPOINT
value: "http://{{ include "dcm.fullname" . }}-acm-cluster-service-provider:8080"
- name: DCM_REGISTRATION_URL
- value: "http://{{ include "dcm.fullname" . }}-service-provider-manager:8080/api/v1alpha1"
+ value: "http://{{ include "dcm.fullname" . }}-control-plane:8080/api/v1alpha1"
- name: SP_NATS_URL
value: "nats://{{ include "dcm.fullname" . }}-nats:4222"
- name: SP_CLUSTER_NAMESPACE
diff --git a/helm/dcm/templates/catalog-manager.yaml b/helm/dcm/templates/catalog-manager.yaml
deleted file mode 100644
index 1a911a2..0000000
--- a/helm/dcm/templates/catalog-manager.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: {{ include "dcm.fullname" . }}-catalog-manager
- labels:
- {{- include "dcm.labels" . | nindent 4 }}
- {{- include "dcm.selectorLabels" (dict "context" . "component" "catalog-manager") | nindent 4 }}
-spec:
- replicas: 1
- selector:
- matchLabels:
- {{- include "dcm.selectorLabels" (dict "context" . "component" "catalog-manager") | nindent 6 }}
- template:
- metadata:
- labels:
- {{- include "dcm.selectorLabels" (dict "context" . "component" "catalog-manager") | nindent 8 }}
- spec:
- initContainers:
- {{- include "dcm.waitForPostgres" . | nindent 8 }}
- containers:
- - name: catalog-manager
- image: "{{ .Values.catalogManager.image }}:{{ include "dcm.imageTag" (dict "tag" .Values.catalogManager.tag "global" .Values.global) }}"
- ports:
- - containerPort: 8080
- protocol: TCP
- envFrom:
- - secretRef:
- name: {{ include "dcm.fullname" . }}-db
- env:
- - name: DB_TYPE
- value: pgsql
- - name: DB_HOST
- value: {{ include "dcm.fullname" . }}-postgres
- - name: DB_PORT
- value: "5432"
- - name: DB_NAME
- value: catalog-manager
- - name: BIND_ADDRESS
- value: ":8080"
- - name: PLACEMENT_MANAGER_URL
- value: "http://{{ include "dcm.fullname" . }}-placement-manager:8080"
----
-apiVersion: v1
-kind: Service
-metadata:
- name: {{ include "dcm.fullname" . }}-catalog-manager
- labels:
- {{- include "dcm.labels" . | nindent 4 }}
-spec:
- selector:
- {{- include "dcm.selectorLabels" (dict "context" . "component" "catalog-manager") | nindent 4 }}
- ports:
- - port: 8080
- targetPort: 8080
- protocol: TCP
diff --git a/helm/dcm/templates/policy-manager.yaml b/helm/dcm/templates/control-plane.yaml
similarity index 69%
rename from helm/dcm/templates/policy-manager.yaml
rename to helm/dcm/templates/control-plane.yaml
index fd4e13a..992e63e 100644
--- a/helm/dcm/templates/policy-manager.yaml
+++ b/helm/dcm/templates/control-plane.yaml
@@ -1,25 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
- name: {{ include "dcm.fullname" . }}-policy-manager
+ name: {{ include "dcm.fullname" . }}-control-plane
labels:
{{- include "dcm.labels" . | nindent 4 }}
- {{- include "dcm.selectorLabels" (dict "context" . "component" "policy-manager") | nindent 4 }}
+ {{- include "dcm.selectorLabels" (dict "context" . "component" "control-plane") | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
- {{- include "dcm.selectorLabels" (dict "context" . "component" "policy-manager") | nindent 6 }}
+ {{- include "dcm.selectorLabels" (dict "context" . "component" "control-plane") | nindent 6 }}
template:
metadata:
labels:
- {{- include "dcm.selectorLabels" (dict "context" . "component" "policy-manager") | nindent 8 }}
+ {{- include "dcm.selectorLabels" (dict "context" . "component" "control-plane") | nindent 8 }}
spec:
initContainers:
{{- include "dcm.waitForPostgres" . | nindent 8 }}
containers:
- - name: policy-manager
- image: "{{ .Values.policyManager.image }}:{{ include "dcm.imageTag" (dict "tag" .Values.policyManager.tag "global" .Values.global) }}"
+ - name: control-plane
+ image: "{{ .Values.controlPlane.image }}:{{ include "dcm.imageTag" (dict "tag" .Values.controlPlane.tag "global" .Values.global) }}"
ports:
- containerPort: 8080
protocol: TCP
@@ -34,21 +34,23 @@ spec:
- name: DB_PORT
value: "5432"
- name: DB_NAME
- value: policy-manager
+ value: control-plane
- name: BIND_ADDRESS
value: ":8080"
- name: LOG_LEVEL
value: info
+ - name: NATS_URL
+ value: "nats://{{ include "dcm.fullname" . }}-nats:4222"
---
apiVersion: v1
kind: Service
metadata:
- name: {{ include "dcm.fullname" . }}-policy-manager
+ name: {{ include "dcm.fullname" . }}-control-plane
labels:
{{- include "dcm.labels" . | nindent 4 }}
spec:
selector:
- {{- include "dcm.selectorLabels" (dict "context" . "component" "policy-manager") | nindent 4 }}
+ {{- include "dcm.selectorLabels" (dict "context" . "component" "control-plane") | nindent 4 }}
ports:
- port: 8080
targetPort: 8080
diff --git a/helm/dcm/templates/gateway.yaml b/helm/dcm/templates/gateway.yaml
index d56c8d1..7e439d0 100644
--- a/helm/dcm/templates/gateway.yaml
+++ b/helm/dcm/templates/gateway.yaml
@@ -29,84 +29,79 @@ data:
routes.yml: |
http:
routers:
- # -- Health endpoints (GET only)
health-providers:
rule: "Path(`/api/v1alpha1/health/providers`) && Method(`GET`)"
- service: service-provider-manager
+ service: control-plane
entryPoints: [web]
middlewares: [strip-health-suffix]
health-catalog:
rule: "Path(`/api/v1alpha1/health/catalog`) && Method(`GET`)"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
middlewares: [strip-health-suffix]
health-policies:
rule: "Path(`/api/v1alpha1/health/policies`) && Method(`GET`)"
- service: policy-manager
+ service: control-plane
entryPoints: [web]
middlewares: [strip-health-suffix]
- health-placement:
- rule: "Path(`/api/v1alpha1/health/placement`) && Method(`GET`)"
- service: placement-manager
+ health:
+ rule: "Path(`/api/v1alpha1/health`) && Method(`GET`)"
+ service: control-plane
entryPoints: [web]
- middlewares: [strip-health-suffix]
- # -- ServiceProviderManager
providers-collection:
rule: "Path(`/api/v1alpha1/providers`) && (Method(`GET`) || Method(`POST`))"
- service: service-provider-manager
+ service: control-plane
entryPoints: [web]
providers-resource:
rule: "PathRegexp(`^/api/v1alpha1/providers/[^/:]+$`) && (Method(`GET`) || Method(`PUT`) || Method(`DELETE`))"
- service: service-provider-manager
+ service: control-plane
entryPoints: [web]
service-type-instances-collection:
rule: "Path(`/api/v1alpha1/service-type-instances`) && Method(`GET`)"
- service: service-provider-manager
+ service: control-plane
entryPoints: [web]
service-type-instances-resource:
rule: "PathRegexp(`^/api/v1alpha1/service-type-instances/[^/:]+$`) && Method(`GET`)"
- service: service-provider-manager
+ service: control-plane
entryPoints: [web]
- # -- CatalogManager
service-types-collection:
rule: "Path(`/api/v1alpha1/service-types`) && Method(`GET`)"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
service-types-resource:
rule: "PathRegexp(`^/api/v1alpha1/service-types/[^/:]+$`) && Method(`GET`)"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
catalog-items-collection:
rule: "Path(`/api/v1alpha1/catalog-items`) && (Method(`GET`) || Method(`POST`))"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
catalog-items-resource:
rule: "PathRegexp(`^/api/v1alpha1/catalog-items/[^/:]+$`) && (Method(`GET`) || Method(`PATCH`) || Method(`DELETE`))"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
catalog-item-instances-collection:
rule: "Path(`/api/v1alpha1/catalog-item-instances`) && (Method(`GET`) || Method(`POST`))"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
catalog-item-instances-resource:
rule: "PathRegexp(`^/api/v1alpha1/catalog-item-instances/[^/:]+$`) && (Method(`GET`) || Method(`DELETE`))"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
catalog-item-instances-rehydrate:
rule: "PathRegexp(`^/api/v1alpha1/catalog-item-instances/[^/]+:rehydrate$`) && Method(`POST`)"
- service: catalog-manager
+ service: control-plane
entryPoints: [web]
- # -- PolicyManager
policies-collection:
rule: "Path(`/api/v1alpha1/policies`) && (Method(`GET`) || Method(`POST`))"
- service: policy-manager
+ service: control-plane
entryPoints: [web]
policies-resource:
rule: "PathRegexp(`^/api/v1alpha1/policies/[^/:]+$`) && (Method(`GET`) || Method(`PATCH`) || Method(`DELETE`))"
- service: policy-manager
+ service: control-plane
entryPoints: [web]
middlewares:
@@ -116,22 +111,10 @@ data:
replacement: "/api/v1alpha1/health"
services:
- service-provider-manager:
- loadBalancer:
- servers:
- - url: "http://{{ include "dcm.fullname" .}}-service-provider-manager:8080"
- catalog-manager:
- loadBalancer:
- servers:
- - url: "http://{{ include "dcm.fullname" .}}-catalog-manager:8080"
- policy-manager:
- loadBalancer:
- servers:
- - url: "http://{{ include "dcm.fullname" .}}-policy-manager:8080"
- placement-manager:
+ control-plane:
loadBalancer:
servers:
- - url: "http://{{ include "dcm.fullname" .}}-placement-manager:8080"
+ - url: "http://{{ include "dcm.fullname" . }}-control-plane:8080"
---
apiVersion: apps/v1
kind: Deployment
diff --git a/helm/dcm/templates/k8s-container-service-provider.yaml b/helm/dcm/templates/k8s-container-service-provider.yaml
index 0e53acb..8929eac 100644
--- a/helm/dcm/templates/k8s-container-service-provider.yaml
+++ b/helm/dcm/templates/k8s-container-service-provider.yaml
@@ -85,7 +85,7 @@ spec:
- name: SP_ENDPOINT
value: "http://{{ include "dcm.fullname" . }}-k8s-container-service-provider:8080"
- name: DCM_REGISTRATION_URL
- value: "http://{{ include "dcm.fullname" . }}-service-provider-manager:8080/api/v1alpha1"
+ value: "http://{{ include "dcm.fullname" . }}-control-plane:8080/api/v1alpha1"
- name: SP_NATS_URL
value: "nats://{{ include "dcm.fullname" . }}-nats:4222"
- name: SP_K8S_NAMESPACE
diff --git a/helm/dcm/templates/kubevirt-service-provider.yaml b/helm/dcm/templates/kubevirt-service-provider.yaml
index fd14a53..ba1acd4 100644
--- a/helm/dcm/templates/kubevirt-service-provider.yaml
+++ b/helm/dcm/templates/kubevirt-service-provider.yaml
@@ -35,7 +35,7 @@ spec:
- name: NATS_URL
value: "nats://{{ include "dcm.fullname" . }}-nats:4222"
- name: SERVICE_MANAGER_ENDPOINT
- value: "http://{{ include "dcm.fullname" . }}-service-provider-manager:8080/api/v1alpha1"
+ value: "http://{{ include "dcm.fullname" . }}-control-plane:8080/api/v1alpha1"
- name: PROVIDER_NAME
value: {{ .Values.kubevirtServiceProvider.providerName | quote }}
- name: PROVIDER_ENDPOINT
diff --git a/helm/dcm/templates/placement-manager.yaml b/helm/dcm/templates/placement-manager.yaml
deleted file mode 100644
index 9002a8b..0000000
--- a/helm/dcm/templates/placement-manager.yaml
+++ /dev/null
@@ -1,57 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: {{ include "dcm.fullname" . }}-placement-manager
- labels:
- {{- include "dcm.labels" . | nindent 4 }}
- {{- include "dcm.selectorLabels" (dict "context" . "component" "placement-manager") | nindent 4 }}
-spec:
- replicas: 1
- selector:
- matchLabels:
- {{- include "dcm.selectorLabels" (dict "context" . "component" "placement-manager") | nindent 6 }}
- template:
- metadata:
- labels:
- {{- include "dcm.selectorLabels" (dict "context" . "component" "placement-manager") | nindent 8 }}
- spec:
- initContainers:
- {{- include "dcm.waitForPostgres" . | nindent 8 }}
- containers:
- - name: placement-manager
- image: "{{ .Values.placementManager.image }}:{{ include "dcm.imageTag" (dict "tag" .Values.placementManager.tag "global" .Values.global) }}"
- ports:
- - containerPort: 8080
- protocol: TCP
- envFrom:
- - secretRef:
- name: {{ include "dcm.fullname" . }}-db
- env:
- - name: DB_TYPE
- value: pgsql
- - name: DB_HOST
- value: {{ include "dcm.fullname" . }}-postgres
- - name: DB_PORT
- value: "5432"
- - name: DB_NAME
- value: placement-manager
- - name: BIND_ADDRESS
- value: ":8080"
- - name: POLICY_MANAGER_EVALUATION_URL
- value: "http://{{ include "dcm.fullname" . }}-policy-manager:8081"
- - name: SP_RESOURCE_MANAGER_URL
- value: "http://{{ include "dcm.fullname" . }}-service-provider-manager:8080"
----
-apiVersion: v1
-kind: Service
-metadata:
- name: {{ include "dcm.fullname" . }}-placement-manager
- labels:
- {{- include "dcm.labels" . | nindent 4 }}
-spec:
- selector:
- {{- include "dcm.selectorLabels" (dict "context" . "component" "placement-manager") | nindent 4 }}
- ports:
- - port: 8080
- targetPort: 8080
- protocol: TCP
diff --git a/helm/dcm/templates/postgres.yaml b/helm/dcm/templates/postgres.yaml
index 4e18d68..f02b7d4 100644
--- a/helm/dcm/templates/postgres.yaml
+++ b/helm/dcm/templates/postgres.yaml
@@ -6,10 +6,7 @@ metadata:
{{- include "dcm.labels" . | nindent 4 }}
data:
01-create-databases.sql: |
- CREATE DATABASE "service-provider";
- CREATE DATABASE "policy-manager";
- CREATE DATABASE "catalog-manager";
- CREATE DATABASE "placement-manager";
+ CREATE DATABASE "control-plane";
CREATE DATABASE "three-tier-sp";
---
apiVersion: apps/v1
diff --git a/helm/dcm/templates/service-provider-manager.yaml b/helm/dcm/templates/service-provider-manager.yaml
deleted file mode 100644
index f226b53..0000000
--- a/helm/dcm/templates/service-provider-manager.yaml
+++ /dev/null
@@ -1,55 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: {{ include "dcm.fullname" . }}-service-provider-manager
- labels:
- {{- include "dcm.labels" . | nindent 4 }}
- {{- include "dcm.selectorLabels" (dict "context" . "component" "service-provider-manager") | nindent 4 }}
-spec:
- replicas: 1
- selector:
- matchLabels:
- {{- include "dcm.selectorLabels" (dict "context" . "component" "service-provider-manager") | nindent 6 }}
- template:
- metadata:
- labels:
- {{- include "dcm.selectorLabels" (dict "context" . "component" "service-provider-manager") | nindent 8 }}
- spec:
- initContainers:
- {{- include "dcm.waitForPostgres" . | nindent 8 }}
- containers:
- - name: service-provider-manager
- image: "{{ .Values.serviceProviderManager.image }}:{{ include "dcm.imageTag" (dict "tag" .Values.serviceProviderManager.tag "global" .Values.global) }}"
- ports:
- - containerPort: 8080
- protocol: TCP
- envFrom:
- - secretRef:
- name: {{ include "dcm.fullname" . }}-db
- env:
- - name: DB_TYPE
- value: pgsql
- - name: DB_HOST
- value: {{ include "dcm.fullname" . }}-postgres
- - name: DB_PORT
- value: "5432"
- - name: DB_NAME
- value: service-provider
- - name: SVC_ADDRESS
- value: ":8080"
- - name: NATS_URL
- value: "nats://{{ include "dcm.fullname" . }}-nats:4222"
----
-apiVersion: v1
-kind: Service
-metadata:
- name: {{ include "dcm.fullname" . }}-service-provider-manager
- labels:
- {{- include "dcm.labels" . | nindent 4 }}
-spec:
- selector:
- {{- include "dcm.selectorLabels" (dict "context" . "component" "service-provider-manager") | nindent 4 }}
- ports:
- - port: 8080
- targetPort: 8080
- protocol: TCP
diff --git a/helm/dcm/templates/three-tier-demo-service-provider.yaml b/helm/dcm/templates/three-tier-demo-service-provider.yaml
index 6c4e9e7..d16303f 100644
--- a/helm/dcm/templates/three-tier-demo-service-provider.yaml
+++ b/helm/dcm/templates/three-tier-demo-service-provider.yaml
@@ -43,7 +43,7 @@ spec:
- name: SP_ENDPOINT
value: "http://{{ include "dcm.fullname" . }}-three-tier-demo-sp:8080"
- name: DCM_REGISTRATION_URL
- value: "http://{{ include "dcm.fullname" . }}-service-provider-manager:8080/api/v1alpha1"
+ value: "http://{{ include "dcm.fullname" . }}-control-plane:8080/api/v1alpha1"
- name: SP_NATS_URL
value: "nats://{{ include "dcm.fullname" . }}-nats:4222"
- name: SP_K8S_NAMESPACE
diff --git a/helm/dcm/values.yaml b/helm/dcm/values.yaml
index d24d5cb..354c1bf 100644
--- a/helm/dcm/values.yaml
+++ b/helm/dcm/values.yaml
@@ -31,23 +31,11 @@ gateway:
# - gateway.example.com
annotations: {}
-# -- Core managers
-serviceProviderManager:
- image: quay.io/dcm-project/service-provider-manager
+# -- Control-plane monolith (catalog, policy, placement, SP manager)
+controlPlane:
+ image: quay.io/dcm-project/control-plane
tag: "" # defaults to global.imageTag
-catalogManager:
- image: quay.io/dcm-project/catalog-manager
- tag: ""
-
-policyManager:
- image: quay.io/dcm-project/policy-manager
- tag: ""
-
-placementManager:
- image: quay.io/dcm-project/placement-manager
- tag: ""
-
# -- DCM UI
dcmUi:
enabled: true