Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Instructions for AI agents working in this repository.

## What this repo is

Customer-side **OpenShift RWX storage** (Azure NetApp Files + Trident CSI), **OpenShift Virtualization**, and **CUDN BGP** (Azure Route Server + in-cluster [bgp-cloud-connector](https://github.com/openshift/bgp-cloud-connector)). Terraform provisions a NetApp-delegated subnet, ANF account and capacity pool, `RouteServerSubnet` + Route Server, and Trident/BGP identities. GitOps installs Trident, kubevirt-hyperconverged, and builds the BGP operator from [bgp-cloud-connector](https://github.com/openshift/bgp-cloud-connector) commit `2b6ad93989a2adfe4b52d4067f70a782aabd9a11` (kustomize remote + BuildConfig `ref`; bump both together). Cleanup drains BGP CRs then Trident/ANF volumes.
Customer-side **OpenShift RWX storage** (Azure NetApp Files + Trident CSI), **OpenShift Virtualization**, and **CUDN BGP** (Azure Route Server + in-cluster [bgp-cloud-connector](https://github.com/openshift/bgp-cloud-connector)). Terraform provisions a NetApp-delegated subnet, ANF account and capacity pool, `RouteServerSubnet` + Route Server, and Trident/BGP identities. GitOps installs Trident, kubevirt-hyperconverged, and builds the BGP operator from [bgp-cloud-connector](https://github.com/openshift/bgp-cloud-connector) commit `2b6ad93989a2adfe4b52d4067f70a782aabd9a11` (kustomize remote + Shipwright `Build` git `revision` + `BuildRun` name suffix; bump all three together). Cleanup drains BGP CRs then Trident/ANF volumes.

This is **not** an OpenShift cluster installer. The cluster lives in the sibling **ARO HCP** pattern: [`rh-mobb/validated-pattern-aro-hcp`](https://github.com/rh-mobb/validated-pattern-aro-hcp). Do not create an HCP cluster here. Do not add AWS/GCP providers beyond empty module stubs until those slices exist.

Expand Down
2 changes: 1 addition & 1 deletion clusters/aro-virt/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ az netappfiles volume delete -g aro-virt-rg --account-name aro-virt-anf --pool-n
| DV clone ~65% OOM | CDI ~600M | `cdiconfig` 4Gi; see CDI guide |
| `disk.img: file exists` | Partial clone after OOM | Delete DV/tmp PVCs; retry |
| Wrong tags/region | `TF_VAR_*` | Unset; same as installer A/B/C |
| `virt-stack` Forbidden (ImageStream, TridentOrchestrator, …) | GitOps controller lacks `cluster-admin` on first sync | Bootstrap pre-applies `gitops-controller-rbac.yaml`; if skipped: `oc apply -f gitops/base/gitops-controller-rbac.yaml`, sync `virt-stack` |
| `virt-stack` Forbidden (Shipwright Build, TridentOrchestrator, …) | GitOps controller lacks `cluster-admin` on first sync | Bootstrap pre-applies `gitops-controller-rbac.yaml`; if skipped: `oc apply -f gitops/base/gitops-controller-rbac.yaml`, sync `virt-stack` |
| `azure-nic-ip-forwarding` missing ConfigMap | DS applied before `bgp-from-metadata` Job (legacy `hook: Sync`) | Use current GitOps (Job sync-wave `4`); `oc apply -f gitops/operators/bgp-cloud-connector/from-metadata-job.yaml` once |

After a new live failure: add a row here. If operators would hit it, update consume.md and/or installer virt-stack troubleshooting in the same PR.
6 changes: 4 additions & 2 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ Do not add a public IP, public PaaS data plane, or internet listener without a n
| Subnet `RouteServerSubnet` | Azure-required name, **no NSG, no UDR**, CIDR from installer `route_server_subnet_prefix` (default `10.0.4.0/26`). |
| Public IP + Azure Route Server `<cluster>-routeserver` | Standard PIP (management plane exception). BGP neighbors are RFC1918 `virtualRouterIps`. Apply fails without `bgp_router=true` in `platform.json` `node_pools`. |
| UAMI `<cluster>-bgp` | Custom role: Route Server BGP connections **in the customer RG** only (no NIC write). Federated credential for `openshift-bgp-cloud-connector/openshift-bgp-cloud-connector-controller-manager`. NIC IP forwarding uses installer **`cluster-api-azure`** via `spec.azure.networkInterfaceClientID` (`platform.json` `cluster_api_azure_client_id`). Worker NICs are in the managed RG (RP deny assignment). Blast radius: the operator can act as full CAPI there. Installer [#20](https://github.com/rh-mobb/validated-pattern-aro-hcp/issues/20). |
| bgp-cloud-connector | GitOps in-cluster build from `github.com/openshift/bgp-cloud-connector` commit `2b6ad93989a2adfe4b52d4067f70a782aabd9a11` (kustomize `config/default?ref=` and BuildConfig `spec.source.git.ref`; not OLM until GA). `bgp-from-metadata` is a **sync-wave `4` Job** (not `hook: Sync`) so it finishes before wave `6` `azure-nic-ip-forwarding`. It stamps WI + `BGPCloudConfiguration` `platform: Azure` from `bgp-platform-metadata` (including `networkInterfaceClientID`). Deployment sync-wave `5` so the Job annotates the SA before manager pods admit. If the Deployment already exists (`oc apply -k` ignores waves), the Job `rollout restart`s it and waits until some pod spec has `AZURE_CLIENT_ID` (ImagePullBackOff is fine; the WI webhook only injects at create). **Temporary** DaemonSet `azure-nic-ip-forwarding` (wave 6) sets `enableIPForwarding` on **all worker NICs** so CUDN extra-hop replies from non-speakers are not dropped. Operator only does this for `bgp_router=true` today (Azure Route Server **16 peer** cap). Remove the DS when [bgp-cloud-connector#121](https://github.com/openshift/bgp-cloud-connector/issues/121) ships ([tracking #9](https://github.com/rh-mobb/validated-pattern-openshift-virt/issues/9)). Sample **`BGPRouting` `virt`** (wave 7, `gitops/samples/cudn`) creates namespace `virt` (`cluster-udn: virt`, primary-UDN label at create) and subnet `192.168.100.0/24`. The operator creates `ClusterUserDefinedNetwork` `cluster-udn-virt` and shared `RouteAdvertisements` — do not GitOps a CUDN for this path. Put VMs/pods in `virt`; jump/VNet reach the CUDN IPs, not overlay `10.128.0.0/14`. |
| bgp-cloud-connector | GitOps in-cluster build from `github.com/openshift/bgp-cloud-connector` commit `2b6ad93989a2adfe4b52d4067f70a782aabd9a11` (kustomize `config/default?ref=`, Shipwright `Build.spec.source.git.revision`, and `BuildRun` name suffix; not OLM until GA). Requires OpenShift Pipelines + Builds for OpenShift (`gitops/operators/openshift-pipelines`, `openshift-builds`). `bgp-from-metadata` is a **sync-wave `4` Job** (not `hook: Sync`) so it finishes before wave `6` `azure-nic-ip-forwarding`. It stamps WI + `BGPCloudConfiguration` `platform: Azure` from `bgp-platform-metadata` (including `networkInterfaceClientID`). Deployment sync-wave `5` so the Job annotates the SA before manager pods admit. If the Deployment already exists (`oc apply -k` ignores waves), the Job `rollout restart`s it and waits until some pod spec has `AZURE_CLIENT_ID` (ImagePullBackOff is fine; the WI webhook only injects at create). **Temporary** DaemonSet `azure-nic-ip-forwarding` (wave 6) sets `enableIPForwarding` on **all worker NICs** so CUDN extra-hop replies from non-speakers are not dropped. Operator only does this for `bgp_router=true` today (Azure Route Server **16 peer** cap). Remove the DS when [bgp-cloud-connector#121](https://github.com/openshift/bgp-cloud-connector/issues/121) ships ([tracking #9](https://github.com/rh-mobb/validated-pattern-openshift-virt/issues/9)). Sample **`BGPRouting` `virt`** (wave 7, `gitops/samples/cudn`) creates namespace `virt` (`cluster-udn: virt`, primary-UDN label at create) and subnet `192.168.100.0/24`. The operator creates `ClusterUserDefinedNetwork` `cluster-udn-virt` and shared `RouteAdvertisements` — do not GitOps a CUDN for this path. Put VMs/pods in `virt`; jump/VNet reach the CUDN IPs, not overlay `10.128.0.0/14`. |
| OpenShift Pipelines | GitOps `gitops/operators/openshift-pipelines`: prerequisite for Builds for OpenShift (`openshift-pipelines-operator`, `redhat-operators`, sync-wave `-4`). |
| Builds for OpenShift | GitOps `gitops/operators/openshift-builds`: Shipwright CRDs + `buildah` `ClusterBuildStrategy` (`openshift-builds-operator`, sync-wave `-3`). |
| NetApp account `<cluster>-anf` | Customer RG |
| Capacity pool `<cluster>-anf-pool` | Flexible, Manual QoS, default 1 TiB, `custom_throughput_mibps` 128. Trident backend must set `defaults.qosType: Manual` (not `serviceLevel: Flexible` — Trident only accepts Standard/Premium/Ultra) and `networkFeatures: Standard` (pools under 4 TiB reject Basic; snapshot clones of Basic golden images fail with `VolumesInSub4TiBPoolsCannotUseBasicNetworking`). |
| Trident operator | Certified `trident-operator`; OperatorGroup is **AllNamespaces** (OwnNamespace is unsupported). `TridentOrchestrator` `cloudProvider: Azure` plus `cloudIdentity` for workload identity. |
| OpenShift Virtualization | GitOps `gitops/operators/cnv`: `kubevirt-hyperconverged` from `redhat-operators` (`stable`) into `openshift-cnv`. HyperConverged `infra`/`workloads` nodePlacement is worker-only (HCP has no masters). Job patches StorageProfile `anf-virt` to RWX Filesystem for live migration. StorageClass annotation `storageclass.kubevirt.io/is-default-virt-class` — cluster default StorageClass stays `managed-csi`. |
| GitOps controller | `gitops/base/gitops-controller-rbac.yaml` binds OpenShift `cluster-admin` to `openshift-gitops-argocd-application-controller` (`virt-stack-gitops-controller`, sync-wave `-1` inside `virt-stack`). `scripts/gitops-bootstrap.sh` also `oc apply`s it **before** planting the Application so the first sync can create ImageStreams and operators. Default OpenShift GitOps is get/list/watch plus a few API groups — not enough for this overlay. The installer baseline keeps the limited controller (ESO ignores ServiceAccount drift). |
| GitOps controller | `gitops/base/gitops-controller-rbac.yaml` binds OpenShift `cluster-admin` to `openshift-gitops-argocd-application-controller` (`virt-stack-gitops-controller`, sync-wave `-1` inside `virt-stack`). `scripts/gitops-bootstrap.sh` also `oc apply`s it **before** planting the Application so the first sync can create operator Subscriptions, Shipwright Builds, and Trident resources. Default OpenShift GitOps is get/list/watch plus a few API groups — not enough for this overlay. The installer baseline keeps the limited controller (ESO ignores ServiceAccount drift). |
| `trident-from-metadata` Job | Namespaced Role in `trident` for ServiceAccounts / `TridentBackendConfig`. **ClusterRole** for cluster-scoped `TridentOrchestrator` and `get` on CRDs (the Job `oc get crd` / `oc patch tridentorchestrator`). |
| UAMI `<cluster>-trident` | Custom role on the RG; federated credential for `trident/trident-controller` |

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/consume.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ make cluster.aro-virt.bootstrap

Destroy reverse: `make cluster.aro-virt.destroy` here (BGP CR drain + ANF cleanup then terraform; leftover ANF volumes block the pool — delete them and retry). Then installer destroy.

GitOps: `make cluster.aro-virt.bootstrap` pre-applies `virt-stack-gitops-controller` (`cluster-admin` on `openshift-gitops-argocd-application-controller`) before the `virt-stack` Application — the binding also stays at sync-wave `-1` inside that App. Metadata Jobs (`trident-from-metadata`, `bgp-from-metadata`) are **sync-wave `4` resources**, not `hook: Sync` hooks, so wave `6` (`azure-nic-ip-forwarding`) waits for the Job ConfigMap. The Trident Job uses a ClusterRole for cluster-scoped `TridentOrchestrator` and CRD `get`. BGP operator is an in-cluster build of [bgp-cloud-connector](https://github.com/openshift/bgp-cloud-connector) pinned to commit `2b6ad93989a2adfe4b52d4067f70a782aabd9a11` (`gitops/operators/bgp-cloud-connector` kustomize `config/default?ref=` and BuildConfig `spec.source.git.ref` must stay in lockstep); `bgp-from-metadata` stamps workload identity (sibling BGP MI) and `BGPCloudConfiguration` including `networkInterfaceClientID` (installer `cluster-api-azure`). Sample `BGPRouting` `virt` (`192.168.100.0/24`, namespace `virt`) is in `gitops/samples/cudn`; the operator creates the CUDN. Same Argo CD instance as the installer `cluster-config` Application.
GitOps: `make cluster.aro-virt.bootstrap` pre-applies `virt-stack-gitops-controller` (`cluster-admin` on `openshift-gitops-argocd-application-controller`) before the `virt-stack` Application — the binding also stays at sync-wave `-1` inside that App. Metadata Jobs (`trident-from-metadata`, `bgp-from-metadata`) are **sync-wave `4` resources**, not `hook: Sync` hooks, so wave `6` (`azure-nic-ip-forwarding`) waits for the Job ConfigMap. The Trident Job uses a ClusterRole for cluster-scoped `TridentOrchestrator` and CRD `get`. BGP operator is an in-cluster Shipwright build of [bgp-cloud-connector](https://github.com/openshift/bgp-cloud-connector) pinned to commit `2b6ad93989a2adfe4b52d4067f70a782aabd9a11` (`gitops/operators/bgp-cloud-connector` kustomize `config/default?ref=`, `Build.spec.source.git.revision`, and `BuildRun` name suffix must stay in lockstep; virt-stack also installs OpenShift Pipelines + Builds for OpenShift); `bgp-from-metadata` stamps workload identity (sibling BGP MI) and `BGPCloudConfiguration` including `networkInterfaceClientID` (installer `cluster-api-azure`). Sample `BGPRouting` `virt` (`192.168.100.0/24`, namespace `virt`) is in `gitops/samples/cudn`; the operator creates the CUDN. Same Argo CD instance as the installer `cluster-config` Application.

## In-tree module

Expand Down
2 changes: 2 additions & 0 deletions gitops/base/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gitops-controller-rbac.yaml
- ../operators/openshift-pipelines
- ../operators/openshift-builds
- ../operators/trident
- ../operators/cnv
- ../operators/bgp-cloud-connector
Expand Down
26 changes: 20 additions & 6 deletions gitops/operators/bgp-cloud-connector/build-rbac.yaml
Original file line number Diff line number Diff line change
@@ -1,34 +1,48 @@
# OpenShift docker Strategy builds need a builder SA and privileged SCC.
# Shipwright buildah BuildRun: push to internal registry + privileged build pods.
apiVersion: v1
kind: ServiceAccount
metadata:
name: builder
name: shipwright-build
namespace: openshift-bgp-cloud-connector
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: builder-image-builder
name: shipwright-build-registry
namespace: openshift-bgp-cloud-connector
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:registry
subjects:
- kind: ServiceAccount
name: shipwright-build
namespace: openshift-bgp-cloud-connector
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: shipwright-build-image-builder
namespace: openshift-bgp-cloud-connector
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:image-builder
subjects:
- kind: ServiceAccount
name: builder
name: shipwright-build
namespace: openshift-bgp-cloud-connector
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: builder-privileged
name: shipwright-build-privileged
namespace: openshift-bgp-cloud-connector
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:openshift:scc:privileged
subjects:
- kind: ServiceAccount
name: builder
name: shipwright-build
namespace: openshift-bgp-cloud-connector
32 changes: 32 additions & 0 deletions gitops/operators/bgp-cloud-connector/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apiVersion: shipwright.io/v1beta1
kind: Build
metadata:
name: operator
namespace: openshift-bgp-cloud-connector
annotations:
argocd.argoproj.io/sync-wave: "-2"
argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true
spec:
source:
type: Git
git:
url: https://github.com/openshift/bgp-cloud-connector.git
# Same SHA as kustomization.yaml config/default?ref= (not floating main).
revision: 2b6ad93989a2adfe4b52d4067f70a782aabd9a11
strategy:
# Namespace BuildStrategy: CBS buildah defaults to 1 CPU / 2Gi; FIPS go build needs more.
kind: BuildStrategy
name: buildah-heavy
paramValues:
- name: dockerfile
value: Dockerfile
output:
image: image-registry.openshift-image-registry.svc:5000/openshift-bgp-cloud-connector/operator:dev
volumes:
- name: service-ca
configMap:
name: service-ca-bundle
retention:
succeededLimit: 3
failedLimit: 3
timeout: 60m
37 changes: 0 additions & 37 deletions gitops/operators/bgp-cloud-connector/buildconfig.yaml

This file was deleted.

13 changes: 13 additions & 0 deletions gitops/operators/bgp-cloud-connector/buildrun.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: shipwright.io/v1beta1
kind: BuildRun
metadata:
name: operator-2b6ad939
namespace: openshift-bgp-cloud-connector
annotations:
argocd.argoproj.io/sync-wave: "-1"
argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true
spec:
build:
name: operator
serviceAccount: shipwright-build
timeout: 60m
Loading
Loading