Skip to content
Open
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ Creates the main OpenStack custom resource that defines the overall OpenStack de

#### Key resources

* **OpenStack CR:** Primary configuration object in `openstack-operators` namespace
* **OpenStack CR:** Primary configuration object in `openstack-operators` namespace
* **Example overlay:** [`example/openstack-operator-cr/`](example/openstack-operator-cr/)

### openstack-networks

Expand Down
8 changes: 8 additions & 0 deletions components/utilities/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Utilities

Shared Kustomize `Component` helpers for GitOps overlays. Add new utilities as subdirectories
here (each subdirectory should contain a `kustomization.yaml` with `kind: Component`).

| Component | Role |
| --------- | ---- |
| [approve-installplan](./approve-installplan/) | RBAC, `Job`, and Subscription sync-wave patch for Manual OLM InstallPlan approval (OpenStack operator subscription from `architecture` `olm-openstack-subscriptions`). |
27 changes: 27 additions & 0 deletions components/utilities/approve-installplan/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# approve-installplan

Kustomize `Component` that adds:

- `ClusterRole` / `ClusterRoleBinding` so the OpenShift GitOps Argo CD application controller can patch `InstallPlan` objects and read related OpenStack APIs used by the Job script.
- `Job` `approve-openstack-installplan` (sync-wave `1`) that approves a Manual InstallPlan and waits for operator install.
- JSON6902 patch on `Subscription` named `openstack` (sync-wave `0`), matching
[`architecture` `olm-openstack-subscriptions`](https://github.com/openstack-k8s-operators/architecture/tree/main/lib/olm-openstack-subscriptions).

## Usage

List this directory under `components` **after** the overlay that emits the `Subscription` (for
example the remote `lib/olm-openstack-subscriptions/overlays/default` component). If this component
runs first, the Subscription sync-wave patch will not apply.

```yaml
components:
- pin-version
- https://github.com/openstack-k8s-operators/architecture/lib/olm-openstack-subscriptions/overlays/default?ref=COMMIT_SHA
- https://github.com/openstack-k8s-operators/gitops/components/utilities/approve-installplan?ref=v0.1.0
```

Images: `registry.redhat.io/openshift4/ose-tools-rhel9:latest` (Job).

In-tree overlays may reference this component with a local path until a release tag that contains
`components/utilities/approve-installplan` is published; use the HTTPS URL above for reproducible
builds outside the repository.
160 changes: 160 additions & 0 deletions components/utilities/approve-installplan/job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
---
apiVersion: batch/v1
kind: Job
metadata:
name: approve-openstack-installplan
namespace: openshift-gitops
annotations:
argocd.argoproj.io/sync-wave: "1"
spec:
backoffLimit: 1
template:
spec:
containers:
- name: installplan-approver
image: registry.redhat.io/openshift4/ose-tools-rhel9:latest
env:
- name: OS_OPERATORS_NAMESPACE
value: "openstack-operators"
- name: OS_NAMESPACE
value: "openstack"
- name: RETRIES
value: "30"
- name: DELAY
value: "10"
- name: INSTALL_PLAN_RETRIES
value: "60"
- name: DEBUG
value: "true"
command:
- /bin/bash
- -c
- |
set -eo pipefail
if [ "${DEBUG}" = "true" ]; then
set -x
fi
# --- Configuration with defaults ---
# Namespace where the OpenStack operators are installed.
OS_OPERATORS_NAMESPACE=${OS_OPERATORS_NAMESPACE:-"openstack-operators"}
# Namespace where the OpenStack control plane is deployed and the OpenStackVersion CR exists.
OS_NAMESPACE=${OS_NAMESPACE:-"openstack"}
# Default number of retries for most checks.
RETRIES=${RETRIES:-60}
# Number of retries specifically for waiting for the InstallPlan to complete.
# This is longer because pulling operator images and starting pods can take a significant amount of time.
INSTALL_PLAN_RETRIES=${INSTALL_PLAN_RETRIES:-60}
# Delay in seconds between retries.
DELAY=${DELAY:-10}
# ---

log() {
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) $@" >&2
}

find_and_approve_installplan() {
log "Waiting for unapproved InstallPlan..."
for i in $(seq 1 $RETRIES); do
install_plan_name=$(oc get installplan -n $OS_OPERATORS_NAMESPACE -o json | jq -r '.items[] | select(.spec.approval=="Manual" and .spec.approved==false) | .metadata.name' | head -n1) || true
[ -n "$install_plan_name" ] && break
log "Attempt $i/$RETRIES: No InstallPlan found, retrying..."
sleep $DELAY
done

if [ -z "$install_plan_name" ]; then
log "Error: No manual InstallPlan found to approve within the time limit."
exit 1
fi

log "Found InstallPlan: $install_plan_name, approving..."
oc patch installplan $install_plan_name -n $OS_OPERATORS_NAMESPACE --type merge -p '{"spec":{"approved":true}}' >&2
echo "$install_plan_name"
}

wait_for_installplan_completion() {
local install_plan_name=$1
for i in $(seq 1 $INSTALL_PLAN_RETRIES); do
phase=$(oc get installplan $install_plan_name -n $OS_OPERATORS_NAMESPACE -o jsonpath='{.status.phase}')
if [ "$phase" == "Complete" ]; then
log "InstallPlan completed successfully."
return 0
fi
if [ $i -eq $INSTALL_PLAN_RETRIES ]; then
log "Error: InstallPlan did not complete in time."
exit 1
fi
log "Attempt $i/$INSTALL_PLAN_RETRIES: Status is $phase, retrying..."
sleep $DELAY
done
}

wait_for_crd() {
log "Waiting for OpenStack CRD to become available..."
for i in $(seq 1 $RETRIES); do
if oc get crd openstacks.operator.openstack.org -o jsonpath='{.status.conditions[?(@.type=="Established")].status}' | grep -q True; then
log "OpenStack CRD is Established."
return 0
fi
if [ $i -eq $RETRIES ]; then
log "Error: OpenStack CRD did not become Established in time."
exit 1
fi
log "Attempt $i/$RETRIES: CRD not Established, retrying..."
sleep $DELAY
done
}

wait_for_new_version() {
log "Waiting for a new OpenStack version to become available..."

local deployed_version=""
for i in $(seq 1 $RETRIES); do
# There should be only one openstackversion CR
deployed_version=$(oc get openstackversion -n $OS_NAMESPACE -o jsonpath='{.items[0].status.deployedVersion}' 2>/dev/null) || true
if [ -n "$deployed_version" ]; then
log "Current deployed version is: $deployed_version"
break
fi
if [ $i -eq $RETRIES ]; then
log "Error: Could not get current deployed version in time."
exit 1
fi
log "Attempt $i/$RETRIES: Waiting for OpenStackVersion resource to get deployedVersion. Retrying..."
sleep $DELAY
done

for i in $(seq 1 $RETRIES); do
available_version=$(oc get openstackversion -n $OS_NAMESPACE -o jsonpath='{.items[0].status.availableVersion}' 2>/dev/null) || true
if [ -n "$available_version" ] && [ "$available_version" != "$deployed_version" ]; then
log "New available version found: $available_version"
return 0
fi
if [ $i -eq $RETRIES ]; then
log "Error: New version did not become available in time."
exit 1
fi
log "Attempt $i/$RETRIES: No new version available yet. Current available is '$available_version'. Retrying..."
sleep $DELAY
done
}

# --- Main execution ---
log "Starting install_plan_approval"
install_plan_name=$(find_and_approve_installplan)

log "Waiting for InstallPlan '$install_plan_name' to complete..."

wait_for_installplan_completion "$install_plan_name"

log "Checking if this is an initial installation or an update..."
if oc get openstack openstack -n $OS_OPERATORS_NAMESPACE; then
log "OpenStack CR 'openstack' exists. This is an update."
wait_for_new_version
else
log "OpenStack CR 'openstack' does not exist. This is an initial installation."
wait_for_crd
fi

log "Job completed successfully."
restartPolicy: Never
serviceAccountName: openshift-gitops-argocd-application-controller
16 changes: 16 additions & 0 deletions components/utilities/approve-installplan/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
# Apply this component after the Subscription exists in the build (e.g. after
# openstack-k8s-operators/architecture lib/olm-openstack-subscriptions).
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
resources:
- job.yaml
- rbac.yaml
patches:
- target:
kind: Subscription
name: openstack
patch: |-
- op: add
path: /metadata/annotations/argocd.argoproj.io~1sync-wave
value: "0"
51 changes: 51 additions & 0 deletions components/utilities/approve-installplan/rbac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
# ClusterRole and binding so the OpenShift GitOps Argo CD application controller
# can approve OLM InstallPlans and read resources used by the approval Job.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: installplan-approver-role
rules:
- apiGroups:
- operators.coreos.com
resources:
- installplans
verbs:
- get
- list
- patch
- apiGroups:
- operator.openstack.org
resources:
- openstacks
verbs:
- get
- list
- apiGroups:
- core.openstack.org
resources:
- openstackversions
verbs:
- get
- list
- patch
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- get
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: installplan-approver-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: installplan-approver-role
subjects:
- kind: ServiceAccount
name: openshift-gitops-argocd-application-controller
namespace: openshift-gitops
4 changes: 2 additions & 2 deletions example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ where the overlay includes `components/argocd/annotations`).

| Directory | Role |
| --------- | ---- |
| [openstack-operator](./openstack-operator/) | Foundational OpenStack operators, namespaces, subscription, install-plan approval (placeholder until a component exists). |
| [openstack-operator-cr](./openstack-operator-cr/) | Main OpenStack custom resource (placeholder until a component exists). |
| [openstack-operator](./openstack-operator/) | Foundational OpenStack operators: CDN catalog + pinned CSV, OLM subscription from `architecture` `olm-openstack-subscriptions`, InstallPlan approval Job, RBAC. |
| [openstack-operator-cr](./openstack-operator-cr/) | Main `OpenStack` custom resource in `openstack-operators`. |
| [openstack-networks](./openstack-networks/) | Underlying networks: NNCP, NAD, NetConfig, MetalLB pools / advertisements, etc. |
| [openstack-controlplane](./openstack-controlplane/) | `OpenStackControlPlane` and optional watcher service (networking is a separate overlay). |
| [openstack-dataplane](./openstack-dataplane/) | Data plane node set and deployment. |
Expand Down
25 changes: 19 additions & 6 deletions example/openstack-operator-cr/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
# openstack-operator-cr

Placeholder overlay for the **openstack-operator-cr** application described in the root
`README.md` (*Application responsibilities and content*).
Example overlay for the **openstack-operator-cr** application described in the root
`README.md` under *Application responsibilities and content*.

There is no matching component under `components/rhoso/` yet. Replace this directory's
`kustomization.yaml` with real `components` / `resources` when a slice is added.
This directory applies a minimal **OpenStack** custom resource in the
`openstack-operators` namespace. It is the primary configuration object for the overall
OpenStack deployment on the cluster (see product documentation for full `spec` options).

Upstream context: main OpenStack custom resource in the `openstack-operators`
namespace.
## Render

From this directory:

```shell
kustomize build .
```

## Layout

| File | Role |
| ---- | ---- |
| `openstack.yaml` | `OpenStack` CR (`operator.openstack.org/v1beta1`) |
| `kustomization.yaml` | Sets namespace and includes the CR |
11 changes: 3 additions & 8 deletions example/openstack-operator-cr/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources: []
namespace: openstack-operators

# No gitops component yet for this slice. See README.md.
# Future: add components (remote refs and local paths), for example:
# components:
# - https://github.com/openstack-k8s-operators/gitops/components/argocd/annotations?ref=TAG
# - https://github.com/openstack-k8s-operators/gitops/components/rhoso/...?ref=TAG
# Local paths (for "kustomize build" testing):
# - ../../components/argocd/annotations
resources:
- openstack.yaml
6 changes: 6 additions & 0 deletions example/openstack-operator-cr/openstack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
apiVersion: operator.openstack.org/v1beta1
kind: OpenStack
metadata:
name: openstack
namespace: openstack-operators
Loading
Loading