From 8d24435a9e7eb72f7a88b6eb50aa5e7d53e89c5d Mon Sep 17 00:00:00 2001 From: Francisc Munteanu Date: Thu, 7 Dec 2023 12:21:12 +0100 Subject: [PATCH 1/5] remove spacebinding request migration controller --- ...pacebindingrequest_migration_controller.go | 176 --------- ...indingrequest_migration_controller_test.go | 335 ------------------ ...spacebindingrequest_spacebinding_mapper.go | 44 --- ...bindingrequest_spacebinding_mapper_test.go | 47 --- main.go | 14 - 5 files changed, 616 deletions(-) delete mode 100644 controllers/spacebindingrequestmigration/spacebindingrequest_migration_controller.go delete mode 100644 controllers/spacebindingrequestmigration/spacebindingrequest_migration_controller_test.go delete mode 100644 controllers/spacebindingrequestmigration/spacebindingrequest_spacebinding_mapper.go delete mode 100644 controllers/spacebindingrequestmigration/spacebindingrequest_spacebinding_mapper_test.go diff --git a/controllers/spacebindingrequestmigration/spacebindingrequest_migration_controller.go b/controllers/spacebindingrequestmigration/spacebindingrequest_migration_controller.go deleted file mode 100644 index 4e5036da0..000000000 --- a/controllers/spacebindingrequestmigration/spacebindingrequest_migration_controller.go +++ /dev/null @@ -1,176 +0,0 @@ -package spacebindingrequestmigration - -import ( - "context" - "fmt" - - toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1" - "github.com/codeready-toolchain/host-operator/pkg/cluster" - errs "github.com/pkg/errors" - "github.com/redhat-cop/operator-utils/pkg/util" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - runtimeclient "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/source" -) - -// Reconciler reconciles a SpaceBindingRequestMigration object -type Reconciler struct { - Client runtimeclient.Client - Scheme *runtime.Scheme - Namespace string - MemberClusters map[string]cluster.Cluster -} - -// SetupWithManager sets up the controller with the Manager. -func (r *Reconciler) SetupWithManager(mgr ctrl.Manager, memberClusters map[string]cluster.Cluster) error { - // Watch SpaceBindings from host cluster. - b := ctrl.NewControllerManagedBy(mgr). - For(&toolchainv1alpha1.SpaceBinding{}) - - // Watch SpaceBindingRequests in all member clusters and all namespaces and map those to their respective SpaceBinding resources. - for _, memberCluster := range memberClusters { - b = b.Watches( - source.NewKindWithCache(&toolchainv1alpha1.SpaceBindingRequest{}, memberCluster.Cache), - handler.EnqueueRequestsFromMapFunc(MapSpaceBindingRequestToSpaceBinding(r.Client, r.Namespace))) - } - return b.Complete(r) -} - -//+kubebuilder:rbac:groups=toolchain.dev.openshift.com,resources=spacebindingrequests,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=toolchain.dev.openshift.com,resources=spacebindingrequests/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=toolchain.dev.openshift.com,resources=spacebindingrequests/finalizers,verbs=update - -// Reconcile converts all the SpaceBindings created using the sandbox-cli to SpaceBindingRequests -func (r *Reconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) { - logger := log.FromContext(ctx) - logger.Info("reconciling SpaceBindingRequestMigration") - - // Fetch the SpaceBinding instance - spaceBinding := &toolchainv1alpha1.SpaceBinding{} - err := r.Client.Get(ctx, request.NamespacedName, spaceBinding) - if err != nil { - if errors.IsNotFound(err) { - // Request object not found, could have been deleted after reconcile request. - // Return and don't requeue - return reconcile.Result{}, nil - } - // Error reading the object - requeue the request. - return reconcile.Result{}, errs.Wrapf(err, "unable to get spacebinding") - } - if util.IsBeingDeleted(spaceBinding) { - logger.Info("the SpaceBinding is already being deleted") - return reconcile.Result{}, nil - } - // check if spaceBinding was created from SpaceBindingRequest, - // in that case we can skip it - if hasSpaceBindingRequest(spaceBinding) { - return reconcile.Result{}, nil - } - - spaceName := types.NamespacedName{Namespace: spaceBinding.Namespace, Name: spaceBinding.Spec.Space} - space := &toolchainv1alpha1.Space{} - if err := r.Client.Get(ctx, spaceName, space); err != nil { - if errors.IsNotFound(err) { - // space was deleted - return reconcile.Result{}, nil - } - // error while reading space - return ctrl.Result{}, errs.Wrapf(err, "unable to get the bound Space") - } - - murName := types.NamespacedName{Namespace: spaceBinding.Namespace, Name: spaceBinding.Spec.MasterUserRecord} - mur := &toolchainv1alpha1.MasterUserRecord{} - if err := r.Client.Get(ctx, murName, mur); err != nil { - if errors.IsNotFound(err) { - // mur was deleted - return reconcile.Result{}, nil - } - // error while reading MUR - return ctrl.Result{}, errs.Wrapf(err, "unable to get the bound MUR") - } - - // error when mur has no owner label (should not happen in prod) - if _, ok := mur.Labels[toolchainv1alpha1.MasterUserRecordOwnerLabelKey]; !ok { - return ctrl.Result{}, errs.New("mur has no MasterUserRecordOwnerLabelKey set") - } - // error when space has no creator label (should not happen in prod) - if _, ok := space.Labels[toolchainv1alpha1.SpaceCreatorLabelKey]; !ok { - return ctrl.Result{}, errs.New("space has no SpaceCreatorLabelKey set") - } - - // skip workspace creator spacebinding - // the controller will convert only spacebindings created by system admins using the sandbox-cli. - // If the creator label on the space matches the owner label on the MUR then this is the owner of the space - // and the spacebinding should not be migrated. - if space.Labels[toolchainv1alpha1.SpaceCreatorLabelKey] == mur.Labels[toolchainv1alpha1.MasterUserRecordOwnerLabelKey] { - return reconcile.Result{}, nil - } - - // get the spaceRole - spaceRole := spaceBinding.Spec.SpaceRole - - // get member cluster name where the space was provisioned - targetCluster := space.Spec.TargetCluster - memberCluster, memberClusterFound := r.MemberClusters[targetCluster] - if !memberClusterFound { - return ctrl.Result{}, errs.New(fmt.Sprintf("unable to find member cluster: %s", targetCluster)) - } - - // get the home namespace from space - defaultNamespace := getDefaultNamespace(space.Status.ProvisionedNamespaces) - - // construct a SpaceBindingRequest object - sbrName := mur.GetName() + "-" + spaceRole - sbr := &toolchainv1alpha1.SpaceBindingRequest{ - ObjectMeta: metav1.ObjectMeta{ - Name: sbrName, - Namespace: defaultNamespace, - }, - } - - result, err := controllerutil.CreateOrUpdate(ctx, memberCluster.Client, sbr, func() error { - sbr.Spec = toolchainv1alpha1.SpaceBindingRequestSpec{ - MasterUserRecord: mur.GetName(), - SpaceRole: spaceRole, - } - return nil - }) - - if err != nil { - // something happened when we tried to read or write the sbr - return ctrl.Result{}, errs.Wrapf(err, "Failed to create or update space binding request %v", sbrName) - } - - if result == controllerutil.OperationResultCreated { - // let's requeue after we created the SBR, so that in next loop the migrated SpaceBinding object will be deleted - return ctrl.Result{Requeue: true}, nil - } - // if the SBR was found (was created from the previous reconcile loop), we can now delete the SpaceBinding object - if err := r.Client.Delete(ctx, spaceBinding); err != nil && !errors.IsNotFound(err) { - return ctrl.Result{}, errs.Wrapf(err, "unable to delete the SpaceBinding") - } - - return ctrl.Result{}, nil -} - -func getDefaultNamespace(provisionedNamespaces []toolchainv1alpha1.SpaceNamespace) string { - for _, namespaceObj := range provisionedNamespaces { - if namespaceObj.Type == "default" { - return namespaceObj.Name - } - } - return "" -} - -func hasSpaceBindingRequest(spaceBinding *toolchainv1alpha1.SpaceBinding) bool { - _, sbrNameFound := spaceBinding.Labels[toolchainv1alpha1.SpaceBindingRequestLabelKey] - return sbrNameFound -} diff --git a/controllers/spacebindingrequestmigration/spacebindingrequest_migration_controller_test.go b/controllers/spacebindingrequestmigration/spacebindingrequest_migration_controller_test.go deleted file mode 100644 index 0fe58206a..000000000 --- a/controllers/spacebindingrequestmigration/spacebindingrequest_migration_controller_test.go +++ /dev/null @@ -1,335 +0,0 @@ -package spacebindingrequestmigration_test - -import ( - "context" - "fmt" - "testing" - - toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1" - "github.com/codeready-toolchain/host-operator/controllers/spacebindingrequestmigration" - "github.com/codeready-toolchain/host-operator/pkg/apis" - "github.com/codeready-toolchain/host-operator/pkg/cluster" - . "github.com/codeready-toolchain/host-operator/test" - spacebindingtest "github.com/codeready-toolchain/host-operator/test/spacebinding" - spacebindingrequesttest "github.com/codeready-toolchain/host-operator/test/spacebindingrequest" - commoncluster "github.com/codeready-toolchain/toolchain-common/pkg/cluster" - "github.com/codeready-toolchain/toolchain-common/pkg/test" - "github.com/codeready-toolchain/toolchain-common/pkg/test/masteruserrecord" - spacetest "github.com/codeready-toolchain/toolchain-common/pkg/test/space" - "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - runtimeclient "sigs.k8s.io/controller-runtime/pkg/client" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func TestMigrateSpaceBindingToSBR(t *testing.T) { - // given - logf.SetLogger(zap.New(zap.UseDevMode(true))) - err := apis.AddToScheme(scheme.Scheme) - require.NoError(t, err) - janeSpace := spacetest.NewSpace(test.HostOperatorNs, "jane", - spacetest.WithSpecTargetCluster("member-1"), - spacetest.WithStatusProvisionedNamespaces([]toolchainv1alpha1.SpaceNamespace{{ - Name: "jane-tenant", - Type: "default", - }}), - spacetest.WithLabel(toolchainv1alpha1.SpaceCreatorLabelKey, "jane"), - ) - - janeMur := masteruserrecord.NewMasterUserRecord(t, "jane", masteruserrecord.WithLabel(toolchainv1alpha1.MasterUserRecordOwnerLabelKey, "jane")) - sbForCreator := spacebindingtest.NewSpaceBinding(janeMur.Name, janeSpace.Name, "admin", janeMur.Name) - // we have a user which was added to the space via sandbox-cli - johnMur := masteruserrecord.NewMasterUserRecord(t, "john", masteruserrecord.WithLabel(toolchainv1alpha1.MasterUserRecordOwnerLabelKey, "john")) - sbForJohn := spacebindingtest.NewSpaceBinding(johnMur.Name, janeSpace.Name, "admin", janeMur.GetName()) - t.Run("success", func(t *testing.T) { - - t.Run("create sbr for sb added via sandbox-cli", func(t *testing.T) { - // given - member1 := NewMemberClusterWithClient(test.NewFakeClient(t), "member-1", corev1.ConditionTrue) - hostClient := test.NewFakeClient(t, janeSpace, janeMur, johnMur, sbForCreator, sbForJohn) - ctrl := newReconciler(t, hostClient, member1) - - // when - res, err := ctrl.Reconcile(context.TODO(), requestFor(sbForJohn)) - - // then - require.NoError(t, err) - require.True(t, res.Requeue) // requeue should be triggered once SBR is created - // spaceBindingRequest with expected name, namespace and spec should be created - spacebindingrequesttest.AssertThatSpaceBindingRequest(t, "jane-tenant", johnMur.Name+"-admin", member1.Client). - HasSpecSpaceRole("admin"). - HasSpecMasterUserRecord(johnMur.Name) - // the migrated spacebinding is still there, it will be deleted at the next reconcile loop - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, johnMur.Name, janeSpace.Name, hostClient). - Exists() - // the spacebinding for the space creator is still there - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, janeMur.Name, janeSpace.Name, hostClient). - Exists() - - t.Run("the next reconcile deletes the migrated spacebinding", func(t *testing.T) { - // when - res, err := ctrl.Reconcile(context.TODO(), requestFor(sbForJohn)) - - // then - require.NoError(t, err) - require.False(t, res.Requeue) // no requeue this time - // the migrated spacebinding was deleted - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, johnMur.Name, janeSpace.Name, hostClient). - DoesNotExist() - // spaceBindingRequest with expected name, namespace and spec is still there - spacebindingrequesttest.AssertThatSpaceBindingRequest(t, "jane-tenant", johnMur.Name+"-admin", member1.Client). - HasSpecSpaceRole("admin"). - HasSpecMasterUserRecord(johnMur.Name) - // the spacebinding for the space creator is still there - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, janeMur.Name, janeSpace.Name, hostClient). - Exists() - }) - }) - - t.Run("skip space creator spacebinding ", func(t *testing.T) { - // given - // we have the workspace creator spacebinding, it should not be migrated to SpaceBindingRequest - member1 := NewMemberClusterWithClient(test.NewFakeClient(t), "member-1", corev1.ConditionTrue) - hostClient := test.NewFakeClient(t, janeSpace, janeMur, sbForCreator) - ctrl := newReconciler(t, hostClient, member1) - - // when - _, err = ctrl.Reconcile(context.TODO(), requestFor(sbForCreator)) - - // then - require.NoError(t, err) - // the spacebinding for the space creator is still there - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, janeMur.Name, janeSpace.Name, hostClient). - Exists() - // the spaceBindingRequest wasn't created - spacebindingrequesttest.AssertThatSpaceBindingRequest(t, "jane-tenant", janeMur.Name+"-admin", member1.Client). - DoesNotExist() - }) - - t.Run("space creator name is different than mur name", func(t *testing.T) { - // given - batmanSpace := spacetest.NewSpace(test.HostOperatorNs, "batman", - spacetest.WithStatusTargetCluster("member-1"), - spacetest.WithStatusProvisionedNamespaces([]toolchainv1alpha1.SpaceNamespace{{ - Name: "batman-tenant", - Type: "default", - }}), - spacetest.WithLabel(toolchainv1alpha1.SpaceCreatorLabelKey, "batman"), - ) - // mur name differs from the space creator label - // but the usersignup matches the space creator name - batmanMur := masteruserrecord.NewMasterUserRecord(t, "batman123", masteruserrecord.WithLabel(toolchainv1alpha1.MasterUserRecordOwnerLabelKey, "batman")) - sbForBatman := spacebindingtest.NewSpaceBinding(batmanMur.GetName(), batmanSpace.GetName(), "admin", "batman") - member1 := NewMemberClusterWithClient(test.NewFakeClient(t), "member-1", corev1.ConditionTrue) - hostClient := test.NewFakeClient(t, batmanSpace, batmanMur, sbForBatman) - ctrl := newReconciler(t, hostClient, member1) - - // when - _, err = ctrl.Reconcile(context.TODO(), requestFor(sbForBatman)) - - // then - require.NoError(t, err) - // the spacebinding for the space creator is still there - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, batmanMur.Name, batmanSpace.Name, hostClient). - Exists() - // the spaceBindingRequest wasn't created - spacebindingrequesttest.AssertThatSpaceBindingRequest(t, "batman-tenant", batmanMur.Name+"-admin", member1.Client). - DoesNotExist() - }) - - t.Run("space not found", func(t *testing.T) { - // given - member1 := NewMemberClusterWithClient(test.NewFakeClient(t), "member-1", corev1.ConditionTrue) - // let's not load the space object - hostClient := test.NewFakeClient(t, janeMur, johnMur, sbForCreator, sbForJohn) - ctrl := newReconciler(t, hostClient, member1) - - // when - _, err = ctrl.Reconcile(context.TODO(), requestFor(sbForJohn)) - - // then - require.NoError(t, err) - // the spacebinding for the space creator is still there - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, janeMur.Name, janeSpace.Name, hostClient). - Exists() - // the spacebinding for john user is still there - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, johnMur.Name, janeSpace.Name, hostClient). - Exists() - // the spaceBindingRequest wasn't created - spacebindingrequesttest.AssertThatSpaceBindingRequest(t, "jane-tenant", johnMur.Name+"-admin", member1.Client). - DoesNotExist() - }) - - t.Run("mur not found", func(t *testing.T) { - // given - member1 := NewMemberClusterWithClient(test.NewFakeClient(t), "member-1", corev1.ConditionTrue) - // let's not load the mur object - hostClient := test.NewFakeClient(t, janeMur, janeSpace, sbForCreator, sbForJohn) - ctrl := newReconciler(t, hostClient, member1) - - // when - _, err = ctrl.Reconcile(context.TODO(), requestFor(sbForJohn)) - - // then - require.NoError(t, err) - // the spacebinding for the space creator is still there - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, janeMur.Name, janeSpace.Name, hostClient). - Exists() - // the spacebinding for john user is still there - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, johnMur.Name, janeSpace.Name, hostClient). - Exists() - // the spaceBindingRequest wasn't created - spacebindingrequesttest.AssertThatSpaceBindingRequest(t, "jane-tenant", johnMur.Name+"-admin", member1.Client). - DoesNotExist() - }) - - t.Run("spacebinding has spacebindingrequest", func(t *testing.T) { - // given - // the spacebinding has a spacebindingrequest - sbrForJohn := spacebindingrequesttest.NewSpaceBindingRequest("john-admin", "jane-tenant", spacebindingrequesttest.WithLabel(toolchainv1alpha1.SpaceCreatorLabelKey, "somevalue")) - sbForJohnWithSBR := spacebindingtest.NewSpaceBinding(johnMur.Name, janeSpace.Name, "admin", janeMur.GetName(), spacebindingtest.WithSpaceBindingRequest(sbrForJohn)) - member1 := NewMemberClusterWithClient(test.NewFakeClient(t, sbrForJohn), "member-1", corev1.ConditionTrue) - hostClient := test.NewFakeClient(t, janeMur, janeSpace, johnMur, sbForJohnWithSBR) - ctrl := newReconciler(t, hostClient, member1) - - // when - _, err = ctrl.Reconcile(context.TODO(), requestFor(sbForJohnWithSBR)) - - // then - require.NoError(t, err) - // the spacebinding for john user is still there - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, johnMur.Name, janeSpace.Name, hostClient). - Exists() - // the spaceBindingRequest is unchanged - // no migration label as creator - spacebindingrequesttest.AssertThatSpaceBindingRequest(t, "jane-tenant", johnMur.Name+"-admin", member1.Client). - HasLabelWithValue(toolchainv1alpha1.SpaceCreatorLabelKey, "somevalue"). - Exists() - }) - - t.Run("spacebinding is being deleted", func(t *testing.T) { - // given - member1 := NewMemberClusterWithClient(test.NewFakeClient(t), "member-1", corev1.ConditionTrue) - // the spacebinding is being deleted - sbForJohn := spacebindingtest.NewSpaceBinding(johnMur.Name, janeSpace.Name, "admin", janeMur.GetName(), spacebindingtest.WithDeletionTimestamp()) - hostClient := test.NewFakeClient(t, janeMur, janeSpace, sbForCreator, johnMur, sbForJohn) - ctrl := newReconciler(t, hostClient, member1) - - // when - _, err = ctrl.Reconcile(context.TODO(), requestFor(sbForJohn)) - - // then - require.NoError(t, err) - // the spacebinding for the space creator is still there - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, janeMur.Name, janeSpace.Name, hostClient). - Exists() - // the spacebinding for john user is still there - spacebindingtest.AssertThatSpaceBinding(t, test.HostOperatorNs, johnMur.Name, janeSpace.Name, hostClient). - Exists() - // the spaceBindingRequest wasn't created - spacebindingrequesttest.AssertThatSpaceBindingRequest(t, "jane-tenant", johnMur.Name+"-admin", member1.Client). - DoesNotExist() - }) - }) - - t.Run("error", func(t *testing.T) { - t.Run("unable to get spacebinding", func(t *testing.T) { - hostClient := test.NewFakeClient(t, sbForCreator) - hostClient.MockGet = mockGetSpaceBindingFail(hostClient) - ctrl := newReconciler(t, hostClient) - - // when - _, err := ctrl.Reconcile(context.TODO(), requestFor(sbForCreator)) - - // then - // space binding request should not be there - require.EqualError(t, err, "unable to get spacebinding: mock error") - }) - - t.Run("member cluster not found", func(t *testing.T) { - spaceWithInvalidTargetCluster := spacetest.NewSpace(test.HostOperatorNs, "jane", - spacetest.WithSpecTargetCluster("invalid"), - spacetest.WithLabel(toolchainv1alpha1.SpaceCreatorLabelKey, "jane"), - ) - sb := spacebindingtest.NewSpaceBinding(johnMur.Name, spaceWithInvalidTargetCluster.Name, "admin", janeMur.Name) - hostClient := test.NewFakeClient(t, sb, spaceWithInvalidTargetCluster, johnMur) - ctrl := newReconciler(t, hostClient) - - // when - _, err := ctrl.Reconcile(context.TODO(), requestFor(sb)) - - // then - // space binding request should not be there - require.EqualError(t, err, "unable to find member cluster: invalid") - }) - - t.Run("mur has no owner label", func(t *testing.T) { - murWithNoOwnership := masteruserrecord.NewMasterUserRecord(t, "jane") - sb := spacebindingtest.NewSpaceBinding(murWithNoOwnership.Name, janeSpace.Name, "admin", janeMur.Name) - hostClient := test.NewFakeClient(t, sb, janeSpace, murWithNoOwnership) - ctrl := newReconciler(t, hostClient) - - // when - _, err := ctrl.Reconcile(context.TODO(), requestFor(sb)) - - // then - // space binding request should not be there - require.EqualError(t, err, "mur has no MasterUserRecordOwnerLabelKey set") - }) - - }) -} - -func newReconciler(t *testing.T, hostCl runtimeclient.Client, memberClusters ...*commoncluster.CachedToolchainCluster) *spacebindingrequestmigration.Reconciler { - s := scheme.Scheme - err := apis.AddToScheme(s) - require.NoError(t, err) - - clusters := map[string]cluster.Cluster{} - for _, c := range memberClusters { - clusters[c.Name] = cluster.Cluster{ - Config: &commoncluster.Config{ - Type: commoncluster.Member, - OperatorNamespace: c.OperatorNamespace, - OwnerClusterName: test.MemberClusterName, - }, - Client: c.Client, - } - } - return &spacebindingrequestmigration.Reconciler{ - Client: hostCl, - Scheme: s, - Namespace: test.HostOperatorNs, - MemberClusters: clusters, - } -} - -func requestFor(s *toolchainv1alpha1.SpaceBinding) reconcile.Request { - if s != nil { - return reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: s.Namespace, - Name: s.Name, - }, - } - } - return reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: test.HostOperatorNs, - Name: "unknown", - }, - } -} - -func mockGetSpaceBindingFail(cl runtimeclient.Client) func(ctx context.Context, key runtimeclient.ObjectKey, obj runtimeclient.Object, opts ...runtimeclient.GetOption) error { - return func(ctx context.Context, key runtimeclient.ObjectKey, obj runtimeclient.Object, opts ...runtimeclient.GetOption) error { - if _, ok := obj.(*toolchainv1alpha1.SpaceBinding); ok { - return fmt.Errorf("mock error") - } - return cl.Get(ctx, key, obj, opts...) - } -} diff --git a/controllers/spacebindingrequestmigration/spacebindingrequest_spacebinding_mapper.go b/controllers/spacebindingrequestmigration/spacebindingrequest_spacebinding_mapper.go deleted file mode 100644 index 051ad3c07..000000000 --- a/controllers/spacebindingrequestmigration/spacebindingrequest_spacebinding_mapper.go +++ /dev/null @@ -1,44 +0,0 @@ -package spacebindingrequestmigration - -import ( - "context" - - toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1" - ctrl "sigs.k8s.io/controller-runtime" - - "k8s.io/apimachinery/pkg/types" - runtimeclient "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -// MapSpaceBindingRequestToSpaceBinding returns an event for the spacebinding that owns. -func MapSpaceBindingRequestToSpaceBinding(cl runtimeclient.Client, watchNamespace string) func(spaceBindingRequest runtimeclient.Object) []reconcile.Request { - mapperLog := ctrl.Log.WithName("SpaceBindingRequestToSpaceBinding") - return func(obj runtimeclient.Object) []reconcile.Request { - spaceBindings := &toolchainv1alpha1.SpaceBindingList{} - err := cl.List(context.TODO(), spaceBindings, - runtimeclient.InNamespace(watchNamespace), - runtimeclient.MatchingLabels{ - toolchainv1alpha1.SpaceBindingRequestLabelKey: obj.GetName(), - toolchainv1alpha1.SpaceBindingRequestNamespaceLabelKey: obj.GetNamespace(), - }) - if err != nil { - mapperLog.Error(err, "cannot list spacebindings") - return []reconcile.Request{} - } - if len(spaceBindings.Items) == 0 { - return []reconcile.Request{} - } - - req := make([]reconcile.Request, len(spaceBindings.Items)) - for i, item := range spaceBindings.Items { - req[i] = reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: item.Namespace, - Name: item.Name, - }, - } - } - return req - } -} diff --git a/controllers/spacebindingrequestmigration/spacebindingrequest_spacebinding_mapper_test.go b/controllers/spacebindingrequestmigration/spacebindingrequest_spacebinding_mapper_test.go deleted file mode 100644 index b9e70ae3a..000000000 --- a/controllers/spacebindingrequestmigration/spacebindingrequest_spacebinding_mapper_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package spacebindingrequestmigration_test - -import ( - "testing" - - "github.com/codeready-toolchain/api/api/v1alpha1" - "github.com/codeready-toolchain/host-operator/controllers/spacebindingrequestmigration" - sb "github.com/codeready-toolchain/host-operator/test/spacebinding" - spacebindingrequesttest "github.com/codeready-toolchain/host-operator/test/spacebindingrequest" - "github.com/codeready-toolchain/toolchain-common/pkg/test" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func TestMapSpaceBindingRequestToSpaceBinding(t *testing.T) { - // given - restore := test.SetEnvVarAndRestore(t, "WATCH_NAMESPACE", test.HostOperatorNs) - defer restore() - spaceBindingRequest := spacebindingrequesttest.NewSpaceBindingRequest("mySpaceBindingRequest", "jane") - // following spaceBinding has a spaceBindingRequest associated - spaceBinding := sb.NewSpaceBinding("jane", "jane", "admin", "signupAdmin") - spaceBinding.Labels[v1alpha1.SpaceBindingRequestLabelKey] = spaceBindingRequest.Name - spaceBinding.Labels[v1alpha1.SpaceBindingRequestNamespaceLabelKey] = spaceBindingRequest.Namespace - - cl := test.NewFakeClient(t, spaceBinding) - - t.Run("should return SpaceBinding requests for SpaceBindingRequest", func(t *testing.T) { - // when - requests := spacebindingrequestmigration.MapSpaceBindingRequestToSpaceBinding(cl, test.HostOperatorNs)(spaceBindingRequest) - - // then - require.Len(t, requests, 1) - assert.Contains(t, requests, newRequest(spaceBinding.Name)) - }) - -} - -func newRequest(name string) reconcile.Request { - return reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: test.HostOperatorNs, - Name: name, - }, - } -} diff --git a/main.go b/main.go index aec7519a1..8e97464a7 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,6 @@ import ( "github.com/codeready-toolchain/host-operator/controllers/space" "github.com/codeready-toolchain/host-operator/controllers/spacebindingcleanup" "github.com/codeready-toolchain/host-operator/controllers/spacebindingrequest" - "github.com/codeready-toolchain/host-operator/controllers/spacebindingrequestmigration" "github.com/codeready-toolchain/host-operator/controllers/spacecleanup" "github.com/codeready-toolchain/host-operator/controllers/spacecompletion" "github.com/codeready-toolchain/host-operator/controllers/spacerequest" @@ -324,19 +323,6 @@ func main() { // nolint:gocyclo os.Exit(1) } } - // TEMPORARY controller that converts spacebindings created via sandbox-cli into spacebinding requests - // once the migration effort is completed , the controller can be disabled and deleted. - if crtConfig.SpaceConfig().SpaceBindingRequestIsEnabled() { - if err = (&spacebindingrequestmigration.Reconciler{ - Client: mgr.GetClient(), - Namespace: namespace, - MemberClusters: clusterScopedMemberClusters, - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr, clusterScopedMemberClusters); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "SpaceBindingRequestMigration") - os.Exit(1) - } - } if err = (&space.Reconciler{ Client: mgr.GetClient(), Namespace: namespace, From 09f9f30dce41f0fbb10c2a3010e39f032f35b493 Mon Sep 17 00:00:00 2001 From: Devtools Date: Tue, 25 Feb 2025 15:56:23 +0100 Subject: [PATCH 2/5] handle conditions on nstemplatetier --- .../nstemplatetier_controller.go | 53 ++++++++++++++++++- .../nstemplatetier_controller_test.go | 18 ++++++- test/nstemplatetier/assertion.go | 7 +++ 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/controllers/nstemplatetier/nstemplatetier_controller.go b/controllers/nstemplatetier/nstemplatetier_controller.go index 567030f9c..07036bf4c 100644 --- a/controllers/nstemplatetier/nstemplatetier_controller.go +++ b/controllers/nstemplatetier/nstemplatetier_controller.go @@ -8,7 +8,9 @@ import ( toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1" "github.com/codeready-toolchain/host-operator/controllers/toolchainconfig" + "github.com/codeready-toolchain/toolchain-common/pkg/condition" "github.com/redhat-cop/operator-utils/pkg/util" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/handler" @@ -24,6 +26,11 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" ) +const UnableToEnsureRevisions = "UnableToEnsureRevisions" + +// NSTemplateTierProvisionedReason represents the reason for a successfully provisioned NSTemplateTier. +const NSTemplateTierProvisionedReason = "Provisioned" + // SetupWithManager sets up the controller with the Manager. func (r *Reconciler) SetupWithManager(mgr manager.Manager) error { return ctrl.NewControllerManagedBy(mgr). @@ -71,14 +78,21 @@ func (r *Reconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl. // check if the `status.revisions` field is up-to-date and create a TTR for each TierTemplate if created, err := r.ensureRevision(ctx, tier); err != nil { - // todo add/update ready condition false in the NSTemplateTier when something fails + // set ready condition false in the NSTemplateTier + if err := r.setStatusFailed(ctx, tier, UnableToEnsureRevisions, err); err != nil { + return reconcile.Result{}, err + } + return reconcile.Result{}, fmt.Errorf("unable to create new TierTemplateRevision after NSTemplateTier changed: %w", err) } else if created { logger.Info("Requeue after creating a new TTR") return reconcile.Result{RequeueAfter: time.Second}, nil } - return reconcile.Result{}, nil + // set ready condition on NSTemplateTier + err = r.updateStatus(ctx, tier, ReadyCondition()) + + return reconcile.Result{}, err } // ensureRevision ensures that there is a TierTemplateRevision CR for each of the TierTemplate. @@ -241,3 +255,38 @@ func NewTTR(tierTmpl *toolchainv1alpha1.TierTemplate, nsTmplTier *toolchainv1alp return ttr } + +func (r *Reconciler) setStatusFailed(ctx context.Context, tmplTier *toolchainv1alpha1.NSTemplateTier, reason string, cause error) error { + if err := r.updateStatus( + ctx, + tmplTier, + toolchainv1alpha1.Condition{ + Type: toolchainv1alpha1.ConditionReady, + Status: corev1.ConditionFalse, + Reason: reason, + Message: cause.Error(), + }); err != nil { + logger := log.FromContext(ctx) + logger.Error(err, "unable to update NSTemplateTier condition") + return err + } + return cause +} + +func (r *Reconciler) updateStatus(ctx context.Context, tmplTier *toolchainv1alpha1.NSTemplateTier, conditions ...toolchainv1alpha1.Condition) error { + var updated bool + tmplTier.Status.Conditions, updated = condition.AddOrUpdateStatusConditions(tmplTier.Status.Conditions, conditions...) + if !updated { + // Nothing changed + return nil + } + return r.Client.Status().Update(ctx, tmplTier) +} + +func ReadyCondition() toolchainv1alpha1.Condition { + return toolchainv1alpha1.Condition{ + Type: toolchainv1alpha1.ConditionReady, + Status: corev1.ConditionTrue, + Reason: NSTemplateTierProvisionedReason, + } +} diff --git a/controllers/nstemplatetier/nstemplatetier_controller_test.go b/controllers/nstemplatetier/nstemplatetier_controller_test.go index df82a22cd..480563181 100644 --- a/controllers/nstemplatetier/nstemplatetier_controller_test.go +++ b/controllers/nstemplatetier/nstemplatetier_controller_test.go @@ -17,6 +17,7 @@ import ( templatev1 "github.com/openshift/api/template/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -115,6 +116,9 @@ func TestReconcile(t *testing.T) { require.Equal(t, reconcile.Result{Requeue: false}, res) // no reconcile // revisions are the same tiertest.AssertThatNSTemplateTier(t, "base1ns", cl). + HasConditions( + nstemplatetier.ReadyCondition(), + ). HasStatusTierTemplateRevisions(tierTemplatesRefs) // no TierTemplateRevision CRs were created tiertemplaterevision.AssertThatTTRs(t, cl, base1nsTier.GetNamespace()).DoNotExist() @@ -161,6 +165,9 @@ func TestReconcile(t *testing.T) { require.Equal(t, reconcile.Result{Requeue: false}, res) // no reconcile // revisions are the same tiertest.AssertThatNSTemplateTier(t, "base1ns", cl). + HasConditions( + nstemplatetier.ReadyCondition(), + ). HasStatusTierTemplateRevisions(tierTemplatesRefs) // expected TierTemplateRevision CRs are still there ttrs := toolchainv1alpha1.TierTemplateRevisionList{} @@ -268,9 +275,18 @@ func TestReconcile(t *testing.T) { _, err := r.Reconcile(context.TODO(), req) // then // we expect an error caused by the absence of the tiertemplate for the `code` namespace CR - require.ErrorContains(t, err, "tiertemplates.toolchain.dev.openshift.com \"base1ns-code-123456new\" not found") + errCause := "tiertemplates.toolchain.dev.openshift.com \"base1ns-code-123456new\" not found" + require.ErrorContains(t, err, errCause) // the revisions field also should remain empty tiertest.AssertThatNSTemplateTier(t, "base1ns", cl). + HasConditions( + toolchainv1alpha1.Condition{ + Type: toolchainv1alpha1.ConditionReady, + Status: corev1.ConditionFalse, + Reason: nstemplatetier.UnableToEnsureRevisions, + Message: errCause, + }, + ). HasNoStatusTierTemplateRevisions() // and the TierTemplateRevision CRs are not created tiertemplaterevision.AssertThatTTRs(t, cl, base1nsTier.GetNamespace()).DoNotExist() diff --git a/test/nstemplatetier/assertion.go b/test/nstemplatetier/assertion.go index 7af179809..395275184 100644 --- a/test/nstemplatetier/assertion.go +++ b/test/nstemplatetier/assertion.go @@ -61,3 +61,10 @@ func (a *Assertion) HasNoStatusTierTemplateRevisions() *Assertion { require.Nil(a.t, a.tier.Status.Revisions) return a } + +func (a *Assertion) HasConditions(expected ...toolchainv1alpha1.Condition) *Assertion { + err := a.loadResource() + require.NoError(a.t, err) + test.AssertConditionsMatch(a.t, a.tier.Status.Conditions, expected...) + return a +} From e1fa93cd6b238c3917c687954dc528c6744c328b Mon Sep 17 00:00:00 2001 From: Devtools Date: Wed, 26 Feb 2025 13:11:15 +0100 Subject: [PATCH 3/5] move reasons into api --- controllers/nstemplatetier/nstemplatetier_controller.go | 9 ++------- .../nstemplatetier/nstemplatetier_controller_test.go | 2 +- go.mod | 2 ++ go.sum | 4 ++-- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/controllers/nstemplatetier/nstemplatetier_controller.go b/controllers/nstemplatetier/nstemplatetier_controller.go index 07036bf4c..7b749ab67 100644 --- a/controllers/nstemplatetier/nstemplatetier_controller.go +++ b/controllers/nstemplatetier/nstemplatetier_controller.go @@ -26,11 +26,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" ) -const UnableToEnsureRevisions = "UnableToEnsureRevisions" - -// NSTemplateTierProvisionedReason represents the reason for a successfully provisioned NSTemplateTier. -const NSTemplateTierProvisionedReason = "Provisioned" - // SetupWithManager sets up the controller with the Manager. func (r *Reconciler) SetupWithManager(mgr manager.Manager) error { return ctrl.NewControllerManagedBy(mgr). @@ -79,7 +74,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl. // check if the `status.revisions` field is up-to-date and create a TTR for each TierTemplate if created, err := r.ensureRevision(ctx, tier); err != nil { // set ready condition false in the NSTemplateTier - if err := r.setStatusFailed(ctx, tier, UnableToEnsureRevisions, err); err != nil { + if err := r.setStatusFailed(ctx, tier, toolchainv1alpha1.NSTemplateTierUnableToEnsureRevisionsReason, err); err != nil { return reconcile.Result{}, err } @@ -287,6 +282,6 @@ func ReadyCondition() toolchainv1alpha1.Condition { return toolchainv1alpha1.Condition{ Type: toolchainv1alpha1.ConditionReady, Status: corev1.ConditionTrue, - Reason: NSTemplateTierProvisionedReason, + Reason: toolchainv1alpha1.NSTemplateTierProvisionedReason, } } diff --git a/controllers/nstemplatetier/nstemplatetier_controller_test.go b/controllers/nstemplatetier/nstemplatetier_controller_test.go index 480563181..72c5e7715 100644 --- a/controllers/nstemplatetier/nstemplatetier_controller_test.go +++ b/controllers/nstemplatetier/nstemplatetier_controller_test.go @@ -283,7 +283,7 @@ func TestReconcile(t *testing.T) { toolchainv1alpha1.Condition{ Type: toolchainv1alpha1.ConditionReady, Status: corev1.ConditionFalse, - Reason: nstemplatetier.UnableToEnsureRevisions, + Reason: toolchainv1alpha1.NSTemplateTierUnableToEnsureRevisionsReason, Message: errCause, }, ). diff --git a/go.mod b/go.mod index 1738890f2..1bf6d287e 100644 --- a/go.mod +++ b/go.mod @@ -128,3 +128,5 @@ require ( ) go 1.21 + +replace github.com/codeready-toolchain/api => github.com/mfrancisc/api v0.0.0-20250226115151-870f14a6831a diff --git a/go.sum b/go.sum index 943fe8bcf..3860b5b06 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,6 @@ github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtM github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/codeready-toolchain/api v0.0.0-20250131222557-beba5463f429 h1:I7xzHRmstvzucH9NqF54xvsM/yYuWOp/G5+BUr5j4tY= -github.com/codeready-toolchain/api v0.0.0-20250131222557-beba5463f429/go.mod h1:gPwicZPTmRm1PF75ysEYXaYKdXoFgwgCggTJd1oYmOs= github.com/codeready-toolchain/toolchain-common v0.0.0-20250131223755-a9c24d874b32 h1:mX8aMYw9yPCSZuRNeZwShOPQDl0aTKV9FcEfb1Sdhiw= github.com/codeready-toolchain/toolchain-common v0.0.0-20250131223755-a9c24d874b32/go.mod h1:/PeschEEyTZIAsXQxIf83Fl8kOpSOHDfR5yyanz+bSA= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -179,6 +177,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/mfrancisc/api v0.0.0-20250226115151-870f14a6831a h1:GXemBKb4nF8Tm+UcixjkGBMO3JEQi0Q4WDPYouZ3udE= +github.com/mfrancisc/api v0.0.0-20250226115151-870f14a6831a/go.mod h1:gPwicZPTmRm1PF75ysEYXaYKdXoFgwgCggTJd1oYmOs= github.com/migueleliasweb/go-github-mock v0.0.18 h1:0lWt9MYmZQGnQE2rFtjlft/YtD6hzxuN6JJRFpujzEI= github.com/migueleliasweb/go-github-mock v0.0.18/go.mod h1:CcgXcbMoRnf3rRVHqGssuBquZDIcaplxL2W6G+xs7kM= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= From 45404cdf31313c45a6c6437aaf90bf4cc2199775 Mon Sep 17 00:00:00 2001 From: Devtools Date: Mon, 3 Mar 2025 11:27:58 +0100 Subject: [PATCH 4/5] refactor err conditions --- .../nstemplatetier_controller.go | 23 +++++++++++-------- .../nstemplatetier_controller_test.go | 8 +------ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/controllers/nstemplatetier/nstemplatetier_controller.go b/controllers/nstemplatetier/nstemplatetier_controller.go index e376b8da5..f31e193c5 100644 --- a/controllers/nstemplatetier/nstemplatetier_controller.go +++ b/controllers/nstemplatetier/nstemplatetier_controller.go @@ -75,7 +75,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl. // check if the `status.revisions` field is up-to-date and create a TTR for each TierTemplate if created, err := r.ensureRevision(ctx, tier); err != nil { // set ready condition false in the NSTemplateTier - if err := r.setStatusFailed(ctx, tier, toolchainv1alpha1.NSTemplateTierUnableToEnsureRevisionsReason, err); err != nil { + if err := r.setStatusFailed(ctx, tier, FailedCondition(toolchainv1alpha1.NSTemplateTierUnableToEnsureRevisionsReason, err.Error())); err != nil { return reconcile.Result{}, err } @@ -232,21 +232,17 @@ func NewTTR(tierTmpl *toolchainv1alpha1.TierTemplate, nsTmplTier *toolchainv1alp return ttr } -func (r *Reconciler) setStatusFailed(ctx context.Context, tmplTier *toolchainv1alpha1.NSTemplateTier, reason string, cause error) error { +func (r *Reconciler) setStatusFailed(ctx context.Context, tmplTier *toolchainv1alpha1.NSTemplateTier, failedCondition toolchainv1alpha1.Condition) error { if err := r.updateStatus( ctx, tmplTier, - toolchainv1alpha1.Condition{ - Type: toolchainv1alpha1.ConditionReady, - Status: corev1.ConditionFalse, - Reason: reason, - Message: cause.Error(), - }); err != nil { + failedCondition, + ); err != nil { logger := log.FromContext(ctx) logger.Error(err, "unable to update NSTemplateTier condition") return err } - return cause + return nil } func (r *Reconciler) updateStatus(ctx context.Context, tmplTier *toolchainv1alpha1.NSTemplateTier, conditions ...toolchainv1alpha1.Condition) error { @@ -259,6 +255,15 @@ func (r *Reconciler) updateStatus(ctx context.Context, tmplTier *toolchainv1alph return r.Client.Status().Update(ctx, tmplTier) } +func FailedCondition(reason string, cause string) toolchainv1alpha1.Condition { + return toolchainv1alpha1.Condition{ + Type: toolchainv1alpha1.ConditionReady, + Status: corev1.ConditionFalse, + Reason: reason, + Message: cause, + } +} + func ReadyCondition() toolchainv1alpha1.Condition { return toolchainv1alpha1.Condition{ Type: toolchainv1alpha1.ConditionReady, diff --git a/controllers/nstemplatetier/nstemplatetier_controller_test.go b/controllers/nstemplatetier/nstemplatetier_controller_test.go index 72c5e7715..23aa79499 100644 --- a/controllers/nstemplatetier/nstemplatetier_controller_test.go +++ b/controllers/nstemplatetier/nstemplatetier_controller_test.go @@ -17,7 +17,6 @@ import ( templatev1 "github.com/openshift/api/template/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -280,12 +279,7 @@ func TestReconcile(t *testing.T) { // the revisions field also should remain empty tiertest.AssertThatNSTemplateTier(t, "base1ns", cl). HasConditions( - toolchainv1alpha1.Condition{ - Type: toolchainv1alpha1.ConditionReady, - Status: corev1.ConditionFalse, - Reason: toolchainv1alpha1.NSTemplateTierUnableToEnsureRevisionsReason, - Message: errCause, - }, + nstemplatetier.FailedCondition(toolchainv1alpha1.NSTemplateTierUnableToEnsureRevisionsReason, errCause), ). HasNoStatusTierTemplateRevisions() // and the TierTemplateRevision CRs are not created From 5e18a51ab95ee50bed58f00374eb2192f1e5e6f4 Mon Sep 17 00:00:00 2001 From: Devtools Date: Wed, 5 Mar 2025 12:16:54 +0100 Subject: [PATCH 5/5] Empty-Commit