From 5e0ffa84691d8d7dbbe94d99249a326294ca71eb Mon Sep 17 00:00:00 2001 From: Logan McNaughton <848146+loganmc10@users.noreply.github.com> Date: Wed, 5 Jul 2023 13:07:30 -0600 Subject: [PATCH] more --- internal/acm/reconcile.go | 43 +++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/internal/acm/reconcile.go b/internal/acm/reconcile.go index 141f942..0d86c12 100644 --- a/internal/acm/reconcile.go +++ b/internal/acm/reconcile.go @@ -13,6 +13,7 @@ import ( agentv1 "github.com/stolostron/klusterlet-addon-controller/pkg/apis/agent/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" + apimeta "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/util/yaml" @@ -33,18 +34,36 @@ import ( //+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterrolebindings,verbs=create //+kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=create +// returns nil if the Klusterlet is Available, error otherwise +func checkKlusterlet(ctx context.Context, c client.Client, logger logr.Logger) error { + klusterlet := &operatorapiv1.Klusterlet{} + err := c.Get(ctx, types.NamespacedName{Name: "klusterlet"}, klusterlet) + if err == nil { + klusterletCondition := apimeta.FindStatusCondition(klusterlet.Status.Conditions, "Available") + if klusterletCondition.Status == metav1.ConditionTrue { + logger.Info("cluster registered to ACM") + } else { + return fmt.Errorf("cluster not registered to ACM") + } + } + return err +} + func Reconcile(ctx context.Context, c client.Client, scheme *runtime.Scheme, relocation *rhsysenggithubiov1beta1.ClusterRelocation, logger logr.Logger) error { if relocation.Spec.ACMRegistration == nil { return nil } - klusterlet := &operatorapiv1.Klusterlet{} - if err := c.Get(ctx, types.NamespacedName{Name: "klusterlet"}, klusterlet); err == nil { - // TODO: ensure klusterlet status is good - logger.Info("cluster already registered to ACM") + // skip these steps if the cluster is already registered to ACM + if checkKlusterlet(ctx, c, logger) == nil { return nil } + // the tokenSecret holds the credentials for the ACM cluster + // these credentials should allow the following: + // Creating ManagedClusters (these are cluster scoped resources) + // Creating KlusterletAddonConfigs (these are namespace scoped resources) + // Getting Secrets (these are namespace scoped resources) tokenSecret := &corev1.Secret{} if err := c.Get(ctx, types.NamespacedName{Name: relocation.Spec.ACMRegistration.TokenRef.Name, Namespace: relocation.Spec.ACMRegistration.TokenRef.Namespace}, tokenSecret); err != nil { return err @@ -88,6 +107,7 @@ func Reconcile(ctx context.Context, c client.Client, scheme *runtime.Scheme, rel break } + // the import secret that we obtained from the ACM cluster contains YAML manifests that need to be applied here d := yaml.NewYAMLToJSONDecoder(bytes.NewReader(importSecret.Data["crds.yaml"])) for { klusterletCRDObj := &unstructured.Unstructured{} @@ -109,6 +129,7 @@ func Reconcile(ctx context.Context, c client.Client, scheme *runtime.Scheme, rel } } + // the import secret that we obtained from the ACM cluster contains YAML manifests that need to be applied here d = yaml.NewYAMLToJSONDecoder(bytes.NewReader(importSecret.Data["import.yaml"])) for { importObj := &unstructured.Unstructured{} @@ -145,7 +166,17 @@ func Reconcile(ctx context.Context, c client.Client, scheme *runtime.Scheme, rel } } - // TODO: wait for klusterlet to finish deploying + // wait for the Klusterlet to become Available + startTime := time.Now() + for { + if checkKlusterlet(ctx, c, logger) == nil { + return nil + } + time.Sleep(time.Second * 10) - return nil + // we set a 5 minute timeout in case the Klusterlet never gets to Available + if time.Since(startTime) > time.Minute*5 { + return fmt.Errorf("klusterlet error") + } + } }