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