diff --git a/controllers/idler/idler_controller.go b/controllers/idler/idler_controller.go index 0d367b8e..38e462c4 100644 --- a/controllers/idler/idler_controller.go +++ b/controllers/idler/idler_controller.go @@ -56,7 +56,7 @@ type Reconciler struct { AllNamespacesClient client.Client ScalesClient scale.ScalesGetter DynamicClient dynamic.Interface - GetHostCluster cluster.GetHostClusterFunc + GetHostCluster cluster.GetClustersFunc Namespace string } @@ -195,8 +195,8 @@ func (r *Reconciler) ensureIdling(ctx context.Context, idler *toolchainv1alpha1. func (r *Reconciler) createNotification(ctx context.Context, idler *toolchainv1alpha1.Idler, appName string, appType string) error { log.FromContext(ctx).Info("Create Notification") //Get the HostClient - hostCluster, ok := r.GetHostCluster() - if !ok { + clusters := r.GetHostCluster() + if len(clusters) != 1 { return fmt.Errorf("unable to get the host cluster") } //check the condition on Idler if notification already sent, only create a notification if not created before @@ -204,7 +204,7 @@ func (r *Reconciler) createNotification(ctx context.Context, idler *toolchainv1a // notification already created return nil } - + hostCluster := clusters[0] notificationName := fmt.Sprintf("%s-%s", idler.Name, toolchainv1alpha1.NotificationTypeIdled) notification := &toolchainv1alpha1.Notification{} // Check if notification already exists in host diff --git a/controllers/idler/idler_controller_test.go b/controllers/idler/idler_controller_test.go index e6817f67..ed5982e9 100644 --- a/controllers/idler/idler_controller_test.go +++ b/controllers/idler/idler_controller_test.go @@ -323,7 +323,9 @@ func TestEnsureIdling(t *testing.T) { memberoperatortest.AssertThatIdler(t, idler.Name, cl). HasConditions(memberoperatortest.Running(), memberoperatortest.IdlerNotificationCreated()) //check the notification is actually created - hostCl, _ := reconciler.GetHostCluster() + allclustersCl := reconciler.GetHostCluster() + hostCl := allclustersCl[0] + notification := &toolchainv1alpha1.Notification{} err = hostCl.Client.Get(context.TODO(), types.NamespacedName{ Namespace: test.HostOperatorNs, @@ -841,7 +843,8 @@ func TestNotificationAppNameTypeForPods(t *testing.T) { HasConditions(memberoperatortest.Running()) } //check the notification is actually created - hostCl, _ := reconciler.GetHostCluster() + allclustersCl := reconciler.GetHostCluster() + hostCl := allclustersCl[0] notification := &toolchainv1alpha1.Notification{} err = hostCl.Client.Get(context.TODO(), types.NamespacedName{ Namespace: test.HostOperatorNs, @@ -887,7 +890,8 @@ func TestCreateNotification(t *testing.T) { require.NoError(t, err) require.True(t, condition.IsTrue(idler.Status.Conditions, toolchainv1alpha1.IdlerTriggeredNotificationCreated)) //check notification was created - hostCl, _ := reconciler.GetHostCluster() + allclustersCl := reconciler.GetHostCluster() + hostCl := allclustersCl[0] notification := toolchainv1alpha1.Notification{} err = hostCl.Client.Get(context.TODO(), types.NamespacedName{Name: "alex-stage-idled", Namespace: hostCl.OperatorNamespace}, ¬ification) require.NoError(t, err) @@ -1015,7 +1019,8 @@ func TestGetUserEmailFromMUR(t *testing.T) { nsTmplSet := newNSTmplSet(test.MemberOperatorNs, "alex", "advanced", "abcde11", namespaces, usernames) mur := newMUR("alex") reconciler, _, _, _, _ := prepareReconcile(t, idler.Name, getHostCluster, idler, nsTmplSet, mur) - hostCluster, _ := reconciler.GetHostCluster() + allclustersCl := reconciler.GetHostCluster() + hostCluster := allclustersCl[0] //when emails, err := reconciler.getUserEmailsFromMURs(context.TODO(), hostCluster, idler) //then @@ -1034,7 +1039,8 @@ func TestGetUserEmailFromMUR(t *testing.T) { mur2 := newMUR("brian") mur3 := newMUR("charlie") reconciler, _, _, _, _ := prepareReconcile(t, idler.Name, getHostCluster, idler, nsTmplSet, mur, mur2, mur3) - hostCluster, _ := reconciler.GetHostCluster() + allclustersCl := reconciler.GetHostCluster() + hostCluster := allclustersCl[0] //when emails, err := reconciler.getUserEmailsFromMURs(context.TODO(), hostCluster, idler) //then @@ -1049,7 +1055,8 @@ func TestGetUserEmailFromMUR(t *testing.T) { t.Run("unable to get NSTemplateSet", func(t *testing.T) { //given reconciler, _, _, _, _ := prepareReconcile(t, idler.Name, getHostCluster, idler) - hostCluster, _ := reconciler.GetHostCluster() + allclustersCl := reconciler.GetHostCluster() + hostCluster := allclustersCl[0] //when emails, err := reconciler.getUserEmailsFromMURs(context.TODO(), hostCluster, idler) //then @@ -1063,7 +1070,8 @@ func TestGetUserEmailFromMUR(t *testing.T) { usernames := []string{"alex"} nsTmplSet := newNSTmplSet(test.MemberOperatorNs, "alex", "advanced", "abcde11", namespaces, usernames) reconciler, _, _, _, _ := prepareReconcile(t, idler.Name, getHostCluster, idler, nsTmplSet) - hostCluster, _ := reconciler.GetHostCluster() + allclustersCl := reconciler.GetHostCluster() + hostCluster := allclustersCl[0] //when emails, err := reconciler.getUserEmailsFromMURs(context.TODO(), hostCluster, idler) //then @@ -1327,7 +1335,7 @@ func createPods(t *testing.T, r *Reconciler, owner metav1.Object, startTime meta return podsToTrack } -func prepareReconcile(t *testing.T, name string, getHostClusterFunc func(fakeClient client.Client) cluster.GetHostClusterFunc, initIdlerObjs ...runtime.Object) (*Reconciler, reconcile.Request, *test.FakeClient, *test.FakeClient, *fakedynamic.FakeDynamicClient) { +func prepareReconcile(t *testing.T, name string, getHostClusterFunc func(fakeClient client.Client) cluster.GetClustersFunc, initIdlerObjs ...runtime.Object) (*Reconciler, reconcile.Request, *test.FakeClient, *test.FakeClient, *fakedynamic.FakeDynamicClient) { s := scheme.Scheme err := apis.AddToScheme(s) require.NoError(t, err) @@ -1415,7 +1423,7 @@ func prepareReconcileWithPodsRunningTooLong(t *testing.T, idler toolchainv1alpha return reconciler, req, cl, allCl, dynamicClient } -func getHostCluster(fakeClient client.Client) cluster.GetHostClusterFunc { +func getHostCluster(fakeClient client.Client) cluster.GetClustersFunc { return memberoperatortest.NewGetHostCluster(fakeClient, true, corev1.ConditionTrue) } diff --git a/controllers/memberstatus/memberstatus_controller.go b/controllers/memberstatus/memberstatus_controller.go index 12d78040..56deebc1 100644 --- a/controllers/memberstatus/memberstatus_controller.go +++ b/controllers/memberstatus/memberstatus_controller.go @@ -61,7 +61,7 @@ func (r *Reconciler) SetupWithManager(mgr manager.Manager) error { type Reconciler struct { Client client.Client Scheme *runtime.Scheme - GetHostCluster func() (*cluster.CachedToolchainCluster, bool) + GetHostCluster cluster.GetClustersFunc AllNamespacesClient client.Client VersionCheckManager status.VersionCheckManager } @@ -150,9 +150,9 @@ func (r *Reconciler) aggregateAndUpdateStatus(ctx context.Context, memberStatus func (r *Reconciler) hostConnectionHandleStatus(ctx context.Context, memberStatus *toolchainv1alpha1.MemberStatus, config membercfg.Configuration) error { attributes := status.ToolchainClusterAttributes{ - GetClusterFunc: r.GetHostCluster, - Period: config.ToolchainCluster().HealthCheckPeriod(), - Timeout: config.ToolchainCluster().HealthCheckTimeout(), + GetClustersFunc: r.GetHostCluster, + Period: config.ToolchainCluster().HealthCheckPeriod(), + Timeout: config.ToolchainCluster().HealthCheckTimeout(), } // look up host connection status diff --git a/controllers/memberstatus/memberstatus_controller_test.go b/controllers/memberstatus/memberstatus_controller_test.go index bc74223f..3d8ffbce 100644 --- a/controllers/memberstatus/memberstatus_controller_test.go +++ b/controllers/memberstatus/memberstatus_controller_test.go @@ -695,26 +695,26 @@ func newMemberDeploymentWithConditions(deploymentConditions ...appsv1.Deployment } } -func newGetHostClusterReady(fakeClient client.Client) cluster.GetHostClusterFunc { +func newGetHostClusterReady(fakeClient client.Client) cluster.GetClustersFunc { return NewGetHostClusterWithProbe(fakeClient, true, corev1.ConditionTrue, metav1.Now()) } -func newGetHostClusterNotReady(fakeClient client.Client) cluster.GetHostClusterFunc { +func newGetHostClusterNotReady(fakeClient client.Client) cluster.GetClustersFunc { return NewGetHostClusterWithProbe(fakeClient, true, corev1.ConditionFalse, metav1.Now()) } -func newGetHostClusterProbeNotWorking(fakeClient client.Client) cluster.GetHostClusterFunc { +func newGetHostClusterProbeNotWorking(fakeClient client.Client) cluster.GetClustersFunc { aMinuteAgo := metav1.Time{ Time: time.Now().Add(time.Duration(-60 * time.Second)), } return NewGetHostClusterWithProbe(fakeClient, true, corev1.ConditionTrue, aMinuteAgo) } -func newGetHostClusterNotExist(fakeClient client.Client) cluster.GetHostClusterFunc { +func newGetHostClusterNotExist(fakeClient client.Client) cluster.GetClustersFunc { return NewGetHostClusterWithProbe(fakeClient, false, corev1.ConditionFalse, metav1.Now()) } -func prepareReconcile(t *testing.T, requestName string, getHostClusterFunc func(fakeClient client.Client) cluster.GetHostClusterFunc, allNamespacesClient *test.FakeClient, lastGitHubAPICall time.Time, mockedGitHubClient commonclient.GetGitHubClientFunc, initObjs ...runtime.Object) (*Reconciler, reconcile.Request, *test.FakeClient) { +func prepareReconcile(t *testing.T, requestName string, getHostClusterFunc func(fakeClient client.Client) cluster.GetClustersFunc, allNamespacesClient *test.FakeClient, lastGitHubAPICall time.Time, mockedGitHubClient commonclient.GetGitHubClientFunc, initObjs ...runtime.Object) (*Reconciler, reconcile.Request, *test.FakeClient) { logf.SetLogger(zap.New(zap.UseDevMode(true))) os.Setenv("WATCH_NAMESPACE", test.MemberOperatorNs) fakeClient := test.NewFakeClient(t, initObjs...) diff --git a/controllers/nstemplateset/client.go b/controllers/nstemplateset/client.go index 33f7b6cc..1fbd70c0 100644 --- a/controllers/nstemplateset/client.go +++ b/controllers/nstemplateset/client.go @@ -19,7 +19,7 @@ type APIClient struct { AllNamespacesClient runtimeclient.Client Client runtimeclient.Client Scheme *runtime.Scheme - GetHostCluster cluster.GetHostClusterFunc + GetHostCluster cluster.GetClustersFunc AvailableAPIGroups []metav1.APIGroup } diff --git a/controllers/nstemplateset/nstemplatetier.go b/controllers/nstemplateset/nstemplatetier.go index 1c937e24..2371fe61 100644 --- a/controllers/nstemplateset/nstemplatetier.go +++ b/controllers/nstemplateset/nstemplatetier.go @@ -23,7 +23,7 @@ var tierTemplatesCache = newTierTemplateCache() // getTierTemplate retrieves the TierTemplate resource with the given name from the host cluster // and returns an instance of the tierTemplate type for it whose template content can be parsable. // The returned tierTemplate contains all data from TierTemplate including its name. -func getTierTemplate(ctx context.Context, hostClusterFunc cluster.GetHostClusterFunc, templateRef string) (*tierTemplate, error) { +func getTierTemplate(ctx context.Context, hostClusterFunc cluster.GetClustersFunc, templateRef string) (*tierTemplate, error) { if templateRef == "" { return nil, fmt.Errorf("templateRef is not provided - it's not possible to fetch related TierTemplate resource") } @@ -46,12 +46,14 @@ func getTierTemplate(ctx context.Context, hostClusterFunc cluster.GetHostCluster } // getToolchainTierTemplate gets the TierTemplate resource from the host cluster. -func getToolchainTierTemplate(ctx context.Context, hostClusterFunc cluster.GetHostClusterFunc, templateRef string) (*toolchainv1alpha1.TierTemplate, error) { +func getToolchainTierTemplate(ctx context.Context, hostClusterFunc cluster.GetClustersFunc, templateRef string) (*toolchainv1alpha1.TierTemplate, error) { // retrieve the ToolchainCluster instance representing the host cluster - host, ok := hostClusterFunc() - if !ok { + clusters := hostClusterFunc() + if len(clusters) != 1 { return nil, fmt.Errorf("unable to connect to the host cluster: unknown cluster") } + + host := clusters[0] if !cluster.IsReady(host.ClusterStatus) { return nil, fmt.Errorf("the host cluster is not ready") } diff --git a/go.mod b/go.mod index 3d56696c..56bf6cb8 100644 --- a/go.mod +++ b/go.mod @@ -110,3 +110,5 @@ require ( ) go 1.20 + +replace github.com/codeready-toolchain/toolchain-common => ../toolchain-common diff --git a/go.sum b/go.sum index f7e95c4d..cc0b1ac3 100644 --- a/go.sum +++ b/go.sum @@ -136,8 +136,6 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/codeready-toolchain/api v0.0.0-20240227210924-371ddb054d87 h1:eQLsrMqfjAzGfuO9t6pVxO4K6cUDKOMxEvl0ujQq/2I= github.com/codeready-toolchain/api v0.0.0-20240227210924-371ddb054d87/go.mod h1:FO7kgXH1x1LqkF327D5a36u0WIrwjVCbeijPkzgwaZc= -github.com/codeready-toolchain/toolchain-common v0.0.0-20240313081501-5cafefaa6598 h1:06nit/nCQFVKp51ZtIOyY49ncmxEK5shJGTaM+Ogicw= -github.com/codeready-toolchain/toolchain-common v0.0.0-20240313081501-5cafefaa6598/go.mod h1:c2JxboVI7keMD5fx5bB7LwzowFYYTwbepJhzPWSYXVs= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= diff --git a/main.go b/main.go index 68c8d3a4..9fbeb760 100644 --- a/main.go +++ b/main.go @@ -218,7 +218,7 @@ func main() { Client: mgr.GetClient(), ScalesClient: scalesClient, DynamicClient: dynamicClient, - GetHostCluster: cluster.GetHostCluster, + GetHostCluster: cluster.GetClusters, Namespace: namespace, }).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "Idler") @@ -228,7 +228,7 @@ func main() { if err = (&memberstatus.Reconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), - GetHostCluster: cluster.GetHostCluster, + GetHostCluster: cluster.GetClusters, AllNamespacesClient: allNamespacesClient, VersionCheckManager: status.VersionCheckManager{GetGithubClientFunc: commonclient.NewGitHubClient}, }).SetupWithManager(mgr); err != nil { @@ -239,7 +239,7 @@ func main() { Client: mgr.GetClient(), AllNamespacesClient: allNamespacesClient, Scheme: mgr.GetScheme(), - GetHostCluster: cluster.GetHostCluster, + GetHostCluster: cluster.GetClusters, })).SetupWithManager(mgr, allNamespacesCluster, discoveryClient); err != nil { setupLog.Error(err, "unable to create controller", "controller", "NSTemplateSet") os.Exit(1) diff --git a/test/cluster.go b/test/cluster.go index 1c46ec73..c694ecaa 100644 --- a/test/cluster.go +++ b/test/cluster.go @@ -14,14 +14,14 @@ import ( // NewGetHostCluster returns cluster.GetHostClusterFunc function. The cluster.CachedToolchainCluster // that is returned by the function then contains the given client and the given status. // If ok == false, then the function returns nil for the cluster. -func NewGetHostCluster(cl client.Client, ok bool, status v1.ConditionStatus) cluster.GetHostClusterFunc { +func NewGetHostCluster(cl client.Client, ok bool, status v1.ConditionStatus) cluster.GetClustersFunc { if !ok { - return func() (*cluster.CachedToolchainCluster, bool) { - return nil, false + return func(conditions ...cluster.Condition) []*cluster.CachedToolchainCluster { + return nil } } - return func() (toolchainCluster *cluster.CachedToolchainCluster, b bool) { - return &cluster.CachedToolchainCluster{ + return func(conditions ...cluster.Condition) []*cluster.CachedToolchainCluster { + return []*cluster.CachedToolchainCluster{{ Config: &cluster.Config{ OperatorNamespace: test.HostOperatorNs, OwnerClusterName: test.MemberClusterName, @@ -33,7 +33,7 @@ func NewGetHostCluster(cl client.Client, ok bool, status v1.ConditionStatus) clu Status: status, }}, }, - }, true + }} } } @@ -41,14 +41,14 @@ func NewGetHostCluster(cl client.Client, ok bool, status v1.ConditionStatus) clu // NewGetHostClusterWithProbe returns a cluster.GetHostClusterFunc function which returns a cluster.CachedToolchainCluster. // The returned cluster.CachedToolchainCluster contains the given client and the given status and lastProbeTime. // If ok == false, then the function returns nil for the cluster. -func NewGetHostClusterWithProbe(cl client.Client, ok bool, status v1.ConditionStatus, lastProbeTime metav1.Time) cluster.GetHostClusterFunc { +func NewGetHostClusterWithProbe(cl client.Client, ok bool, status v1.ConditionStatus, lastProbeTime metav1.Time) cluster.GetClustersFunc { if !ok { - return func() (*cluster.CachedToolchainCluster, bool) { - return nil, false + return func(conditions ...cluster.Condition) []*cluster.CachedToolchainCluster { + return nil } } - return func() (toolchainCluster *cluster.CachedToolchainCluster, b bool) { - return &cluster.CachedToolchainCluster{ + return func(conditions ...cluster.Condition) []*cluster.CachedToolchainCluster { + return []*cluster.CachedToolchainCluster{{ Config: &cluster.Config{ OperatorNamespace: test.HostOperatorNs, OwnerClusterName: test.MemberClusterName, @@ -61,7 +61,7 @@ func NewGetHostClusterWithProbe(cl client.Client, ok bool, status v1.ConditionSt LastProbeTime: lastProbeTime, }}, }, - }, true + }} } }