From f76db506e379cf4f3722ccd85ec20c471d114be1 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Tue, 10 Dec 2024 12:39:51 +0100 Subject: [PATCH] Refactor the code to update the gitea password post reconciliation. #441 Signed-off-by: cmoulliard --- pkg/controllers/gitrepository/controller.go | 4 ++ pkg/controllers/gitrepository/gitea.go | 1 + pkg/controllers/localbuild/controller.go | 69 +++++++++++++++++++-- pkg/controllers/localbuild/gitea.go | 39 +++++------- 4 files changed, 83 insertions(+), 30 deletions(-) diff --git a/pkg/controllers/gitrepository/controller.go b/pkg/controllers/gitrepository/controller.go index 6a303494..f9a08ff2 100644 --- a/pkg/controllers/gitrepository/controller.go +++ b/pkg/controllers/gitrepository/controller.go @@ -143,6 +143,10 @@ func (r *RepositoryReconciler) reconcileGitRepo(ctx context.Context, repo *v1alp return ctrl.Result{}, fmt.Errorf("getting git provider credentials: %w", err) } + if r.Config.DevMode { + creds.password = "developer" + } + err = provider.setProviderCredentials(ctx, repo, creds) if err != nil { return ctrl.Result{}, fmt.Errorf("setting git provider credentials: %w", err) diff --git a/pkg/controllers/gitrepository/gitea.go b/pkg/controllers/gitrepository/gitea.go index de82970f..a19a433f 100644 --- a/pkg/controllers/gitrepository/gitea.go +++ b/pkg/controllers/gitrepository/gitea.go @@ -69,6 +69,7 @@ func (g *giteaProvider) getProviderCredentials(ctx context.Context, repo *v1alph if !ok { return gitProviderCredentials{}, fmt.Errorf("%s key not found in secret %s in %s ns", giteaAdminPasswordKey, repo.Spec.SecretRef.Name, repo.Spec.SecretRef.Namespace) } + return gitProviderCredentials{ username: string(username), password: string(password), diff --git a/pkg/controllers/localbuild/controller.go b/pkg/controllers/localbuild/controller.go index 96c0f9a8..10f0df30 100644 --- a/pkg/controllers/localbuild/controller.go +++ b/pkg/controllers/localbuild/controller.go @@ -2,6 +2,7 @@ package localbuild import ( "bytes" + "code.gitea.io/sdk/gitea" "context" "encoding/json" "fmt" @@ -45,7 +46,8 @@ const ( ) var ( - status = "failed" + argocdPasswordChangeStatus = "failed" + giteaPasswordChangeStatus = "failed" ) type ArgocdSession struct { @@ -104,7 +106,9 @@ func (r *LocalbuildReconciler) Reconcile(ctx context.Context, req ctrl.Request) if r.Config.DevMode { logger.Info("DevMode is enabled") - initialPassword, err := r.extractArgocdInitialAdminSecret(ctx) + + // Check if the Argocd Initial admin secret exists + argocdInitialAdminPassword, err := r.extractArgocdInitialAdminSecret(ctx) if err != nil { // Argocd initial admin secret is not yet available ... return ctrl.Result{RequeueAfter: defaultRequeueTime}, nil @@ -114,12 +118,30 @@ func (r *LocalbuildReconciler) Reconcile(ctx context.Context, req ctrl.Request) // Secret containing the initial argocd password exists // Lets try to update the password - if initialPassword != "" && status == "failed" { - err, status = r.updateDevPassword(ctx, initialPassword) + if argocdInitialAdminPassword != "" && argocdPasswordChangeStatus == "failed" { + err, argocdPasswordChangeStatus = r.updateArgocdDevPassword(ctx, argocdInitialAdminPassword) if err != nil { return ctrl.Result{}, err } else { - logger.Info(fmt.Sprintf("Argocd admin password change %s !", status)) + logger.Info(fmt.Sprintf("Argocd admin password change %s !", argocdPasswordChangeStatus)) + } + } + + // Check if the Gitea credentials secret exists + giteaAdminPassword, err := r.extractGiteaAdminSecret(ctx) + if err != nil { + // Gitea admin secret is not yet available ... + return ctrl.Result{RequeueAfter: defaultRequeueTime}, nil + } + logger.Info("Gitea admin secret found ...") + // Secret containing the gitea password exists + // Lets try to update the password + if giteaAdminPassword != "" && giteaPasswordChangeStatus == "failed" { + err, giteaPasswordChangeStatus = r.updateGiteaDevPassword(ctx, giteaAdminPassword) + if err != nil { + return ctrl.Result{}, err + } else { + logger.Info(fmt.Sprintf("Gitea admin password change %s !", giteaPasswordChangeStatus)) } } } @@ -631,7 +653,42 @@ func (r *LocalbuildReconciler) extractArgocdInitialAdminSecret(ctx context.Conte return string(sec.Data["password"]), nil } -func (r *LocalbuildReconciler) updateDevPassword(ctx context.Context, adminPassword string) (error, string) { +func (r *LocalbuildReconciler) extractGiteaAdminSecret(ctx context.Context) (string, error) { + sec := r.GiteaAdminSecretObject() + err := r.Client.Get(ctx, types.NamespacedName{ + Namespace: sec.GetNamespace(), + Name: sec.GetName(), + }, &sec) + + if err != nil { + if k8serrors.IsNotFound(err) { + return "", fmt.Errorf("gitea admin secret not found") + } + } + return string(sec.Data["password"]), nil +} + +func (r *LocalbuildReconciler) updateGiteaDevPassword(ctx context.Context, adminPassword string) (error, string) { + client, err := gitea.NewClient(r.GiteaBaseUrl(r.Config), gitea.SetHTTPClient(util.GetHttpClient()), + gitea.SetBasicAuth("giteaAdmin", adminPassword), gitea.SetContext(ctx), + ) + if err != nil { + return fmt.Errorf("cannot create gitea client: %w", err), "failed" + } + + opts := gitea.EditUserOption{ + LoginName: "giteaAdmin", + Password: "developer", + } + + resp, err := client.AdminEditUser("giteaAdmin", opts) + if err != nil { + return fmt.Errorf("cannot update gitea admin user: %w", resp.StatusCode, err), "failed" + } + return nil, "succeeded" +} + +func (r *LocalbuildReconciler) updateArgocdDevPassword(ctx context.Context, adminPassword string) (error, string) { argocdEndpoint := r.ArgocdBaseUrl(r.Config) + "/api/v1" payload := map[string]string{ diff --git a/pkg/controllers/localbuild/gitea.go b/pkg/controllers/localbuild/gitea.go index 38064ca3..292d5ec3 100644 --- a/pkg/controllers/localbuild/gitea.go +++ b/pkg/controllers/localbuild/gitea.go @@ -45,7 +45,7 @@ func RawGiteaInstallResources(templateData any, config v1alpha1.PackageCustomiza return k8s.BuildCustomizedManifests(config.FilePath, "resources/gitea/k8s", installGiteaFS, scheme, templateData) } -func giteaAdminSecretObject() corev1.Secret { +func (r *LocalbuildReconciler) GiteaAdminSecretObject() corev1.Secret { return corev1.Secret{ TypeMeta: metav1.TypeMeta{ Kind: "Secret", @@ -58,27 +58,13 @@ func giteaAdminSecretObject() corev1.Secret { } } -func newGiteaAdminSecret(devMode bool) (corev1.Secret, error) { - pass := giteaDevModePassword - // TODO: Reverting to giteaAdmin till we know why a different user - developer fails - userName := v1alpha1.GiteaAdminUserName - - if !devMode { - var err error - pass, err = util.GeneratePassword() - if err != nil { - return corev1.Secret{}, err - } - - userName = v1alpha1.GiteaAdminUserName - } - - obj := giteaAdminSecretObject() +func (r *LocalbuildReconciler) newGiteaAdminSecret(password string) corev1.Secret { + obj := r.GiteaAdminSecretObject() obj.StringData = map[string]string{ - "username": userName, - "password": pass, + "username": v1alpha1.GiteaAdminUserName, + "password": password, } - return obj, nil + return obj } func (r *LocalbuildReconciler) ReconcileGitea(ctx context.Context, req ctrl.Request, resource *v1alpha1.Localbuild) (ctrl.Result, error) { @@ -97,7 +83,7 @@ func (r *LocalbuildReconciler) ReconcileGitea(ctx context.Context, req ctrl.Requ }, } - sec := giteaAdminSecretObject() + sec := r.GiteaAdminSecretObject() err := r.Client.Get(ctx, types.NamespacedName{ Namespace: sec.GetNamespace(), Name: sec.GetName(), @@ -105,7 +91,12 @@ func (r *LocalbuildReconciler) ReconcileGitea(ctx context.Context, req ctrl.Requ if err != nil { if k8serrors.IsNotFound(err) { - giteaCreds, err := newGiteaAdminSecret(r.Config.DevMode) + genPassword, err := util.GeneratePassword() + if err != nil { + return ctrl.Result{}, fmt.Errorf("generating gitea password: %w", err) + } + + giteaCreds := r.newGiteaAdminSecret(genPassword) if err != nil { return ctrl.Result{}, fmt.Errorf("generating gitea admin secret: %w", err) } @@ -125,7 +116,7 @@ func (r *LocalbuildReconciler) ReconcileGitea(ctx context.Context, req ctrl.Requ return result, err } - baseUrl := giteaBaseUrl(r.Config) + baseUrl := r.GiteaBaseUrl(r.Config) // need this to ensure gitrepository controller can reach the api endpoint. logger.V(1).Info("checking gitea api endpoint", "url", baseUrl) c := util.GetHttpClient() @@ -224,7 +215,7 @@ func getGiteaToken(ctx context.Context, baseUrl, username, password string) (str return token.Token, nil } -func giteaBaseUrl(config v1alpha1.BuildCustomizationSpec) string { +func (r *LocalbuildReconciler) GiteaBaseUrl(config v1alpha1.BuildCustomizationSpec) string { return fmt.Sprintf(giteaIngressURL, config.Protocol, config.Port) }