Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
06b80db
WIP
akafazov Dec 3, 2025
cf29510
feat: enhance configuration documentation with detailed environment v…
akafazov Dec 3, 2025
318ee8a
sub(deployment): implement remote deployment
akafazov Dec 5, 2025
288c33b
fix(deployment): replace clientDeploy with clientPlatformMesh for KCP…
akafazov Dec 5, 2025
03ba251
feat(kcp): always connect to kcp on external endpoint
akafazov Dec 8, 2025
34e2f30
Update .gitignore
akafazov Dec 9, 2025
4bd15af
fix(e2e): improve kubeconfig handling in Kind cluster setup
akafazov Dec 9, 2025
a6c4047
fix(test): remove unused variable in createKindCluster function
akafazov Dec 9, 2025
d997d9f
fix(config): add exposure settings for baseDomain and protocol in pla…
akafazov Dec 9, 2025
bd0dce3
fix(task): standardize test timeout using TEST_TIMEOUT variable in Ta…
akafazov Dec 9, 2025
780a1e5
fix(providersecret): enhance KCP host handling for external and inter…
akafazov Dec 9, 2025
70c326e
fix(lint): subroutine mock
akafazov Dec 9, 2025
78b4d87
fix(tests): refactor Test_updateOciRepo_CreateOrUpdateError to use cl…
akafazov Dec 9, 2025
342b9ff
fix(tests): refactor tests to use clientMock directly in subroutine t…
akafazov Dec 9, 2025
fea7319
feat: refactor and improve configuration
akafazov Dec 11, 2025
f759850
fix(tests): subroutines
akafazov Dec 12, 2025
6f80a32
fix: pass Kubernetes client to PlatformMesh reconciler
akafazov Dec 12, 2025
05dad44
Refactor operator to replace pm-components and pm-infra-components ch…
akafazov Dec 21, 2025
b6c0d4e
refactor(config): update struct definitions for subroutines and impro…
akafazov Dec 21, 2025
c2da616
refactor(subroutines): streamline Helm release update logic and enhan…
akafazov Dec 21, 2025
64206e0
feat(docker): add gotemplates to Dockerfile and update client handlin…
akafazov Dec 27, 2025
e5dfb1d
fix(ocm): change in upstream repo
akafazov Dec 27, 2025
dc88d8b
fix(operator): handle Infra client creation error
akafazov Dec 27, 2025
52e0c1d
feat(profile): introduce unified profile configuration for PlatformMesh
akafazov Dec 27, 2025
9cf2cee
update CRD
akafazov Dec 29, 2025
64145ac
code refactoring
akafazov Dec 29, 2025
d6038e1
fix(e2e-test): add profile configuration to test
akafazov Dec 29, 2025
7d48eef
refactor(defaults): update HelmRelease configurations and improve tem…
akafazov Dec 29, 2025
05babb9
fix(wait): configure to wait for helmreleases using label
akafazov Dec 29, 2025
f692a91
fix profile and value precendence when applying manifests
akafazov Dec 29, 2025
fa29677
fix e2e test
akafazov Dec 30, 2025
b85a92c
fix tests and update README
akafazov Dec 30, 2025
47774ac
fix issue with removed configuration not being removed from the helmr…
akafazov Dec 30, 2025
eec4226
enhance test for Helm release spec merging to validate removal of non…
akafazov Dec 30, 2025
1dd7892
Implement Server-Side Apply for HelmReleases to enhance field merging…
akafazov Dec 30, 2025
2adeb18
refactor(subroutines):
akafazov Dec 31, 2025
268055b
remove CRD installation configuration from gateway API kustomization …
akafazov Dec 31, 2025
1cd930d
fix(unittests)
akafazov Jan 2, 2026
bebe8ea
feat(merge): remove complex merge logic
akafazov Jan 2, 2026
b64f666
fix(coderabbitai): resolve issues detenced by ai
akafazov Jan 4, 2026
809072d
refactor(deployment):
akafazov Jan 5, 2026
b602cae
refactor(subroutines): implement Server-Side Apply for various resources
akafazov Jan 5, 2026
5823ac5
feat(profile): enable gateway API in default profile configuration
akafazov Jan 5, 2026
7ddb6a2
Merge remote-tracking branch 'origin/main' into feat/remote-deployment
akafazov Jan 5, 2026
7a052a5
chore: update CRD and remove some logs
akafazov Jan 5, 2026
1c08ec0
fix: log error when applying OCM manifests in SetupSuite
akafazov Jan 5, 2026
e652dc0
feat(test): do not apply Repository resources unless CRD is available
akafazov Jan 5, 2026
6f5e92c
WIP
akafazov Jan 9, 2026
d0044a7
WIP - wdf
akafazov Jan 25, 2026
99f7227
feat: enhance ResourceType with additional fields for status checking
akafazov Jan 26, 2026
77e1d01
remove crossplane and add image resources
akafazov Jan 27, 2026
55ecd6c
Merge remote-tracking branch 'origin/main' into feat/remote-deploymen…
akafazov Jan 27, 2026
576cc34
feat: update HelmRelease targetNamespace and add KCP URL configuration
akafazov Jan 31, 2026
49a14c1
Merge remote-tracking branch 'origin/main' into feat/remote-deploymen…
akafazov Feb 1, 2026
7c9a663
fix lint
akafazov Feb 1, 2026
e60e84a
chore(sync):
akafazov Feb 2, 2026
5f53157
increase test coverage
akafazov Feb 2, 2026
eaa3c2a
Merge remote-tracking branch 'origin/main' into feat/remote-deploymen…
akafazov Feb 2, 2026
54e9383
WIP
akafazov Feb 6, 2026
5c3b7b3
feat: introduce ImageVersionStore to prevent DeploymentSubroutine fro…
akafazov Feb 20, 2026
72490ff
Merge remote-tracking branch 'origin/main' into feat/remote-deploymen…
akafazov Feb 24, 2026
cd35846
feat: enhance deployment technology retrieval and update logic in Res…
akafazov Feb 24, 2026
ff825d2
fix: correct resource names and improve error handling in various sub…
akafazov Feb 25, 2026
0a4019d
fix e2e tests
akafazov Feb 25, 2026
8ac3022
chore(test): improve test coverage in subroutines
akafazov Feb 25, 2026
8a19749
Merge remote-tracking branch 'origin/main' into feat/remote-deploymen…
akafazov Feb 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,7 @@ test/e2e/kind/certs/
*.key
**/__debug_bin*
gha-logs.txt
*.kubeconfig
debug
.cursor/*
test/e2e/kind/kind-testcluster.kubeconfig
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ ENV USER_UID=1001
ENV GROUP_UID=1001
COPY --from=builder --chown=${USER_UID}:${GROUP_UID} /workspace/manager /operator/manager
COPY --from=builder --chown=${USER_UID}:${GROUP_UID} /workspace/manifests /operator/manifests

COPY --chown=${USER_UID}:${GROUP_UID} gotemplates/ /operator/gotemplates
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify build context includes gotemplates and check for .dockerignore
echo "=== Checking for .dockerignore ==="
find . -name ".dockerignore" -type f

echo "=== Checking .dockerignore content for gotemplates ==="
if [ -f .dockerignore ]; then
  cat -n .dockerignore
fi

echo "=== Checking if gotemplates directory exists ==="
ls -la gotemplates/ 2>&1 || echo "gotemplates/ not found"

echo "=== Checking Dockerfile content ==="
cat -n Dockerfile

Repository: platform-mesh/platform-mesh-operator

Length of output: 2145


🌐 Web query:

Docker FROM scratch COPY build context

💡 Result:

  • FROM scratch means your final stage starts from an empty image (no shell, no package manager). You typically only use COPY/ADD plus metadata instructions (like CMD, ENTRYPOINT, ENV). (docs.docker.com)
  • COPY <src> <dest> can only copy files that are in the build context you pass to docker build (e.g., docker build . makes . the context). COPY/ADD source paths are resolved relative to the context root, not relative to where the Dockerfile lives. (docs.docker.com)
  • You can’t do COPY ../something ... to pull files from outside the build context (it’s blocked for security). (docker.com)

Common pattern (multi-stage build): build in one stage, copy into scratch:

FROM golang:1.25 AS build
WORKDIR /src
COPY . .
RUN go build -o /bin/app ./...

FROM scratch
COPY --from=build /bin/app /bin/app
CMD ["/bin/app"]

This copies from a previous stage (--from=build), not from your host filesystem. (docs.docker.com)

If you truly need files from outside the main context: with BuildKit/buildx you can pass additional named build contexts and then COPY --from=<name> .... (docker.com)

Citations:


Fix COPY instruction: line 37 will fail in FROM scratch stage without --from=builder.

The COPY --chown=${USER_UID}:${GROUP_UID} gotemplates/ /operator/gotemplates instruction cannot access the build context in a FROM scratch stage. Additionally, gotemplates/ is not copied into the builder stage, so it is unavailable even with --from=builder.

Add gotemplates/ to the builder stage and use --from=builder to copy it into the final image:

Required fix
COPY manifests/ manifests/

+COPY gotemplates/ gotemplates/
# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} go build -ldflags '-w -s' -o manager main.go

FROM scratch
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

ENV USER_UID=1001
ENV GROUP_UID=1001
COPY --from=builder --chown=${USER_UID}:${GROUP_UID} /workspace/manager /operator/manager
COPY --from=builder --chown=${USER_UID}:${GROUP_UID} /workspace/manifests /operator/manifests
-COPY --chown=${USER_UID}:${GROUP_UID} gotemplates/ /operator/gotemplates
+COPY --from=builder --chown=${USER_UID}:${GROUP_UID} /workspace/gotemplates /operator/gotemplates
🤖 Prompt for AI Agents
In `@Dockerfile` at line 37, The COPY instruction using "COPY
--chown=${USER_UID}:${GROUP_UID} gotemplates/ /operator/gotemplates" will fail
in the final "FROM scratch" stage because gotemplates/ isn't present there; add
gotemplates/ to the builder stage (ensure it's copied into the builder image
during the builder stage) and then update the final-stage COPY to pull from the
builder using the --from=builder flag (e.g., COPY --from=builder
--chown=${USER_UID}:${GROUP_UID} gotemplates/ /operator/gotemplates) so the
files and ownership are available in the final image.

USER ${USER_UID}:${GROUP_UID}
ENTRYPOINT ["/operator/manager"]
171 changes: 159 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ kind: PlatformMesh
metadata:
name: platform-mesh-sample
namespace: platform-mesh-system
spec:iam-service
spec:
exposure:
baseDomain: example.com
port: 443
Expand Down Expand Up @@ -50,6 +50,104 @@ spec:iam-service
enabled: false
```

## platform-mesh-operator Configuration

The platform-mesh-operator can be configured using environment variables or command-line parameters to control its behavior, cluster interactions, and subroutine execution. Command-line parameters use kebab-case format (e.g., `--workspace-dir`, `--kcp-url`) corresponding to the mapstructure tags in the configuration.


### General Configuration

| Variable | Description | Default |
|----------|-------------|---------|
| `KUBECONFIG` | Path to the kubeconfig file for the cluster where the `PlatformMesh` resource is reconciled | In-cluster configuration |
| `WORKSPACE_DIR` | Working directory for operator files and temporary data | `/operator/` |
| `PATCH_OIDC_CONTROLLER_ENABLED` | Enable the OIDC controller patching functionality | `false` |
| `LEADER_ELECTION_ID` | Leader election ID for the main manager instance | `81924e50.platform-mesh.org` |

### KCP Configuration

| Variable | Description | Default |
|----------|-------------|---------|
| `KCP_URL` | URL of the KCP API server | (required) |
| `KCP_NAMESPACE` | Namespace where KCP components are deployed | `platform-mesh-system` |
| `KCP_ROOT_SHARD_NAME` | Name of the KCP root shard | `root` |
| `KCP_FRONT_PROXY_NAME` | Name of the KCP front proxy component | `frontproxy` |
| `KCP_FRONT_PROXY_PORT` | Port for the KCP front proxy | `6443` |
| `KCP_CLUSTER_ADMIN_SECRET_NAME` | Name of the secret containing KCP cluster admin client certificate | `kcp-cluster-admin-client-cert` |

### Subroutines Configuration

#### Deployment Subroutine

| Variable | Description | Default |
|----------|-------------|---------|
| `SUBROUTINES_DEPLOYMENT_ENABLED` | Enable the deployment subroutine | `true` |
| `AUTHORIZATION_WEBHOOK_SECRET_NAME` | Name of the authorization webhook secret | `kcp-webhook-secret` |
| `AUTHORIZATION_WEBHOOK_SECRET_CA_NAME` | Name of the authorization webhook CA certificate | `rebac-authz-webhook-cert` |
| `SUBROUTINES_DEPLOYMENT_ENABLE_ISTIO` | Enable Istio integration in deployment subroutine | `true` |

#### KCP Setup Subroutine

| Variable | Description | Default |
|----------|-------------|---------|
| `SUBROUTINES_KCP_SETUP_ENABLED` | Enable the KCP setup subroutine | `true` |

#### Provider Secret Subroutine

| Variable | Description | Default |
|----------|-------------|---------|
| `SUBROUTINES_PROVIDER_SECRET_ENABLED` | Enable the provider secret subroutine | `true` |

#### Patch OIDC Subroutine

| Variable | Description | Default |
|----------|-------------|---------|
| `SUBROUTINES_PATCH_OIDC_CONFIGMAP_NAME` | Name of the OIDC authentication ConfigMap | `oidc-authentication-config` |
| `SUBROUTINES_PATCH_OIDC_NAMESPACE` | Namespace for OIDC configuration | `platform-mesh-system` |
| `SUBROUTINES_PATCH_OIDC_BASEDOMAIN` | Base domain for OIDC configuration | `portal.dev.local:8443` |
| `SUBROUTINES_PATCH_OIDC_DOMAIN_CA_LOOKUP` | Enable domain CA lookup for OIDC | `false` |

#### Feature Toggles Subroutine

| Variable | Description | Default |
|----------|-------------|---------|
| `SUBROUTINES_FEATURE_TOGGLES_ENABLED` | Enable the feature toggles subroutine | `false` |

#### Resource Subroutine

| Variable | Description | Default |
|----------|-------------|---------|
| `SUBROUTINES_RESOURCE_ENABLED` | Enable the resource subroutine | `true` |

#### Wait Subroutine

| Variable | Description | Default |
|----------|-------------|---------|
| `SUBROUTINES_WAIT_ENABLED` | Enable the wait subroutine | `true` |

### Remote Infrastructure Configuration

| Variable | Description | Default |
|----------|-------------|---------|
| `REMOTE_INFRA_ENABLED` | Enable reconciliation of infrastructure resources on a remote cluster | `false` |
| `REMOTE_INFRA_KUBECONFIG` | Path to the kubeconfig for remote infrastructure cluster | `/operator/infra-kubeconfig` |

### Remote Runtime Configuration

| Variable | Description | Default |
|----------|-------------|---------|
| `REMOTE_RUNTIME_ENABLED` | Enable reconciliation of PlatformMesh resource on a remote runtime cluster | `false` |
| `REMOTE_RUNTIME_KUBECONFIG` | Path to the kubeconfig for remote runtime cluster | `/operator/runtime-kubeconfig` |
| `REMOTE_RUNTIME_INFRA_SECRET_NAME` | Name of the secret containing infra kubeconfig in the remote runtime cluster | `infra-kubeconfig` |
| `REMOTE_RUNTIME_INFRA_SECRET_KEY` | Key in the secret containing infra kubeconfig in the remote runtime cluster | `kubeconfig` |

### Configuration Notes

- **Configuration methods**: All parameters can be set via environment variables (using underscore-separated uppercase names) or command-line flags (using kebab-case format, e.g., `--kcp-url`, `--workspace-dir`).
- **In-cluster behavior**: When running the operator inside a Kubernetes cluster without `KUBECONFIG` or `DEPLOYMENT_KUBECONFIG` set, it will use the in-cluster service account credentials.
- **Remote deployment**: Setting `DEPLOYMENT_KUBECONFIG` enables scenarios where the control plane (operator) runs in one cluster while deploying components to another cluster.
- **Subroutine control**: Individual subroutines can be disabled by setting their respective `_ENABLED` variables to `false`, allowing fine-grained control over operator behavior.
Comment on lines +146 to +149
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Docs still reference DEPLOYMENT_KUBECONFIG.
The configuration section defines REMOTE_INFRA_KUBECONFIG / REMOTE_RUNTIME_KUBECONFIG, so the notes should align to avoid confusion.

📝 Suggested update
- - **In-cluster behavior**: When running the operator inside a Kubernetes cluster without `KUBECONFIG` or `DEPLOYMENT_KUBECONFIG` set, it will use the in-cluster service account credentials.
- - **Remote deployment**: Setting `DEPLOYMENT_KUBECONFIG` enables scenarios where the control plane (operator) runs in one cluster while deploying components to another cluster.
+ - **In-cluster behavior**: When running the operator inside a Kubernetes cluster without `KUBECONFIG` set, it will use the in-cluster service account credentials.
+ - **Remote deployment**: Setting `REMOTE_INFRA_KUBECONFIG` (and/or `REMOTE_RUNTIME_KUBECONFIG`) enables scenarios where the control plane (operator) runs in one cluster while deploying components to another cluster.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **Configuration methods**: All parameters can be set via environment variables (using underscore-separated uppercase names) or command-line flags (using kebab-case format, e.g., `--kcp-url`, `--workspace-dir`).
- **In-cluster behavior**: When running the operator inside a Kubernetes cluster without `KUBECONFIG` or `DEPLOYMENT_KUBECONFIG` set, it will use the in-cluster service account credentials.
- **Remote deployment**: Setting `DEPLOYMENT_KUBECONFIG` enables scenarios where the control plane (operator) runs in one cluster while deploying components to another cluster.
- **Subroutine control**: Individual subroutines can be disabled by setting their respective `_ENABLED` variables to `false`, allowing fine-grained control over operator behavior.
- **Configuration methods**: All parameters can be set via environment variables (using underscore-separated uppercase names) or command-line flags (using kebab-case format, e.g., `--kcp-url`, `--workspace-dir`).
- **In-cluster behavior**: When running the operator inside a Kubernetes cluster without `KUBECONFIG` set, it will use the in-cluster service account credentials.
- **Remote deployment**: Setting `REMOTE_INFRA_KUBECONFIG` (and/or `REMOTE_RUNTIME_KUBECONFIG`) enables scenarios where the control plane (operator) runs in one cluster while deploying components to another cluster.
- **Subroutine control**: Individual subroutines can be disabled by setting their respective `_ENABLED` variables to `false`, allowing fine-grained control over operator behavior.
🤖 Prompt for AI Agents
In `@README.md` around lines 146 - 149, The README still mentions
DEPLOYMENT_KUBECONFIG; update those sentences to reference the actual env vars
used in the codebase—REMOTE_INFRA_KUBECONFIG and REMOTE_RUNTIME_KUBECONFIG—so
docs match configuration; specifically change the “In-cluster behavior” and
“Remote deployment” bullets to explain that when those REMOTE_* vars are unset
the operator uses in-cluster credentials and that setting
REMOTE_INFRA_KUBECONFIG / REMOTE_RUNTIME_KUBECONFIG enables deploying to a
remote cluster.


## PlatformMesh Resource Configuration

The `PlatformMesh` resource provides a comprehensive way to configure your platform-mesh environment. Below is a detailed explanation of each section and field available in the resource specification:
Expand Down Expand Up @@ -149,7 +247,58 @@ spec:
key2: value2
```

Those values are passed 1-1 to the `platform-mesh-operator-components` chart, deployed by the "Deployment" subroutine.
Those values are passed 1-1 to the chart deployed by the "Deployment" subroutine.

### Profile Configuration

The deployment profile controls the configuration of infrastructure and component deployments. The profile is stored in a ConfigMap and can be customized per PlatformMesh instance.

#### Default Profile

If no custom profile is specified, the operator automatically creates a default ConfigMap named `<platform-mesh-name>-profile` in the same namespace as the PlatformMesh resource. This default ConfigMap contains a unified profile with two sections:

- **infra**: Infrastructure components configuration (gateway-api, traefik, cert-manager, etc.)
- **components**: Runtime components configuration (account-operator, security-operator, keycloak, etc.)

#### Custom Profile

You can specify a custom profile ConfigMap by referencing it in the PlatformMesh spec:

```yaml
spec:
profileConfigMap:
name: my-custom-profile
namespace: platform-mesh-system # Optional, defaults to PlatformMesh namespace
```

The ConfigMap must contain a key `profile.yaml` with the unified profile structure:

```yaml
infra:
ocm:
skipVerify: true
interval: 3m
gatewayApi:
enabled: true
name: gateway-api
traefik:
enabled: true
targetNamespace: default
# ... other infra configuration

components:
targetNamespace: platform-mesh-system
protocol: https
port: 443
services:
account-operator:
enabled: true
values:
# ... service configuration
# ... other services
```

The profile structure matches the original `profile-infra.yaml` and `profile-components.yaml` files, now unified into a single structure with `infra` and `components` sections.

### Feature Toggles

Expand Down Expand Up @@ -198,9 +347,10 @@ The platform-mesh-operator processes the PlatformMesh resource through several s

The Deployment subroutine manages the deployment of platform-mesh components across the cluster:

- Merges custom values from the `PlatformMesh` resource with default configurations.
- Applies templated manifests for `platform-mesh-operator-infra-components` and waits for the HelmRelease to become ready and also for `cert-manager` to become ready.
- Applies templated Kubernetes manifests for `platform-mesh-operator-components`, including `Resource` and `HelmRelease` objects.
- Loads deployment profiles from ConfigMap (or creates a default one if not specified).
- Merges custom values from the `PlatformMesh` resource with profile configurations.
- Applies templated manifests and waits for the HelmRelease to become ready and also for `cert-manager` to become ready.
- Applies templated Kubernetes manifests, including `Resource` and `HelmRelease` objects.
- Manages OCM (Open Component Model) integration by configuring resources based on repository, component, and reference path settings.
- Manages authorization webhook secrets by creating an issuer, a certificate, and a KCP webhook secret, and keeps the secret updated with the correct CA bundle.
- Waits for the `istio-istiod` Helm release to become ready.
Expand All @@ -209,13 +359,10 @@ The Deployment subroutine manages the deployment of platform-mesh components acr

#### Merging of custom values in `DeploymentSubroutine`

When creating the `platform-mesh-operator-infra-components` and `platform-mesh-operator-components` helmreleases, their configuration is derived the from **PlatformMesh** resource as follows:

- HelmRelease `platform-mesh-operator-infra-components` has `spec.values` which is equal to the `PlatformMesh.Spec.Values` after replacing templated values.
- Resource `platform-mesh-operator-infra-components` `spec.componentRef` is set to point to `PlatformMesh.Spec.OCM.Component.Name`
When creating helmreleases, their configuration is derived from the **PlatformMesh** resource as follows:

- HelmRelease `platform-mesh-operator-components` has `spec.values.services` which is equal to the `PlatformMesh.Spec.Values` after replacing templated values.
- Resource `platform-mesh-operator-components` `spec.componentRef` is set to point to `PlatformMesh.Spec.OCM.Component.Name`
- HelmRelease has `spec.values` which is equal to the `PlatformMesh.Spec.Values` after replacing templated values.
- Resource `spec.componentRef` is set to point to `PlatformMesh.Spec.OCM.Component.Name`

For both HelmReleases the spec.values are populated with these templated fields:
- baseDomain
Expand Down Expand Up @@ -264,7 +411,7 @@ The Wait subroutine ensures that specified resources are ready before proceeding
- Waits for resources to match specific conditions (e.g., HelmRelease resources with Ready condition)
- Uses configurable wait criteria defined in the `spec.wait` section of the PlatformMesh resource
- Falls back to default wait configurations when no custom wait configuration is specified
- By default, waits for `platform-mesh-operator-components` and `platform-mesh-operator-infra-components` HelmRelease resources to be ready
- By default, waits for HelmRelease resources to be ready
- Supports filtering resources by namespace, labels, and API versions
- Requeues the reconciliation if any monitored resource is not yet ready

Expand Down
9 changes: 5 additions & 4 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ vars:
GOOS:
sh: go env GOOS
KUSTOMIZE: "{{.LOCAL_BIN}}/kustomize"
TEST_TIMEOUT: 15m
tasks:
## Setup
setup:mockery:
Expand Down Expand Up @@ -71,7 +72,7 @@ tasks:
cmds:
- |
export PATH=$(pwd)/{{.LOCAL_BIN}}:$PATH
go test -timeout 10m -coverprofile=cover.out github.com/platform-mesh/platform-mesh-operator/test/e2e/kind {{.ADDITIONAL_COMMAND_ARGS}}
go test -timeout {{.TEST_TIMEOUT}} -coverprofile=cover.out github.com/platform-mesh/platform-mesh-operator/test/e2e/kind {{.ADDITIONAL_COMMAND_ARGS}}


test:
Expand All @@ -82,15 +83,16 @@ tasks:
- cmd: |
if [ "$GITHUB_WORKFLOW" = "ci" ]; then
echo "Running tests in Github Actions"
PATH=$(pwd)/{{.LOCAL_BIN}}:$PATH go test -timeout 10m -coverprofile=cover.out ./... {{.ADDITIONAL_COMMAND_ARGS}} || {
echo "127.0.0.1 portal.dev.local kcp.api.portal.dev.local" | sudo tee -a /etc/hosts
PATH=$(pwd)/{{.LOCAL_BIN}}:$PATH go test -timeout {{.TEST_TIMEOUT}} -coverprofile=cover.out ./... {{.ADDITIONAL_COMMAND_ARGS}} || {
echo "---Listing HelmReleases"
kubectl get helmreleases -A
# ...
exit 1
}
else
export PATH=$(pwd)/{{.LOCAL_BIN}}:$PATH
go test -timeout 10m -coverprofile=cover.out ./... {{.ADDITIONAL_COMMAND_ARGS}}
go test -timeout {{.TEST_TIMEOUT}} -coverprofile=cover.out ./... {{.ADDITIONAL_COMMAND_ARGS}}
fi
ignore_error: false

Expand Down Expand Up @@ -164,7 +166,6 @@ tasks:
- kubernetes-graphql-gateway
- openfga
- observability
- crossplane
- istiod
- istio-gateway
- istio-base
Expand Down
74 changes: 51 additions & 23 deletions api/v1alpha1/platformmesh_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,58 @@ import (

// PlatformMeshSpec defines the desired state of PlatformMesh
type PlatformMeshSpec struct {
Exposure *ExposureConfig `json:"exposure,omitempty"`
Kcp Kcp `json:"kcp,omitempty"`
Values apiextensionsv1.JSON `json:"values,omitempty"`
OCM *OCMConfig `json:"ocm,omitempty"`
FeatureToggles []FeatureToggle `json:"featureToggles,omitempty"`
InfraValues apiextensionsv1.JSON `json:"infraValues,omitempty"`
Wait *WaitConfig `json:"wait,omitempty"`
Exposure *ExposureConfig `json:"exposure,omitempty"`
Kcp Kcp `json:"kcp,omitempty"`
Values apiextensionsv1.JSON `json:"values,omitempty"`
OCM *OCMConfig `json:"ocm,omitempty"`
FeatureToggles []FeatureToggle `json:"featureToggles,omitempty"`
InfraValues apiextensionsv1.JSON `json:"infraValues,omitempty"`
Wait *WaitConfig `json:"wait,omitempty"`
ProfileConfigMap *ConfigMapReference `json:"profileConfigMap,omitempty"`
}

// ConfigMapReference references a ConfigMap by name and optional namespace.
// If namespace is not specified, it defaults to the PlatformMesh resource's namespace.
type ConfigMapReference struct {
// Name is the name of the ConfigMap.
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`
// Namespace is the namespace of the ConfigMap. If not specified, defaults to the PlatformMesh resource's namespace.
// +optional
Namespace string `json:"namespace,omitempty"`
}

type WaitConfig struct {
ResourceTypes []ResourceType `json:"resourceTypes,omitempty"` // e.g., apps/v1/Deployment, core/v1/
}

type ResourceType struct {
metav1.APIVersions `json:",inline"`
metav1.GroupKind `json:",inline"`
Name string `json:"name,omitempty"`
Namespace string `json:"namespace,omitempty"`
metav1.LabelSelector `json:",inline,omitempty"`
metav1.ConditionStatus `json:"conditionStatus,omitempty"` // e.g., "True"
metav1.RowConditionType `json:"conditionType,omitempty"` // e.g., "Ready"
// Versions are the API versions to check (e.g., ["v1", "v1alpha1"]).
Versions []string `json:"versions,omitempty"`
// Group is the API group (e.g., "argoproj.io").
Group string `json:"group,omitempty"`
// Kind is the resource kind (e.g., "Application").
Kind string `json:"kind,omitempty"`
// Name is the specific resource name to check. If empty, uses LabelSelector.
Name string `json:"name,omitempty"`
// Namespace is the namespace to search in.
Namespace string `json:"namespace,omitempty"`
// LabelSelector filters resources by labels when Name is not specified.
metav1.LabelSelector `json:",inline,omitempty"`
// ConditionStatus is the expected condition status (e.g., "True").
ConditionStatus metav1.ConditionStatus `json:"conditionStatus,omitempty"`
// ConditionType is the condition type to check (e.g., "Ready").
ConditionType string `json:"conditionType,omitempty"`
// StatusFieldPath specifies a path to a nested status field to check instead of conditions.
// When set, StatusValue is required and ConditionType/ConditionStatus are ignored.
// Example: ["status", "sync", "status"] for ArgoCD Application sync status.
// +optional
StatusFieldPath []string `json:"statusFieldPath,omitempty"`
// StatusValue is the expected value at the StatusFieldPath.
// Required when StatusFieldPath is set.
// Example: "Synced" for ArgoCD Application sync status.
// +optional
StatusValue string `json:"statusValue,omitempty"`
}
type FeatureToggle struct {
Name string `json:"name,omitempty"`
Expand Down Expand Up @@ -160,15 +191,12 @@ type KcpWorkspace struct {

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:JSONPath=".status.conditions[?(@.type=='KcpsetupSubroutine_Ready')].status",name="KCP",type=string,description="KCP status (shows reason if Unknown)",priority=0
// +kubebuilder:printcolumn:JSONPath=".status.conditions[?(@.type=='KcpsetupSubroutine_Ready')].reason",name="KCP_REASON",type=string,description="KCP reason if status is Unknown",priority=1
// +kubebuilder:printcolumn:JSONPath=".status.conditions[?(@.type=='ProvidersecretSubroutine_Ready')].status",name="SECRET",type=string,description="Provider Secret status (shows reason if Unknown)",priority=0
// +kubebuilder:printcolumn:JSONPath=".status.conditions[?(@.type=='ProvidersecretSubroutine_Ready')].reason",name="SECRET_REASON",type=string,description="Provider Secret reason if status is Unknown",priority=1
// +kubebuilder:printcolumn:JSONPath=".status.conditions[?(@.type=='DeploymentSubroutine_Ready')].status",name="DEPLOYMENT",type=string,description="Deployment status (shows reason if Unknown)",priority=0
// +kubebuilder:printcolumn:JSONPath=".status.conditions[?(@.type=='DeploymentSubroutine_Ready')].reason",name="DEPLOYMENT_REASON",type=string,description="Deployment reason if status is Unknown",priority=1
// +kubebuilder:printcolumn:JSONPath=".status.conditions[?(@.type=='WaitSubroutine_Ready')].status",name="WAIT",type=string,description="Wait status (shows reason if Unknown)",priority=0
// +kubebuilder:printcolumn:JSONPath=".status.conditions[?(@.type=='WaitSubroutine_Ready')].reason",name="WAIT_REASON",type=string,description="Wait reason if status is Unknown",priority=1
// +kubebuilder:printcolumn:JSONPath=".status.conditions[?(@.type=='Ready')].status",name="Ready",type=string,description="Shows if resource is ready",priority=0
// +kubebuilder:printcolumn:name="DEPLOYMENT",type=string,jsonPath=".status.conditions[?(@.type=='DeploymentSubroutine_Ready')].status",description="Deployment status (shows reason if Unknown)",priority=0
// +kubebuilder:printcolumn:name="KCP",type=string,jsonPath=".status.conditions[?(@.type=='KcpsetupSubroutine_Ready')].status",description="KCP status (shows reason if Unknown)",priority=0
// +kubebuilder:printcolumn:name="SECRET",type=string,jsonPath=".status.conditions[?(@.type=='ProvidersecretSubroutine_Ready')].status",description="Provider Secret status (shows reason if Unknown)",priority=0
// +kubebuilder:printcolumn:name="FEATURES",type=string,jsonPath=".status.conditions[?(@.type=='FeatureToggleSubroutine_Ready')].status",description="Feature toggles' status (shows reason if Unknown)",priority=0
// +kubebuilder:printcolumn:name="WAIT",type=string,jsonPath=".status.conditions[?(@.type=='WaitSubroutine_Ready')].status",description="Wait status (shows reason if Unknown)",priority=0
// +kubebuilder:printcolumn:name="Ready",type=string,jsonPath=".status.conditions[?(@.type=='Ready')].status",description="Shows if resource is ready",priority=0

// PlatformMesh is the Schema for the platform-mesh API
type PlatformMesh struct {
Expand Down
Loading
Loading