diff --git a/pkg/registration/hub/importer/importer.go b/pkg/registration/hub/importer/importer.go index d7cf9f8d7..fa0e35599 100644 --- a/pkg/registration/hub/importer/importer.go +++ b/pkg/registration/hub/importer/importer.go @@ -2,6 +2,7 @@ package importer import ( "context" + "errors" "fmt" "github.com/openshift/api" @@ -13,7 +14,7 @@ import ( appsv1 "k8s.io/api/apps/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/api/errors" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -31,6 +32,7 @@ import ( operatorv1 "open-cluster-management.io/api/operator/v1" "open-cluster-management.io/sdk-go/pkg/patcher" + "open-cluster-management.io/ocm/pkg/common/helpers" "open-cluster-management.io/ocm/pkg/common/queue" "open-cluster-management.io/ocm/pkg/operator/helpers/chart" cloudproviders "open-cluster-management.io/ocm/pkg/registration/hub/importer/providers" @@ -100,7 +102,7 @@ func (i *Importer) sync(ctx context.Context, syncCtx factory.SyncContext) error cluster, err := i.clusterLister.Get(clusterName) switch { - case errors.IsNotFound(err): + case apierrors.IsNotFound(err): return nil case err != nil: return err @@ -130,15 +132,17 @@ func (i *Importer) sync(ctx context.Context, syncCtx factory.SyncContext) error if updatedErr != nil { return updatedErr } - if err != nil { - return err - } if updated { syncCtx.Recorder().Eventf( "ManagedClusterImported", "managed cluster %s is imported", clusterName) } + var rqe helpers.RequeueError + if err != nil && errors.As(err, &rqe) { + syncCtx.Queue().AddAfter(clusterName, rqe.RequeueTime) + return nil + } - return nil + return err } func (i *Importer) reconcile( @@ -259,7 +263,7 @@ func ApplyKlusterlet( recorder events.Recorder, required *operatorv1.Klusterlet) (*operatorv1.Klusterlet, bool, error) { existing, err := client.OperatorV1().Klusterlets().Get(ctx, required.Name, metav1.GetOptions{}) - if errors.IsNotFound(err) { + if apierrors.IsNotFound(err) { requiredCopy := required.DeepCopy() actual, err := client.OperatorV1().Klusterlets().Create(ctx, requiredCopy, metav1.CreateOptions{}) resourcehelper.ReportCreateEvent(recorder, required, err) diff --git a/pkg/registration/hub/importer/importer_test.go b/pkg/registration/hub/importer/importer_test.go index bc770e1a2..90019afc5 100644 --- a/pkg/registration/hub/importer/importer_test.go +++ b/pkg/registration/hub/importer/importer_test.go @@ -21,6 +21,7 @@ import ( clusterv1 "open-cluster-management.io/api/cluster/v1" "open-cluster-management.io/sdk-go/pkg/patcher" + "open-cluster-management.io/ocm/pkg/common/helpers" testingcommon "open-cluster-management.io/ocm/pkg/common/testing" "open-cluster-management.io/ocm/pkg/registration/hub/importer/providers" cloudproviders "open-cluster-management.io/ocm/pkg/registration/hub/importer/providers" @@ -70,6 +71,24 @@ func TestSync(t *testing.T) { testingcommon.AssertNoActions(t, actions) }, }, + { + name: "clients for remote cluster is not generated with requeue error", + provider: &fakeProvider{isOwned: true, noClients: true, kubeConfigErr: helpers.NewRequeueError("test", 1*time.Minute)}, + key: "cluster1", + cluster: &clusterv1.ManagedCluster{ObjectMeta: metav1.ObjectMeta{Name: "cluster1"}}, + validate: func(t *testing.T, actions []clienttesting.Action) { + testingcommon.AssertActions(t, actions, "patch") + patch := actions[0].(clienttesting.PatchAction).GetPatch() + managedCluster := &clusterv1.ManagedCluster{} + err := json.Unmarshal(patch, managedCluster) + if err != nil { + t.Fatal(err) + } + if !meta.IsStatusConditionFalse(managedCluster.Status.Conditions, ManagedClusterConditionImported) { + t.Errorf("expected managed cluster to be imported") + } + }, + }, { name: "clients for remote cluster is not generated", provider: &fakeProvider{isOwned: true, noClients: true}, diff --git a/pkg/registration/hub/importer/providers/capi/provider.go b/pkg/registration/hub/importer/providers/capi/provider.go index 28bdefcff..96956f544 100644 --- a/pkg/registration/hub/importer/providers/capi/provider.go +++ b/pkg/registration/hub/importer/providers/capi/provider.go @@ -24,6 +24,7 @@ import ( clusterinformerv1 "open-cluster-management.io/api/client/cluster/informers/externalversions/cluster/v1" clusterv1 "open-cluster-management.io/api/cluster/v1" + "open-cluster-management.io/ocm/pkg/common/helpers" "open-cluster-management.io/ocm/pkg/registration/hub/importer/providers" ) @@ -100,7 +101,7 @@ func (c *CAPIProvider) Clients(ctx context.Context, cluster *clusterv1.ManagedCl case apierrors.IsNotFound(err): logger.V(4).Info( "kubeconfig secret is not found", "name", name+"-kubeconfig", "namespace", namespace) - return nil, nil + return nil, helpers.NewRequeueError("kubeconfig secret is not found", 1*time.Minute) case err != nil: return nil, err } diff --git a/pkg/registration/hub/importer/providers/capi/provider_test.go b/pkg/registration/hub/importer/providers/capi/provider_test.go index b1c00bb29..75de0161b 100644 --- a/pkg/registration/hub/importer/providers/capi/provider_test.go +++ b/pkg/registration/hub/importer/providers/capi/provider_test.go @@ -98,7 +98,7 @@ func TestClients(t *testing.T) { cluster: &clusterv1.ManagedCluster{ObjectMeta: metav1.ObjectMeta{Name: "cluster1"}}, }, { - name: "capi cluster not provisionde", + name: "capi cluster not provisioned", cluster: &clusterv1.ManagedCluster{ObjectMeta: metav1.ObjectMeta{Name: "cluster1"}}, capiObjects: []runtime.Object{ testingcommon.NewUnstructuredWithContent("cluster.x-k8s.io/v1beta1", "Cluster", "cluster1", "cluster1", @@ -114,8 +114,15 @@ func TestClients(t *testing.T) { name: "secret not found", cluster: &clusterv1.ManagedCluster{ObjectMeta: metav1.ObjectMeta{Name: "cluster1"}}, capiObjects: []runtime.Object{ - testingcommon.NewUnstructured( - "cluster.x-k8s.io/v1beta1", "Cluster", "cluster1", "cluster1")}, + testingcommon.NewUnstructuredWithContent("cluster.x-k8s.io/v1beta1", "Cluster", "cluster1", "cluster1", + map[string]interface{}{ + "status": map[string]interface{}{ + "phase": "Provisioned", + }, + }, + ), + }, + expectErr: true, }, { name: "secret found with invalid key",