From 740e3662391c2217f25b427b6e413a0133ba3592 Mon Sep 17 00:00:00 2001 From: Ilan Zuckerman Date: Mon, 27 Jul 2026 10:23:37 +0300 Subject: [PATCH] Fix RouterInterface status when Router is not Available When a Router exists but is not yet Available, the routerinterface controller returned early without writing RouterInterface status, leaving .status empty and hard to diagnose. Mirror the NotFound path: update dependent RouterInterfaces with WaitingOnObject(..., WaitingOnReady) so status shows they are waiting for the Router to be ready. Add a KUTTL test covering this scenario. Fixes #838 --- .../controllers/routerinterface/reconcile.go | 29 +++++++++++++- .../00-assert.yaml | 15 +++++++ .../00-create-dependencies.yaml | 39 +++++++++++++++++++ .../00-secret.yaml | 5 +++ .../01-assert.yaml | 15 +++++++ .../01-create-resource.yaml | 9 +++++ .../README.md | 17 ++++++++ 7 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 internal/controllers/routerinterface/tests/routerinterface-router-not-ready/00-assert.yaml create mode 100644 internal/controllers/routerinterface/tests/routerinterface-router-not-ready/00-create-dependencies.yaml create mode 100644 internal/controllers/routerinterface/tests/routerinterface-router-not-ready/00-secret.yaml create mode 100644 internal/controllers/routerinterface/tests/routerinterface-router-not-ready/01-assert.yaml create mode 100644 internal/controllers/routerinterface/tests/routerinterface-router-not-ready/01-create-resource.yaml create mode 100644 internal/controllers/routerinterface/tests/routerinterface-router-not-ready/README.md diff --git a/internal/controllers/routerinterface/reconcile.go b/internal/controllers/routerinterface/reconcile.go index 61a950410..4a9125615 100644 --- a/internal/controllers/routerinterface/reconcile.go +++ b/internal/controllers/routerinterface/reconcile.go @@ -90,7 +90,34 @@ func (r *orcRouterInterfaceReconciler) Reconcile(ctx context.Context, req ctrl.R // so that we can clear the finalizer if router.Status.ID == nil || (!orcv1alpha1.IsAvailable(router) && router.GetDeletionTimestamp().IsZero()) { log.V(logging.Verbose).Info("Not reconciling interfaces for not-Available router") - return ctrl.Result{}, nil + + // The router exists but is not yet Available. Update status on associated + // RouterInterfaces so users can see they are blocked on the Router, + // matching the NotFound path above. + routerInterfaces, err := routerDependency.GetObjectsForDependency(ctx, r.client, router) + if err != nil { + return ctrl.Result{}, fmt.Errorf("fetching router interfaces: %w", err) + } + + if len(routerInterfaces) == 0 { + return ctrl.Result{}, nil + } + + var osResource *osclients.PortExt + + var reconcileStatus progress.ReconcileStatus + for i := range routerInterfaces { + routerInterface := &routerInterfaces[i] + log = log.WithValues("name", routerInterface.Name) + + var ifReconcileStatus progress.ReconcileStatus + ifReconcileStatus = progress.WaitingOnObject("Router", req.Name, progress.WaitingOnReady) + ifReconcileStatus = ifReconcileStatus.WithReconcileStatus(r.updateStatus(ctx, routerInterface, osResource, ifReconcileStatus)) + + reconcileStatus = reconcileStatus.WithReconcileStatus(ifReconcileStatus) + } + + return reconcileStatus.Return(log) } routerInterfaces, err := routerDependency.GetObjectsForDependency(ctx, r.client, router) diff --git a/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/00-assert.yaml b/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/00-assert.yaml new file mode 100644 index 000000000..dab17b18b --- /dev/null +++ b/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/00-assert.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Router +metadata: + name: routerinterface-router-not-ready +status: + conditions: + - type: Available + message: Waiting for Network/routerinterface-router-not-ready-pending to be created + status: "False" + reason: Progressing + - type: Progressing + message: Waiting for Network/routerinterface-router-not-ready-pending to be created + status: "True" + reason: Progressing diff --git a/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/00-create-dependencies.yaml b/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/00-create-dependencies.yaml new file mode 100644 index 000000000..c45f73503 --- /dev/null +++ b/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/00-create-dependencies.yaml @@ -0,0 +1,39 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Network +metadata: + name: routerinterface-router-not-ready +spec: + cloudCredentialsRef: + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + resource: {} +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Subnet +metadata: + name: routerinterface-router-not-ready +spec: + cloudCredentialsRef: + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + resource: + networkRef: routerinterface-router-not-ready + ipVersion: 4 + cidr: 192.168.156.0/24 +--- +# Router exists but stays not Available while waiting on a missing network. +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Router +metadata: + name: routerinterface-router-not-ready +spec: + cloudCredentialsRef: + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + resource: + externalGateways: + - networkRef: routerinterface-router-not-ready-pending diff --git a/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/00-secret.yaml b/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/00-secret.yaml new file mode 100644 index 000000000..f0fb63e85 --- /dev/null +++ b/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/00-secret.yaml @@ -0,0 +1,5 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl create secret generic openstack-clouds --from-file=clouds.yaml=${E2E_KUTTL_OSCLOUDS} ${E2E_KUTTL_CACERT_OPT} + namespaced: true diff --git a/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/01-assert.yaml b/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/01-assert.yaml new file mode 100644 index 000000000..b6c56ec67 --- /dev/null +++ b/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/01-assert.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: RouterInterface +metadata: + name: routerinterface-router-not-ready +status: + conditions: + - type: Available + message: Waiting for Router/routerinterface-router-not-ready to be ready + status: "False" + reason: Progressing + - type: Progressing + message: Waiting for Router/routerinterface-router-not-ready to be ready + status: "True" + reason: Progressing diff --git a/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/01-create-resource.yaml b/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/01-create-resource.yaml new file mode 100644 index 000000000..67d1754fc --- /dev/null +++ b/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/01-create-resource.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: RouterInterface +metadata: + name: routerinterface-router-not-ready +spec: + type: Subnet + routerRef: routerinterface-router-not-ready + subnetRef: routerinterface-router-not-ready diff --git a/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/README.md b/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/README.md new file mode 100644 index 000000000..d0aaa0eb5 --- /dev/null +++ b/internal/controllers/routerinterface/tests/routerinterface-router-not-ready/README.md @@ -0,0 +1,17 @@ +# RouterInterface status when Router is not Available + +## Step 00 + +Create a Network, Subnet, and a Router which exists but is not Available (the +Router is waiting on a missing external network). Verify that the Router is +waiting for its dependency. + +## Step 01 + +Create a RouterInterface referencing that Router. Verify that the +RouterInterface status reports that it is waiting for the Router to be ready, +rather than leaving status empty. + +## Reference + +https://github.com/k-orc/openstack-resource-controller/issues/838