From f67a91c0423316ed668b1915e1e201d2f4cad516 Mon Sep 17 00:00:00 2001 From: cmoulliard Date: Wed, 11 Dec 2024 18:46:53 +0100 Subject: [PATCH] Regenerate the token for gitea Signed-off-by: cmoulliard --- pkg/controllers/localbuild/controller.go | 4 +- pkg/controllers/localbuild/gitea.go | 38 +---------------- pkg/util/argocd.go | 1 + pkg/util/gitea.go | 54 +++++++++++++++++++++++- 4 files changed, 57 insertions(+), 40 deletions(-) diff --git a/pkg/controllers/localbuild/controller.go b/pkg/controllers/localbuild/controller.go index 4a26738f..6c1c5994 100644 --- a/pkg/controllers/localbuild/controller.go +++ b/pkg/controllers/localbuild/controller.go @@ -686,7 +686,7 @@ func (r *LocalbuildReconciler) updateGiteaDevPassword(ctx context.Context, admin return fmt.Errorf("cannot update gitea admin user. status: %d error : %w", resp.StatusCode, err), "failed" } - err = util.PatchPasswordSecret(ctx, r.Client, util.GiteaNamespace, util.GiteaAdminSecret, "developer") + err = util.PatchPasswordSecret(ctx, r.Client, r.Config, util.GiteaNamespace, util.GiteaAdminSecret, util.GiteaAdminName, "developer") if err != nil { return fmt.Errorf("patching the gitea credentials failed : %w", err), "failed" } @@ -787,7 +787,7 @@ func (r *LocalbuildReconciler) updateArgocdDevPassword(ctx context.Context, admi // Password verification succeeded ! if resp.StatusCode == 200 { // Let's patch the existing secret now - err = util.PatchPasswordSecret(ctx, r.Client, util.ArgocdNamespace, util.ArgocdInitialAdminSecretName, "developer") + err = util.PatchPasswordSecret(ctx, r.Client, r.Config, util.ArgocdNamespace, util.ArgocdInitialAdminSecretName, util.ArgocdAdminName, "developer") if err != nil { return fmt.Errorf("patching the argocd initial secret failed : %w", err), "failed" } diff --git a/pkg/controllers/localbuild/gitea.go b/pkg/controllers/localbuild/gitea.go index c7b28ab8..83c75f30 100644 --- a/pkg/controllers/localbuild/gitea.go +++ b/pkg/controllers/localbuild/gitea.go @@ -7,7 +7,6 @@ import ( "fmt" "net/http" - "code.gitea.io/sdk/gitea" "github.com/cnoe-io/idpbuilder/api/v1alpha1" "github.com/cnoe-io/idpbuilder/pkg/k8s" "github.com/cnoe-io/idpbuilder/pkg/util" @@ -137,7 +136,7 @@ func (r *LocalbuildReconciler) setGiteaToken(ctx context.Context, secret corev1. return fmt.Errorf("password field not found in gitea secret") } - t, err := getGiteaToken(ctx, baseUrl, string(user), string(pass)) + t, err := util.GetGiteaToken(ctx, baseUrl, string(user), string(pass)) if err != nil { return fmt.Errorf("getting gitea token: %w", err) } @@ -151,41 +150,6 @@ func (r *LocalbuildReconciler) setGiteaToken(ctx context.Context, secret corev1. return r.Client.Patch(ctx, &u, client.Apply, client.ForceOwnership, client.FieldOwner(v1alpha1.FieldManager)) } -func getGiteaToken(ctx context.Context, baseUrl, username, password string) (string, error) { - giteaClient, err := gitea.NewClient(baseUrl, gitea.SetHTTPClient(util.GetHttpClient()), - gitea.SetBasicAuth(username, password), gitea.SetContext(ctx), - ) - if err != nil { - return "", fmt.Errorf("creating gitea client: %w", err) - } - tokens, resp, err := giteaClient.ListAccessTokens(gitea.ListAccessTokensOptions{}) - if err != nil { - return "", fmt.Errorf("listing gitea access tokens. status: %s error : %w", resp.Status, err) - } - - for i := range tokens { - if tokens[i].Name == util.GiteaAdminTokenName { - resp, err := giteaClient.DeleteAccessToken(tokens[i].ID) - if err != nil { - return "", fmt.Errorf("deleting gitea access tokens. status: %s error : %w", resp.Status, err) - } - break - } - } - - token, resp, err := giteaClient.CreateAccessToken(gitea.CreateAccessTokenOption{ - Name: util.GiteaAdminTokenName, - Scopes: []gitea.AccessTokenScope{ - gitea.AccessTokenScopeAll, - }, - }) - if err != nil { - return "", fmt.Errorf("deleting gitea access tokens. status: %s error : %w", resp.Status, err) - } - - return token.Token, nil -} - // gitea URL reachable within the cluster with proper coredns config. Mainly for argocd func giteaInternalBaseUrl(config v1alpha1.BuildCustomizationSpec) string { if config.UsePathRouting { diff --git a/pkg/util/argocd.go b/pkg/util/argocd.go index 6f5952cb..1ef8a13e 100644 --- a/pkg/util/argocd.go +++ b/pkg/util/argocd.go @@ -8,6 +8,7 @@ import ( const ( ArgocdDevModePassword = "developer" ArgocdInitialAdminSecretName = "argocd-initial-admin-secret" + ArgocdAdminName = "admin" ArgocdNamespace = "argocd" ArgocdIngressURL = "%s://argocd.cnoe.localtest.me:%s" ) diff --git a/pkg/util/gitea.go b/pkg/util/gitea.go index 7fad3d7d..43dda037 100644 --- a/pkg/util/gitea.go +++ b/pkg/util/gitea.go @@ -1,6 +1,7 @@ package util import ( + "code.gitea.io/sdk/gitea" "context" "encoding/base64" "fmt" @@ -9,12 +10,14 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/controller-runtime/pkg/client" + "strings" ) const ( // hardcoded values from what we have in the yaml installation file. GiteaNamespace = "gitea" GiteaAdminSecret = "gitea-credential" + GiteaAdminName = "giteaAdmin" GiteaAdminTokenName = "admin" GiteaAdminTokenFieldName = "token" // this is the URL accessible outside cluster. resolves to localhost @@ -37,7 +40,7 @@ func GiteaAdminSecretObject() corev1.Secret { } } -func PatchPasswordSecret(ctx context.Context, kubeClient client.Client, ns string, secretName string, pass string) error { +func PatchPasswordSecret(ctx context.Context, kubeClient client.Client, config v1alpha1.BuildCustomizationSpec, ns string, secretName string, username string, pass string) error { sec, err := GetSecretByName(ctx, kubeClient, ns, secretName) if err != nil { return fmt.Errorf("getting secret to patch fails: %w", err) @@ -52,9 +55,58 @@ func PatchPasswordSecret(ctx context.Context, kubeClient client.Client, ns strin return fmt.Errorf("setting password field: %w", err) } + if strings.Contains(secretName, "gitea") { + // We should recreate a token as user/password changed + t, err := GetGiteaToken(ctx, GiteaBaseUrl(config), string(username), string(pass)) + if err != nil { + return fmt.Errorf("getting gitea token: %w", err) + } + + token := base64.StdEncoding.EncodeToString([]byte(t)) + err = unstructured.SetNestedField(u.Object, token, "data", GiteaAdminTokenFieldName) + if err != nil { + return fmt.Errorf("setting gitea token field: %w", err) + } + } + return kubeClient.Patch(ctx, &u, client.Apply, client.ForceOwnership, client.FieldOwner(v1alpha1.FieldManager)) } +func GetGiteaToken(ctx context.Context, baseUrl, username, password string) (string, error) { + giteaClient, err := gitea.NewClient(baseUrl, gitea.SetHTTPClient(GetHttpClient()), + gitea.SetBasicAuth(username, password), gitea.SetContext(ctx), + ) + if err != nil { + return "", fmt.Errorf("creating gitea client: %w", err) + } + tokens, resp, err := giteaClient.ListAccessTokens(gitea.ListAccessTokensOptions{}) + if err != nil { + return "", fmt.Errorf("listing gitea access tokens. status: %s error : %w", resp.Status, err) + } + + for i := range tokens { + if tokens[i].Name == GiteaAdminTokenName { + resp, err := giteaClient.DeleteAccessToken(tokens[i].ID) + if err != nil { + return "", fmt.Errorf("deleting gitea access tokens. status: %s error : %w", resp.Status, err) + } + break + } + } + + token, resp, err := giteaClient.CreateAccessToken(gitea.CreateAccessTokenOption{ + Name: GiteaAdminTokenName, + Scopes: []gitea.AccessTokenScope{ + gitea.AccessTokenScopeAll, + }, + }) + if err != nil { + return "", fmt.Errorf("deleting gitea access tokens. status: %s error : %w", resp.Status, err) + } + + return token.Token, nil +} + func GiteaBaseUrl(config v1alpha1.BuildCustomizationSpec) string { return fmt.Sprintf(GiteaIngressURL, config.Protocol, config.Port) }