From 2321f22bd4d9beb79831955501e9c2df1c457338 Mon Sep 17 00:00:00 2001 From: Austin Abro Date: Wed, 9 Oct 2024 14:18:07 +0000 Subject: [PATCH 1/6] POC Signed-off-by: Austin Abro --- src/internal/packager/template/template.go | 1 + src/pkg/cluster/state.go | 34 +++----------- src/pkg/packager/interactive.go | 2 + src/types/k8s.go | 52 ++++++++++++++++++++++ 4 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/internal/packager/template/template.go b/src/internal/packager/template/template.go index 872754ce4d..cbfd1bb844 100644 --- a/src/internal/packager/template/template.go +++ b/src/internal/packager/template/template.go @@ -126,6 +126,7 @@ func generateHtpasswd(regInfo *types.RegistryInfo) (string, error) { } func debugPrintTemplateMap(templateMap map[string]*variables.TextTemplate) { + // This would be super easy to redact with slog attribute redactions debugText := "templateMap = { " for key, template := range templateMap { diff --git a/src/pkg/cluster/state.go b/src/pkg/cluster/state.go index f2279b0221..929482b0b3 100644 --- a/src/pkg/cluster/state.go +++ b/src/pkg/cluster/state.go @@ -9,6 +9,8 @@ import ( "encoding/json" "errors" "fmt" + "log/slog" + "os" "slices" "time" @@ -209,39 +211,13 @@ func (c *Cluster) LoadZarfState(ctx context.Context) (*types.ZarfState, error) { return state, nil } -func (c *Cluster) sanitizeZarfState(state *types.ZarfState) *types.ZarfState { - // Overwrite the AgentTLS information - state.AgentTLS.CA = []byte("**sanitized**") - state.AgentTLS.Cert = []byte("**sanitized**") - state.AgentTLS.Key = []byte("**sanitized**") - - // Overwrite the GitServer passwords - state.GitServer.PushPassword = "**sanitized**" - state.GitServer.PullPassword = "**sanitized**" - - // Overwrite the RegistryInfo passwords - state.RegistryInfo.PushPassword = "**sanitized**" - state.RegistryInfo.PullPassword = "**sanitized**" - state.RegistryInfo.Secret = "**sanitized**" - - // Overwrite the ArtifactServer secret - state.ArtifactServer.PushToken = "**sanitized**" - - return state -} - func (c *Cluster) debugPrintZarfState(state *types.ZarfState) { if state == nil { return } - // this is a shallow copy, nested pointers WILL NOT be copied - oldState := *state - sanitized := c.sanitizeZarfState(&oldState) - b, err := json.MarshalIndent(sanitized, "", " ") - if err != nil { - return - } - message.Debugf("ZarfState - %s", string(b)) + // OFC IRL we woul + logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})) + logger.Debug("testing slog", "zarfState", state) } // SaveZarfState takes a given state and persists it to the Zarf/zarf-state secret. diff --git a/src/pkg/packager/interactive.go b/src/pkg/packager/interactive.go index bc29c8e0f8..4766406fbb 100644 --- a/src/pkg/packager/interactive.go +++ b/src/pkg/packager/interactive.go @@ -100,6 +100,8 @@ func (p *Packager) getPackageYAMLHints(stage string) map[string]string { } else { value = fmt.Sprintf("'%s'", helpers.Truncate(value, 20, false)) } + // This is harder to sanitize with slog because it gets passed as a string before + // it's printed. Therefore a func (InteractiveVariable) Variable logValue() wouldn't do anything if variable.Sensitive { value = "'**sanitized**'" } diff --git a/src/types/k8s.go b/src/types/k8s.go index 8120768863..649db357a7 100644 --- a/src/types/k8s.go +++ b/src/types/k8s.go @@ -6,6 +6,7 @@ package types import ( "fmt" + "log/slog" "github.com/defenseunicorns/pkg/helpers/v2" "github.com/zarf-dev/zarf/src/api/v1alpha1" @@ -45,6 +46,14 @@ type GeneratedPKI struct { Key []byte `json:"key"` } +func (p GeneratedPKI) LogValue() slog.Value { + return slog.GroupValue( + slog.String("ca", "**sanitized**"), + slog.String("cert", "**sanitized**"), + slog.String("key", "**sanitized**"), + ) +} + // ZarfState is maintained as a secret in the Zarf namespace to track Zarf init data. type ZarfState struct { // Indicates if Zarf was initialized while deploying its own k8s cluster @@ -66,6 +75,19 @@ type ZarfState struct { ArtifactServer ArtifactServerInfo `json:"artifactServer"` } +func (zs ZarfState) LogValue() slog.Value { + return slog.GroupValue( + slog.Bool("ZarfAppliance", zs.ZarfAppliance), + slog.String("distro", zs.Distro), + slog.String("architecture", zs.Architecture), + slog.String("storageClass", zs.StorageClass), + slog.Any("agentTLS", zs.AgentTLS), + slog.Any("gitServer", zs.GitServer), + slog.Any("registryInfo", zs.RegistryInfo), + slog.Any("artifactServer", zs.ArtifactServer), + ) +} + // DeployedPackage contains information about a Zarf Package that has been deployed to a cluster // This object is saved as the data of a k8s secret within the 'Zarf' namespace (not as part of the ZarfState secret). type DeployedPackage struct { @@ -114,6 +136,16 @@ type GitServerInfo struct { Address string `json:"address"` } +func (gs GitServerInfo) LogValue() slog.Value { + return slog.GroupValue( + slog.String("pushUsername", gs.PushUsername), + slog.String("pushPassword", "**sanitized**"), + slog.String("pullUsername", gs.PullUsername), + slog.String("pullPassword", "**sanitized**"), + slog.String("address", gs.Address), + ) +} + // IsInternal returns true if the git server URL is equivalent to a git server deployed through the default init package func (gs GitServerInfo) IsInternal() bool { return gs.Address == ZarfInClusterGitServiceURL @@ -165,6 +197,14 @@ type ArtifactServerInfo struct { Address string `json:"address"` } +func (as ArtifactServerInfo) LogValue() slog.Value { + return slog.GroupValue( + slog.String("pushUsername", as.PushUsername), + slog.String("pushToken", "**sanitized**"), + slog.String("address", as.Address), + ) +} + // IsInternal returns true if the artifact server URL is equivalent to the artifact server deployed through the default init package func (as ArtifactServerInfo) IsInternal() bool { return as.Address == ZarfInClusterArtifactServiceURL @@ -201,6 +241,18 @@ type RegistryInfo struct { Secret string `json:"secret"` } +func (ri RegistryInfo) LogValue() slog.Value { + return slog.GroupValue( + slog.String("pushUsername", ri.PushUsername), + slog.String("pushPassword", "**sanitized**"), + slog.String("pullUsername", ri.PullUsername), + slog.String("pullPassword", "**sanitized**"), + slog.String("address", ri.Address), + slog.Int("nodePort", ri.NodePort), + slog.String("secret", "**sanitized**"), + ) +} + // IsInternal returns true if the registry URL is equivalent to the registry deployed through the default init package func (ri RegistryInfo) IsInternal() bool { return ri.Address == fmt.Sprintf("%s:%d", helpers.IPV4Localhost, ri.NodePort) From a863217b17316ed554e4ebacd68fca27dc389a57 Mon Sep 17 00:00:00 2001 From: Austin Abro Date: Wed, 9 Oct 2024 14:31:52 +0000 Subject: [PATCH 2/6] comments Signed-off-by: Austin Abro --- src/pkg/message/credentials.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pkg/message/credentials.go b/src/pkg/message/credentials.go index a0fc97537c..2da50927c2 100644 --- a/src/pkg/message/credentials.go +++ b/src/pkg/message/credentials.go @@ -137,6 +137,7 @@ func PrintCredentialUpdates(oldState *types.ZarfState, newState *types.ZarfState } func compareStrings(old string, new string, secret bool) string { + // If we wanted to continue to print out what changed, we would still need to sanitize here. I don't think this could be done with redactions if new == old { if secret { return "**sanitized** (unchanged)" From ca817235986c0a04f18e4a4d88568257b38e48fa Mon Sep 17 00:00:00 2001 From: Austin Abro Date: Wed, 9 Oct 2024 14:38:42 +0000 Subject: [PATCH 3/6] comments Signed-off-by: Austin Abro --- src/pkg/message/credentials.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkg/message/credentials.go b/src/pkg/message/credentials.go index 2da50927c2..00c0f5d6d0 100644 --- a/src/pkg/message/credentials.go +++ b/src/pkg/message/credentials.go @@ -137,7 +137,7 @@ func PrintCredentialUpdates(oldState *types.ZarfState, newState *types.ZarfState } func compareStrings(old string, new string, secret bool) string { - // If we wanted to continue to print out what changed, we would still need to sanitize here. I don't think this could be done with redactions + // This should be able to be redacted, we'll have to switch things up a bit first if new == old { if secret { return "**sanitized** (unchanged)" From 4bd5e2edbe451046caee688f81538794d14e3218 Mon Sep 17 00:00:00 2001 From: Austin Abro Date: Wed, 9 Oct 2024 16:05:52 +0000 Subject: [PATCH 4/6] POC Signed-off-by: Austin Abro --- src/cmd/initialize.go | 17 +-- src/cmd/internal.go | 8 +- src/cmd/package.go | 4 +- src/cmd/tools/zarf.go | 135 ++++----------------- src/internal/agent/http/proxy.go | 6 +- src/internal/packager/helm/zarf.go | 4 +- src/internal/packager/images/common.go | 4 +- src/internal/packager/template/template.go | 14 +-- src/internal/packager2/mirror.go | 8 +- src/pkg/cluster/secrets.go | 4 +- src/pkg/cluster/secrets_test.go | 2 +- src/pkg/cluster/state.go | 8 +- src/pkg/cluster/zarf.go | 8 +- src/pkg/message/credentials.go | 94 +++++++------- src/pkg/packager/deploy.go | 6 +- src/test/e2e/22_git_and_gitops_test.go | 4 +- src/types/k8s.go | 51 +++++--- 17 files changed, 154 insertions(+), 223 deletions(-) diff --git a/src/cmd/initialize.go b/src/cmd/initialize.go index 01470e817d..e977e4b31c 100644 --- a/src/cmd/initialize.go +++ b/src/cmd/initialize.go @@ -202,23 +202,24 @@ func init() { // Flags for using an external Git server initCmd.Flags().StringVar(&pkgConfig.InitOpts.GitServer.Address, "git-url", v.GetString(common.VInitGitURL), lang.CmdInitFlagGitURL) initCmd.Flags().StringVar(&pkgConfig.InitOpts.GitServer.PushUsername, "git-push-username", v.GetString(common.VInitGitPushUser), lang.CmdInitFlagGitPushUser) - initCmd.Flags().StringVar(&pkgConfig.InitOpts.GitServer.PushPassword, "git-push-password", v.GetString(common.VInitGitPushPass), lang.CmdInitFlagGitPushPass) - initCmd.Flags().StringVar(&pkgConfig.InitOpts.GitServer.PullUsername, "git-pull-username", v.GetString(common.VInitGitPullUser), lang.CmdInitFlagGitPullUser) - initCmd.Flags().StringVar(&pkgConfig.InitOpts.GitServer.PullPassword, "git-pull-password", v.GetString(common.VInitGitPullPass), lang.CmdInitFlagGitPullPass) + // Ignoring for POC + // initCmd.Flags().StringVar(&pkgConfig.InitOpts.GitServer.PushPassword, "git-push-password", v.GetString(common.VInitGitPushPass), lang.CmdInitFlagGitPushPass) + // initCmd.Flags().StringVar(&pkgConfig.InitOpts.GitServer.PullUsername, "git-pull-username", v.GetString(common.VInitGitPullUser), lang.CmdInitFlagGitPullUser) + // initCmd.Flags().StringVar(&pkgConfig.InitOpts.GitServer.PullPassword, "git-pull-password", v.GetString(common.VInitGitPullPass), lang.CmdInitFlagGitPullPass) // Flags for using an external registry initCmd.Flags().StringVar(&pkgConfig.InitOpts.RegistryInfo.Address, "registry-url", v.GetString(common.VInitRegistryURL), lang.CmdInitFlagRegURL) initCmd.Flags().IntVar(&pkgConfig.InitOpts.RegistryInfo.NodePort, "nodeport", v.GetInt(common.VInitRegistryNodeport), lang.CmdInitFlagRegNodePort) initCmd.Flags().StringVar(&pkgConfig.InitOpts.RegistryInfo.PushUsername, "registry-push-username", v.GetString(common.VInitRegistryPushUser), lang.CmdInitFlagRegPushUser) - initCmd.Flags().StringVar(&pkgConfig.InitOpts.RegistryInfo.PushPassword, "registry-push-password", v.GetString(common.VInitRegistryPushPass), lang.CmdInitFlagRegPushPass) - initCmd.Flags().StringVar(&pkgConfig.InitOpts.RegistryInfo.PullUsername, "registry-pull-username", v.GetString(common.VInitRegistryPullUser), lang.CmdInitFlagRegPullUser) - initCmd.Flags().StringVar(&pkgConfig.InitOpts.RegistryInfo.PullPassword, "registry-pull-password", v.GetString(common.VInitRegistryPullPass), lang.CmdInitFlagRegPullPass) - initCmd.Flags().StringVar(&pkgConfig.InitOpts.RegistryInfo.Secret, "registry-secret", v.GetString(common.VInitRegistrySecret), lang.CmdInitFlagRegSecret) + // initCmd.Flags().StringVar(&pkgConfig.InitOpts.RegistryInfo.PushPassword, "registry-push-password", v.GetString(common.VInitRegistryPushPass), lang.CmdInitFlagRegPushPass) + // initCmd.Flags().StringVar(&pkgConfig.InitOpts.RegistryInfo.PullUsername, "registry-pull-username", v.GetString(common.VInitRegistryPullUser), lang.CmdInitFlagRegPullUser) + // initCmd.Flags().StringVar(&pkgConfig.InitOpts.RegistryInfo.PullPassword, "registry-pull-password", v.GetString(common.VInitRegistryPullPass), lang.CmdInitFlagRegPullPass) + // initCmd.Flags().StringVar(&pkgConfig.InitOpts.RegistryInfo.Secret, "registry-secret", v.GetString(common.VInitRegistrySecret), lang.CmdInitFlagRegSecret) // Flags for using an external artifact server initCmd.Flags().StringVar(&pkgConfig.InitOpts.ArtifactServer.Address, "artifact-url", v.GetString(common.VInitArtifactURL), lang.CmdInitFlagArtifactURL) initCmd.Flags().StringVar(&pkgConfig.InitOpts.ArtifactServer.PushUsername, "artifact-push-username", v.GetString(common.VInitArtifactPushUser), lang.CmdInitFlagArtifactPushUser) - initCmd.Flags().StringVar(&pkgConfig.InitOpts.ArtifactServer.PushToken, "artifact-push-token", v.GetString(common.VInitArtifactPushToken), lang.CmdInitFlagArtifactPushToken) + // initCmd.Flags().StringVar(&pkgConfig.InitOpts.ArtifactServer.PushToken, "artifact-push-token", v.GetString(common.VInitArtifactPushToken), lang.CmdInitFlagArtifactPushToken) // Flags that control how a deployment proceeds // Always require adopt-existing-resources flag (no viper) diff --git a/src/cmd/internal.go b/src/cmd/internal.go index b3bc2c4592..9c175ff75c 100644 --- a/src/cmd/internal.go +++ b/src/cmd/internal.go @@ -251,12 +251,12 @@ var createReadOnlyGiteaUser = &cobra.Command{ } defer tunnel.Close() tunnelURL := tunnel.HTTPEndpoint() - giteaClient, err := gitea.NewClient(tunnelURL, state.GitServer.PushUsername, state.GitServer.PushPassword) + giteaClient, err := gitea.NewClient(tunnelURL, state.GitServer.PushUsername, string(state.GitServer.PushPassword)) if err != nil { return err } err = tunnel.Wrap(func() error { - err = giteaClient.CreateReadOnlyUser(cmd.Context(), state.GitServer.PullUsername, state.GitServer.PullPassword) + err = giteaClient.CreateReadOnlyUser(cmd.Context(), state.GitServer.PullUsername, string(state.GitServer.PullPassword)) if err != nil { return err } @@ -298,7 +298,7 @@ var createPackageRegistryToken = &cobra.Command{ } defer tunnel.Close() tunnelURL := tunnel.HTTPEndpoint() - giteaClient, err := gitea.NewClient(tunnelURL, state.GitServer.PushUsername, state.GitServer.PushPassword) + giteaClient, err := gitea.NewClient(tunnelURL, state.GitServer.PushUsername, string(state.GitServer.PushPassword)) if err != nil { return err } @@ -307,7 +307,7 @@ var createPackageRegistryToken = &cobra.Command{ if err != nil { return fmt.Errorf("unable to create an artifact registry token for Gitea: %w", err) } - state.ArtifactServer.PushToken = tokenSha1 + state.ArtifactServer.PushToken = types.Password(tokenSha1) return nil }) if err != nil { diff --git a/src/cmd/package.go b/src/cmd/package.go index 30b80c612a..007d18277b 100644 --- a/src/cmd/package.go +++ b/src/cmd/package.go @@ -562,12 +562,12 @@ func bindMirrorFlags(v *viper.Viper) { // Flags for using an external Git server mirrorFlags.StringVar(&pkgConfig.InitOpts.GitServer.Address, "git-url", v.GetString(common.VInitGitURL), lang.CmdInitFlagGitURL) mirrorFlags.StringVar(&pkgConfig.InitOpts.GitServer.PushUsername, "git-push-username", v.GetString(common.VInitGitPushUser), lang.CmdInitFlagGitPushUser) - mirrorFlags.StringVar(&pkgConfig.InitOpts.GitServer.PushPassword, "git-push-password", v.GetString(common.VInitGitPushPass), lang.CmdInitFlagGitPushPass) + // mirrorFlags.StringVar(&pkgConfig.InitOpts.GitServer.PushPassword, "git-push-password", v.GetString(common.VInitGitPushPass), lang.CmdInitFlagGitPushPass) // Flags for using an external registry mirrorFlags.StringVar(&pkgConfig.InitOpts.RegistryInfo.Address, "registry-url", v.GetString(common.VInitRegistryURL), lang.CmdInitFlagRegURL) mirrorFlags.StringVar(&pkgConfig.InitOpts.RegistryInfo.PushUsername, "registry-push-username", v.GetString(common.VInitRegistryPushUser), lang.CmdInitFlagRegPushUser) - mirrorFlags.StringVar(&pkgConfig.InitOpts.RegistryInfo.PushPassword, "registry-push-password", v.GetString(common.VInitRegistryPushPass), lang.CmdInitFlagRegPushPass) + // mirrorFlags.StringVar(&pkgConfig.InitOpts.RegistryInfo.PushPassword, "registry-push-password", v.GetString(common.VInitRegistryPushPass), lang.CmdInitFlagRegPushPass) } func bindInspectFlags(_ *viper.Viper) { diff --git a/src/cmd/tools/zarf.go b/src/cmd/tools/zarf.go index df516f9506..36f651d684 100644 --- a/src/cmd/tools/zarf.go +++ b/src/cmd/tools/zarf.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "os" - "slices" "github.com/AlecAivazis/survey/v2" "github.com/sigstore/cosign/v2/pkg/cosign" @@ -21,8 +20,6 @@ import ( "github.com/zarf-dev/zarf/src/cmd/common" "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/config/lang" - "github.com/zarf-dev/zarf/src/internal/packager/helm" - "github.com/zarf-dev/zarf/src/internal/packager/template" "github.com/zarf-dev/zarf/src/pkg/cluster" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/packager/sources" @@ -90,112 +87,24 @@ var updateCredsCmd = &cobra.Command{ Aliases: []string{"uc"}, Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - validKeys := []string{message.RegistryKey, message.GitKey, message.ArtifactKey, message.AgentKey} - if len(args) == 0 { - args = validKeys - } else { - if !slices.Contains(validKeys, args[0]) { - cmd.Help() - return fmt.Errorf("invalid service key specified, valid key choices are: %v", validKeys) - } - } - - ctx := cmd.Context() - - timeoutCtx, cancel := context.WithTimeout(ctx, cluster.DefaultTimeout) - defer cancel() - c, err := cluster.NewClusterWithWait(timeoutCtx) - if err != nil { - return err + // Creating my own example here + + args = []string{"artifact"} + oldState := &types.ZarfState{ + ArtifactServer: types.ArtifactServerInfo{ + Address: "whatever", + PushToken: "artifact-token", + PushUsername: "cool-guy", + }, } - - oldState, err := c.LoadZarfState(ctx) - if err != nil { - return err - } - // TODO: Determine if this is actually needed. - if oldState.Distro == "" { - return errors.New("zarf state secret did not load properly") + newState := &types.ZarfState{ + ArtifactServer: types.ArtifactServerInfo{ + Address: "cooler-address", + PushToken: "artifact-token-new", + PushUsername: "cool-guy", + }, } - newState, err := cluster.MergeZarfState(oldState, updateCredsInitOpts, args) - if err != nil { - return fmt.Errorf("unable to update Zarf credentials: %w", err) - } - message.PrintCredentialUpdates(oldState, newState, args) - - confirm := config.CommonOptions.Confirm - - if confirm { - message.Note(lang.CmdToolsUpdateCredsConfirmProvided) - } else { - prompt := &survey.Confirm{ - Message: lang.CmdToolsUpdateCredsConfirmContinue, - } - if err := survey.AskOne(prompt, &confirm); err != nil { - return fmt.Errorf("confirm selection canceled: %w", err) - } - } - - if confirm { - // Update registry and git pull secrets - if slices.Contains(args, message.RegistryKey) { - err := c.UpdateZarfManagedImageSecrets(ctx, newState) - if err != nil { - return err - } - } - if slices.Contains(args, message.GitKey) { - err := c.UpdateZarfManagedGitSecrets(ctx, newState) - if err != nil { - return err - } - } - // TODO once Zarf is changed so the default state is empty for a service when it is not deployed - // and sufficient time has passed for users state to get updated we can remove this check - internalGitServerExists, err := c.InternalGitServerExists(cmd.Context()) - if err != nil { - return err - } - - // Update artifact token (if internal) - if slices.Contains(args, message.ArtifactKey) && newState.ArtifactServer.PushToken == "" && newState.ArtifactServer.IsInternal() && internalGitServerExists { - newState.ArtifactServer.PushToken, err = c.UpdateInternalArtifactServerToken(ctx, oldState.GitServer) - if err != nil { - return fmt.Errorf("unable to create the new Gitea artifact token: %w", err) - } - } - - // Save the final Zarf State - err = c.SaveZarfState(ctx, newState) - if err != nil { - return fmt.Errorf("failed to save the Zarf State to the cluster: %w", err) - } - - // Update Zarf 'init' component Helm releases if present - h := helm.NewClusterOnly(&types.PackagerConfig{}, template.GetZarfVariableConfig(), newState, c) - - if slices.Contains(args, message.RegistryKey) && newState.RegistryInfo.IsInternal() { - err = h.UpdateZarfRegistryValues(ctx) - if err != nil { - // Warn if we couldn't actually update the registry (it might not be installed and we should try to continue) - message.Warnf(lang.CmdToolsUpdateCredsUnableUpdateRegistry, err.Error()) - } - } - if slices.Contains(args, message.GitKey) && newState.GitServer.IsInternal() && internalGitServerExists { - err := c.UpdateInternalGitServerSecret(cmd.Context(), oldState.GitServer, newState.GitServer) - if err != nil { - return fmt.Errorf("unable to update Zarf Git Server values: %w", err) - } - } - if slices.Contains(args, message.AgentKey) { - err = h.UpdateZarfAgentValues(ctx) - if err != nil { - // Warn if we couldn't actually update the agent (it might not be installed and we should try to continue) - message.Warnf(lang.CmdToolsUpdateCredsUnableUpdateAgent, err.Error()) - } - } - } return nil }, } @@ -346,21 +255,21 @@ func init() { // Flags for using an external Git server updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.GitServer.Address, "git-url", v.GetString(common.VInitGitURL), lang.CmdInitFlagGitURL) updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.GitServer.PushUsername, "git-push-username", v.GetString(common.VInitGitPushUser), lang.CmdInitFlagGitPushUser) - updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.GitServer.PushPassword, "git-push-password", v.GetString(common.VInitGitPushPass), lang.CmdInitFlagGitPushPass) - updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.GitServer.PullUsername, "git-pull-username", v.GetString(common.VInitGitPullUser), lang.CmdInitFlagGitPullUser) - updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.GitServer.PullPassword, "git-pull-password", v.GetString(common.VInitGitPullPass), lang.CmdInitFlagGitPullPass) + // updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.GitServer.PushPassword, "git-push-password", v.GetString(common.VInitGitPushPass), lang.CmdInitFlagGitPushPass) + // updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.GitServer.PullUsername, "git-pull-username", v.GetString(common.VInitGitPullUser), lang.CmdInitFlagGitPullUser) + // updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.GitServer.PullPassword, "git-pull-password", v.GetString(common.VInitGitPullPass), lang.CmdInitFlagGitPullPass) // Flags for using an external registry updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.RegistryInfo.Address, "registry-url", v.GetString(common.VInitRegistryURL), lang.CmdInitFlagRegURL) updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.RegistryInfo.PushUsername, "registry-push-username", v.GetString(common.VInitRegistryPushUser), lang.CmdInitFlagRegPushUser) - updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.RegistryInfo.PushPassword, "registry-push-password", v.GetString(common.VInitRegistryPushPass), lang.CmdInitFlagRegPushPass) - updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.RegistryInfo.PullUsername, "registry-pull-username", v.GetString(common.VInitRegistryPullUser), lang.CmdInitFlagRegPullUser) - updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.RegistryInfo.PullPassword, "registry-pull-password", v.GetString(common.VInitRegistryPullPass), lang.CmdInitFlagRegPullPass) + // updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.RegistryInfo.PushPassword, "registry-push-password", v.GetString(common.VInitRegistryPushPass), lang.CmdInitFlagRegPushPass) + // updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.RegistryInfo.PullUsername, "registry-pull-username", v.GetString(common.VInitRegistryPullUser), lang.CmdInitFlagRegPullUser) + // updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.RegistryInfo.PullPassword, "registry-pull-password", v.GetString(common.VInitRegistryPullPass), lang.CmdInitFlagRegPullPass) // Flags for using an external artifact server updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.ArtifactServer.Address, "artifact-url", v.GetString(common.VInitArtifactURL), lang.CmdInitFlagArtifactURL) updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.ArtifactServer.PushUsername, "artifact-push-username", v.GetString(common.VInitArtifactPushUser), lang.CmdInitFlagArtifactPushUser) - updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.ArtifactServer.PushToken, "artifact-push-token", v.GetString(common.VInitArtifactPushToken), lang.CmdInitFlagArtifactPushToken) + // updateCredsCmd.Flags().StringVar(&updateCredsInitOpts.ArtifactServer.PushToken, "artifact-push-token", v.GetString(common.VInitArtifactPushToken), lang.CmdInitFlagArtifactPushToken) updateCredsCmd.Flags().SortFlags = true diff --git a/src/internal/agent/http/proxy.go b/src/internal/agent/http/proxy.go index 760ba709ec..4c3cfc7a9f 100644 --- a/src/internal/agent/http/proxy.go +++ b/src/internal/agent/http/proxy.go @@ -53,11 +53,11 @@ func proxyRequestTransform(r *http.Request, state *types.ZarfState) error { // Setup authentication for each type of service based on User Agent switch { case isGitUserAgent(r.UserAgent()): - r.SetBasicAuth(state.GitServer.PushUsername, state.GitServer.PushPassword) + r.SetBasicAuth(state.GitServer.PushUsername, string(state.GitServer.PushPassword)) case isNpmUserAgent(r.UserAgent()): - r.Header.Set("Authorization", "Bearer "+state.ArtifactServer.PushToken) + r.Header.Set("Authorization", "Bearer "+string(state.ArtifactServer.PushToken)) default: - r.SetBasicAuth(state.ArtifactServer.PushUsername, state.ArtifactServer.PushToken) + r.SetBasicAuth(state.ArtifactServer.PushUsername, string(state.ArtifactServer.PushToken)) } // Transform the URL; if we see the NoTransform prefix, strip it; otherwise, transform the URL based on User Agent diff --git a/src/internal/packager/helm/zarf.go b/src/internal/packager/helm/zarf.go index 03e4db2ed0..f353e8177b 100644 --- a/src/internal/packager/helm/zarf.go +++ b/src/internal/packager/helm/zarf.go @@ -27,11 +27,11 @@ import ( // UpdateZarfRegistryValues updates the Zarf registry deployment with the new state values func (h *Helm) UpdateZarfRegistryValues(ctx context.Context) error { - pushUser, err := utils.GetHtpasswdString(h.state.RegistryInfo.PushUsername, h.state.RegistryInfo.PushPassword) + pushUser, err := utils.GetHtpasswdString(h.state.RegistryInfo.PushUsername, string(h.state.RegistryInfo.PushPassword)) if err != nil { return fmt.Errorf("error generating htpasswd string: %w", err) } - pullUser, err := utils.GetHtpasswdString(h.state.RegistryInfo.PullUsername, h.state.RegistryInfo.PullPassword) + pullUser, err := utils.GetHtpasswdString(h.state.RegistryInfo.PullUsername, string(h.state.RegistryInfo.PullPassword)) if err != nil { return fmt.Errorf("error generating htpasswd string: %w", err) } diff --git a/src/internal/packager/images/common.go b/src/internal/packager/images/common.go index 285c541edb..af78012b80 100644 --- a/src/internal/packager/images/common.go +++ b/src/internal/packager/images/common.go @@ -90,12 +90,12 @@ func WithBasicAuth(username, password string) crane.Option { // WithPullAuth returns an option for crane that sets pull auth from a given registry info. func WithPullAuth(ri types.RegistryInfo) crane.Option { - return WithBasicAuth(ri.PullUsername, ri.PullPassword) + return WithBasicAuth(ri.PullUsername, string(ri.PullPassword)) } // WithPushAuth returns an option for crane that sets push auth from a given registry info. func WithPushAuth(ri types.RegistryInfo) crane.Option { - return WithBasicAuth(ri.PushUsername, ri.PushPassword) + return WithBasicAuth(ri.PushUsername, string(ri.PushPassword)) } func createPushOpts(cfg PushConfig, pb *message.ProgressBar) []crane.Option { diff --git a/src/internal/packager/template/template.go b/src/internal/packager/template/template.go index cbfd1bb844..f3c4c028ba 100644 --- a/src/internal/packager/template/template.go +++ b/src/internal/packager/template/template.go @@ -54,14 +54,14 @@ func GetZarfTemplates(componentName string, state *types.ZarfState) (templateMap // Registry info "REGISTRY": regInfo.Address, "NODEPORT": fmt.Sprintf("%d", regInfo.NodePort), - "REGISTRY_AUTH_PUSH": regInfo.PushPassword, - "REGISTRY_AUTH_PULL": regInfo.PullPassword, + "REGISTRY_AUTH_PUSH": string(regInfo.PushPassword), + "REGISTRY_AUTH_PULL": string(regInfo.PullPassword), // Git server info "GIT_PUSH": gitInfo.PushUsername, - "GIT_AUTH_PUSH": gitInfo.PushPassword, + "GIT_AUTH_PUSH": string(gitInfo.PushPassword), "GIT_PULL": gitInfo.PullUsername, - "GIT_AUTH_PULL": gitInfo.PullPassword, + "GIT_AUTH_PULL": string(gitInfo.PullPassword), } builtinMap[depMarker] = config.GetDataInjectionMarker() @@ -81,7 +81,7 @@ func GetZarfTemplates(componentName string, state *types.ZarfState) (templateMap return templateMap, err } builtinMap["HTPASSWD"] = htpasswd - builtinMap["REGISTRY_SECRET"] = regInfo.Secret + builtinMap["REGISTRY_SECRET"] = string(regInfo.Secret) } // Iterate over any custom variables and add them to the mappings for templating @@ -109,12 +109,12 @@ func GetZarfTemplates(componentName string, state *types.ZarfState) (templateMap func generateHtpasswd(regInfo *types.RegistryInfo) (string, error) { // Only calculate this for internal registries to allow longer external passwords if regInfo.IsInternal() { - pushUser, err := utils.GetHtpasswdString(regInfo.PushUsername, regInfo.PushPassword) + pushUser, err := utils.GetHtpasswdString(regInfo.PushUsername, string(regInfo.PushPassword)) if err != nil { return "", fmt.Errorf("error generating htpasswd string: %w", err) } - pullUser, err := utils.GetHtpasswdString(regInfo.PullUsername, regInfo.PullPassword) + pullUser, err := utils.GetHtpasswdString(regInfo.PullUsername, string(regInfo.PullPassword)) if err != nil { return "", fmt.Errorf("error generating htpasswd string: %w", err) } diff --git a/src/internal/packager2/mirror.go b/src/internal/packager2/mirror.go index 8532a8c4e6..38c427118a 100644 --- a/src/internal/packager2/mirror.go +++ b/src/internal/packager2/mirror.go @@ -96,7 +96,7 @@ func pushImagesToRegistry(ctx context.Context, c *cluster.Cluster, pkgLayout *la crane.WithTransport(transportWithProgressBar), crane.WithAuth(authn.FromConfig(authn.AuthConfig{ Username: regInfo.PushUsername, - Password: regInfo.PushPassword, + Password: string(regInfo.PushPassword), })), crane.WithUserAgent("zarf"), crane.WithNoClobber(true), @@ -190,7 +190,7 @@ func pushReposToRepository(ctx context.Context, c *cluster.Cluster, pkgLayout *l err = retry.Do(func() error { if !dns.IsServiceURL(gitInfo.Address) { message.Infof("Pushing repository %s to server %s", repoURL, gitInfo.Address) - err = repository.Push(ctx, gitInfo.Address, gitInfo.PushUsername, gitInfo.PushPassword) + err = repository.Push(ctx, gitInfo.Address, gitInfo.PushUsername, string(gitInfo.PushPassword)) if err != nil { return err } @@ -213,13 +213,13 @@ func pushReposToRepository(ctx context.Context, c *cluster.Cluster, pkgLayout *l return err } defer tunnel.Close() - giteaClient, err := gitea.NewClient(tunnel.HTTPEndpoint(), gitInfo.PushUsername, gitInfo.PushPassword) + giteaClient, err := gitea.NewClient(tunnel.HTTPEndpoint(), gitInfo.PushUsername, string(gitInfo.PushPassword)) if err != nil { return err } return tunnel.Wrap(func() error { message.Infof("Pushing repository %s to server %s", repoURL, tunnel.HTTPEndpoint()) - err = repository.Push(ctx, tunnel.HTTPEndpoint(), gitInfo.PushUsername, gitInfo.PushPassword) + err = repository.Push(ctx, tunnel.HTTPEndpoint(), gitInfo.PushUsername, string(gitInfo.PushPassword)) if err != nil { return err } diff --git a/src/pkg/cluster/secrets.go b/src/pkg/cluster/secrets.go index aa693c6a44..75c0ebd756 100644 --- a/src/pkg/cluster/secrets.go +++ b/src/pkg/cluster/secrets.go @@ -37,7 +37,7 @@ type DockerConfigEntryWithAuth struct { // GenerateRegistryPullCreds generates a secret containing the registry credentials. func (c *Cluster) GenerateRegistryPullCreds(ctx context.Context, namespace, name string, registryInfo types.RegistryInfo) (*corev1.Secret, error) { // Auth field must be username:password and base64 encoded - fieldValue := registryInfo.PullUsername + ":" + registryInfo.PullPassword + fieldValue := string(registryInfo.PullUsername) + ":" + string(registryInfo.PullPassword) authEncodedValue := base64.StdEncoding.EncodeToString([]byte(fieldValue)) dockerConfigJSON := DockerConfig{ @@ -106,7 +106,7 @@ func (c *Cluster) GenerateGitPullCreds(namespace, name string, gitServerInfo typ Data: map[string][]byte{}, StringData: map[string]string{ "username": gitServerInfo.PullUsername, - "password": gitServerInfo.PullPassword, + "password": string(gitServerInfo.PullPassword), }, } return gitServerSecret diff --git a/src/pkg/cluster/secrets_test.go b/src/pkg/cluster/secrets_test.go index 0ee731dfe9..a90c34baa3 100644 --- a/src/pkg/cluster/secrets_test.go +++ b/src/pkg/cluster/secrets_test.go @@ -195,7 +195,7 @@ func TestUpdateZarfManagedSecrets(t *testing.T) { Data: map[string][]byte{}, StringData: map[string]string{ "username": state.GitServer.PullUsername, - "password": state.GitServer.PullPassword, + "password": string(state.GitServer.PullPassword), }, } if !tt.updatedGitSecret { diff --git a/src/pkg/cluster/state.go b/src/pkg/cluster/state.go index 929482b0b3..97e9278c0a 100644 --- a/src/pkg/cluster/state.go +++ b/src/pkg/cluster/state.go @@ -271,12 +271,12 @@ func MergeZarfState(oldState *types.ZarfState, initOptions types.ZarfInitOptions // Set the new passwords if they should be autogenerated if newState.RegistryInfo.PushPassword == oldState.RegistryInfo.PushPassword && oldState.RegistryInfo.IsInternal() { - if newState.RegistryInfo.PushPassword, err = helpers.RandomString(types.ZarfGeneratedPasswordLen); err != nil { + if newState.RegistryInfo.PushPassword, err = types.RandomString(); err != nil { return nil, fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) } } if newState.RegistryInfo.PullPassword == oldState.RegistryInfo.PullPassword && oldState.RegistryInfo.IsInternal() { - if newState.RegistryInfo.PullPassword, err = helpers.RandomString(types.ZarfGeneratedPasswordLen); err != nil { + if newState.RegistryInfo.PullPassword, err = types.RandomString(); err != nil { return nil, fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) } } @@ -287,12 +287,12 @@ func MergeZarfState(oldState *types.ZarfState, initOptions types.ZarfInitOptions // Set the new passwords if they should be autogenerated if newState.GitServer.PushPassword == oldState.GitServer.PushPassword && oldState.GitServer.IsInternal() { - if newState.GitServer.PushPassword, err = helpers.RandomString(types.ZarfGeneratedPasswordLen); err != nil { + if newState.GitServer.PushPassword, err = types.RandomString(); err != nil { return nil, fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) } } if newState.GitServer.PullPassword == oldState.GitServer.PullPassword && oldState.GitServer.IsInternal() { - if newState.GitServer.PullPassword, err = helpers.RandomString(types.ZarfGeneratedPasswordLen); err != nil { + if newState.GitServer.PullPassword, err = types.RandomString(); err != nil { return nil, fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) } } diff --git a/src/pkg/cluster/zarf.go b/src/pkg/cluster/zarf.go index 3f12381e38..4096e24685 100644 --- a/src/pkg/cluster/zarf.go +++ b/src/pkg/cluster/zarf.go @@ -298,7 +298,7 @@ func (c *Cluster) UpdateInternalArtifactServerToken(ctx context.Context, oldGitS } defer tunnel.Close() tunnelURL := tunnel.HTTPEndpoint() - giteaClient, err := gitea.NewClient(tunnelURL, oldGitServer.PushUsername, oldGitServer.PushPassword) + giteaClient, err := gitea.NewClient(tunnelURL, oldGitServer.PushUsername, string(oldGitServer.PushPassword)) if err != nil { return "", err } @@ -328,16 +328,16 @@ func (c *Cluster) UpdateInternalGitServerSecret(ctx context.Context, oldGitServe } defer tunnel.Close() tunnelURL := tunnel.HTTPEndpoint() - giteaClient, err := gitea.NewClient(tunnelURL, oldGitServer.PushUsername, oldGitServer.PushPassword) + giteaClient, err := gitea.NewClient(tunnelURL, oldGitServer.PushUsername, string(oldGitServer.PushPassword)) if err != nil { return err } err = tunnel.Wrap(func() error { - err := giteaClient.UpdateGitUser(ctx, newGitServer.PullUsername, newGitServer.PullPassword) + err := giteaClient.UpdateGitUser(ctx, newGitServer.PullUsername, string(newGitServer.PullPassword)) if err != nil { return err } - err = giteaClient.UpdateGitUser(ctx, newGitServer.PushUsername, newGitServer.PushPassword) + err = giteaClient.UpdateGitUser(ctx, newGitServer.PushUsername, string(newGitServer.PushPassword)) if err != nil { return err } diff --git a/src/pkg/message/credentials.go b/src/pkg/message/credentials.go index 00c0f5d6d0..ae99d3e6f7 100644 --- a/src/pkg/message/credentials.go +++ b/src/pkg/message/credentials.go @@ -6,6 +6,8 @@ package message import ( "fmt" + "log/slog" + "os" "strings" "github.com/pterm/pterm" @@ -37,8 +39,8 @@ func PrintCredentialTable(state *types.ZarfState, componentsToDeploy []types.Dep loginData := [][]string{} if state.RegistryInfo.IsInternal() { loginData = append(loginData, - []string{"Registry", state.RegistryInfo.PushUsername, state.RegistryInfo.PushPassword, "zarf connect registry", RegistryKey}, - []string{"Registry (read-only)", state.RegistryInfo.PullUsername, state.RegistryInfo.PullPassword, "zarf connect registry", RegistryReadKey}, + []string{"Registry", state.RegistryInfo.PushUsername, string(state.RegistryInfo.PushPassword), "zarf connect registry", RegistryKey}, + []string{"Registry (read-only)", state.RegistryInfo.PullUsername, string(state.RegistryInfo.PullPassword), "zarf connect registry", RegistryReadKey}, ) } @@ -46,9 +48,9 @@ func PrintCredentialTable(state *types.ZarfState, componentsToDeploy []types.Dep // Show message if including git-server if component.Name == "git-server" { loginData = append(loginData, - []string{"Git", state.GitServer.PushUsername, state.GitServer.PushPassword, "zarf connect git", GitKey}, - []string{"Git (read-only)", state.GitServer.PullUsername, state.GitServer.PullPassword, "zarf connect git", GitReadKey}, - []string{"Artifact Token", state.ArtifactServer.PushUsername, state.ArtifactServer.PushToken, "zarf connect git", ArtifactKey}, + []string{"Git", state.GitServer.PushUsername, string(state.GitServer.PushPassword), "zarf connect git", GitKey}, + []string{"Git (read-only)", state.GitServer.PullUsername, string(state.GitServer.PullPassword), "zarf connect git", GitReadKey}, + []string{"Artifact Token", state.ArtifactServer.PushUsername, string(state.ArtifactServer.PushToken), "zarf connect git", ArtifactKey}, ) } } @@ -90,62 +92,64 @@ func PrintCredentialUpdates(oldState *types.ZarfState, newState *types.ZarfState defer logFile.Resume() } + // IRL this would be made somewhere else + logger := slog.New(slog.NewTextHandler(os.Stderr, nil)) + for _, service := range services { HorizontalRule() switch service { - case RegistryKey: - oR := oldState.RegistryInfo - nR := newState.RegistryInfo - Title("Registry", "the information used to interact with Zarf's container image registry") - pterm.Println() - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("URL Address"), compareStrings(oR.Address, nR.Address, false)) - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Push Username"), compareStrings(oR.PushUsername, nR.PushUsername, false)) - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Push Password"), compareStrings(oR.PushPassword, nR.PushPassword, true)) - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Pull Username"), compareStrings(oR.PullUsername, nR.PullUsername, false)) - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Pull Password"), compareStrings(oR.PullPassword, nR.PullPassword, true)) - case GitKey: - oG := oldState.GitServer - nG := newState.GitServer - Title("Git Server", "the information used to interact with Zarf's GitOps Git Server") - pterm.Println() - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("URL Address"), compareStrings(oG.Address, nG.Address, false)) - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Push Username"), compareStrings(oG.PushUsername, nG.PushUsername, false)) - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Push Password"), compareStrings(oG.PushPassword, nG.PushPassword, true)) - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Pull Username"), compareStrings(oG.PullUsername, nG.PullUsername, false)) - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Pull Password"), compareStrings(oG.PullPassword, nG.PullPassword, true)) + // case RegistryKey: + // oR := oldState.RegistryInfo + // nR := newState.RegistryInfo + // Title("Registry", "the information used to interact with Zarf's container image registry") + // pterm.Println() + // logger.Info("Registry information", compareStrings(oR.Address, nR.Address), + // compareStrings(oR.PushUsername, nR.PushUsername), comparePasswords(oR.PushPassword, nR.PushPassword), + // compareStrings(oR.PullUsername, nR.PullUsername), comparePasswords(oR.PullPassword, nR.PullPassword)) + // case GitKey: + // oG := oldState.GitServer + // nG := newState.GitServer + // Title("Git Server", "the information used to interact with Zarf's GitOps Git Server") + // pterm.Println() + // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("URL Address"), compareStrings(oG.Address, nG.Address, false)) + // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Push Username"), compareStrings(oG.PushUsername, nG.PushUsername, false)) + // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Push Password"), compareStrings(oG.PushPassword, nG.PushPassword, true)) + // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Pull Username"), compareStrings(oG.PullUsername, nG.PullUsername, false)) + // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Pull Password"), compareStrings(oG.PullPassword, nG.PullPassword, true)) case ArtifactKey: oA := oldState.ArtifactServer nA := newState.ArtifactServer Title("Artifact Server", "the information used to interact with Zarf's Artifact Server") pterm.Println() - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("URL Address"), compareStrings(oA.Address, nA.Address, false)) - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Push Username"), compareStrings(oA.PushUsername, nA.PushUsername, false)) - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Push Token"), compareStrings(oA.PushToken, nA.PushToken, true)) - case AgentKey: - oT := oldState.AgentTLS - nT := newState.AgentTLS - Title("Agent TLS", "the certificates used to connect to Zarf's Agent") - pterm.Println() - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Certificate Authority"), compareStrings(string(oT.CA), string(nT.CA), true)) - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Public Certificate"), compareStrings(string(oT.Cert), string(nT.Cert), true)) - pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Private Key"), compareStrings(string(oT.Key), string(nT.Key), true)) + logger.Info("Artifact info", + compareStrings("URL Address", oA.Address, nA.Address), + compareStrings("Push Username", oA.PushUsername, nA.PushUsername), + comparePasswords("Push Token", oA.PushToken, nA.PushToken)) + // case AgentKey: + // oT := oldState.AgentTLS + // nT := newState.AgentTLS + // Title("Agent TLS", "the certificates used to connect to Zarf's Agent") + // pterm.Println() + // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Certificate Authority"), compareStrings(string(oT.CA), string(nT.CA), true)) + // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Public Certificate"), compareStrings(string(oT.Cert), string(nT.Cert), true)) + // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Private Key"), compareStrings(string(oT.Key), string(nT.Key), true)) } } pterm.Println() } -func compareStrings(old string, new string, secret bool) string { - // This should be able to be redacted, we'll have to switch things up a bit first +func compareStrings(attribute string, old string, new string) slog.Attr { if new == old { - if secret { - return "**sanitized** (unchanged)" - } - return fmt.Sprintf("%s (unchanged)", old) + return slog.String(attribute, "(unchanged) "+old) } - if secret { - return fmt.Sprintf("%s -> %s", pterm.FgRed.Sprint("**existing (sanitized)**"), pterm.FgGreen.Sprint("**replacement (sanitized)**")) + return slog.Group(attribute, "old", old, "new", new) +} + +func comparePasswords(attribute string, old types.Password, new types.Password) slog.Attr { + if new == old { + return slog.Any(attribute, old) } - return fmt.Sprintf("%s -> %s", pterm.FgRed.Sprint(old), pterm.FgGreen.Sprint(new)) + return slog.Group(attribute, "old", old, "new", new) } diff --git a/src/pkg/packager/deploy.go b/src/pkg/packager/deploy.go index 26079df5d4..c210554b26 100644 --- a/src/pkg/packager/deploy.go +++ b/src/pkg/packager/deploy.go @@ -576,12 +576,12 @@ func (p *Packager) pushReposToRepository(ctx context.Context, reposPath string, return err } defer tunnel.Close() - giteaClient, err := gitea.NewClient(tunnel.HTTPEndpoint(), p.state.GitServer.PushUsername, p.state.GitServer.PushPassword) + giteaClient, err := gitea.NewClient(tunnel.HTTPEndpoint(), p.state.GitServer.PushUsername, string(p.state.GitServer.PushPassword)) if err != nil { return err } return tunnel.Wrap(func() error { - err = repository.Push(ctx, tunnel.HTTPEndpoint(), p.state.GitServer.PushUsername, p.state.GitServer.PushPassword) + err = repository.Push(ctx, tunnel.HTTPEndpoint(), p.state.GitServer.PushUsername, string(p.state.GitServer.PushPassword)) if err != nil { return err } @@ -598,7 +598,7 @@ func (p *Packager) pushReposToRepository(ctx context.Context, reposPath string, }) } - err = repository.Push(ctx, p.state.GitServer.Address, p.state.GitServer.PushUsername, p.state.GitServer.PushPassword) + err = repository.Push(ctx, p.state.GitServer.Address, p.state.GitServer.PushUsername, string(p.state.GitServer.PushPassword)) if err != nil { return err } diff --git a/src/test/e2e/22_git_and_gitops_test.go b/src/test/e2e/22_git_and_gitops_test.go index 90eb715259..d4b606d7b9 100644 --- a/src/test/e2e/22_git_and_gitops_test.go +++ b/src/test/e2e/22_git_and_gitops_test.go @@ -73,7 +73,7 @@ func testGitServerReadOnly(ctx context.Context, t *testing.T, gitURL string) { // Init the state variable state, err := c.LoadZarfState(ctx) require.NoError(t, err) - giteaClient, err := gitea.NewClient(gitURL, types.ZarfGitReadUser, state.GitServer.PullPassword) + giteaClient, err := gitea.NewClient(gitURL, types.ZarfGitReadUser, string(state.GitServer.PullPassword)) require.NoError(t, err) repoName := "zarf-public-test-2363058019" @@ -102,7 +102,7 @@ func testGitServerTagAndHash(ctx context.Context, t *testing.T, gitURL string) { // Init the state variable state, err := c.LoadZarfState(ctx) require.NoError(t, err, "Failed to load Zarf state") - giteaClient, err := gitea.NewClient(gitURL, types.ZarfGitReadUser, state.GitServer.PullPassword) + giteaClient, err := gitea.NewClient(gitURL, types.ZarfGitReadUser, string(state.GitServer.PullPassword)) require.NoError(t, err) repoName := "zarf-public-test-2363058019" diff --git a/src/types/k8s.go b/src/types/k8s.go index 649db357a7..da7d21f797 100644 --- a/src/types/k8s.go +++ b/src/types/k8s.go @@ -39,6 +39,8 @@ const ( ZarfInClusterArtifactServiceURL = ZarfInClusterGitServiceURL + "/api/packages/" + ZarfGitPushUser ) +// Could also do password bytes here + // GeneratedPKI is a struct for storing generated PKI data. type GeneratedPKI struct { CA []byte `json:"ca"` @@ -54,6 +56,12 @@ func (p GeneratedPKI) LogValue() slog.Value { ) } +type Password string + +func (p Password) LogValue() slog.Value { + return slog.StringValue("REDACTED") +} + // ZarfState is maintained as a secret in the Zarf namespace to track Zarf init data. type ZarfState struct { // Indicates if Zarf was initialized while deploying its own k8s cluster @@ -127,11 +135,11 @@ type GitServerInfo struct { // Username of a user with push access to the git repository PushUsername string `json:"pushUsername"` // Password of a user with push access to the git repository - PushPassword string `json:"pushPassword"` + PushPassword Password `json:"pushPassword"` // Username of a user with pull-only access to the git repository. If not provided for an external repository then the push-user is used PullUsername string `json:"pullUsername"` // Password of a user with pull-only access to the git repository. If not provided for an external repository then the push-user is used - PullPassword string `json:"pullPassword"` + PullPassword Password `json:"pullPassword"` // URL address of the git server Address string `json:"address"` } @@ -139,9 +147,9 @@ type GitServerInfo struct { func (gs GitServerInfo) LogValue() slog.Value { return slog.GroupValue( slog.String("pushUsername", gs.PushUsername), - slog.String("pushPassword", "**sanitized**"), + slog.Any("pushPassword", gs.PushPassword), slog.String("pullUsername", gs.PullUsername), - slog.String("pullPassword", "**sanitized**"), + slog.Any("pullPassword", gs.PullPassword), slog.String("address", gs.Address), ) } @@ -151,6 +159,15 @@ func (gs GitServerInfo) IsInternal() bool { return gs.Address == ZarfInClusterGitServiceURL } +// Just for POC quickness +func RandomString() (Password, error) { + rand, err := helpers.RandomString(ZarfGeneratedPasswordLen) + if err != nil { + return "", err + } + return Password(rand), nil +} + // FillInEmptyValues sets every necessary value that's currently empty to a reasonable default func (gs *GitServerInfo) FillInEmptyValues() error { var err error @@ -161,7 +178,7 @@ func (gs *GitServerInfo) FillInEmptyValues() error { // Generate a push-user password if not provided by init flag if gs.PushPassword == "" { - if gs.PushPassword, err = helpers.RandomString(ZarfGeneratedPasswordLen); err != nil { + if gs.PushPassword, err = RandomString(); err != nil { return fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) } } @@ -176,7 +193,7 @@ func (gs *GitServerInfo) FillInEmptyValues() error { } if gs.PullPassword == "" { if gs.IsInternal() { - if gs.PullPassword, err = helpers.RandomString(ZarfGeneratedPasswordLen); err != nil { + if gs.PullPassword, err = RandomString(); err != nil { return fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) } } else { @@ -192,7 +209,7 @@ type ArtifactServerInfo struct { // Username of a user with push access to the artifact registry PushUsername string `json:"pushUsername"` // Password of a user with push access to the artifact registry - PushToken string `json:"pushPassword"` + PushToken Password `json:"pushPassword"` // URL address of the artifact registry Address string `json:"address"` } @@ -200,7 +217,7 @@ type ArtifactServerInfo struct { func (as ArtifactServerInfo) LogValue() slog.Value { return slog.GroupValue( slog.String("pushUsername", as.PushUsername), - slog.String("pushToken", "**sanitized**"), + slog.Any("pushToken", as.PushToken), slog.String("address", as.Address), ) } @@ -228,28 +245,28 @@ type RegistryInfo struct { // Username of a user with push access to the registry PushUsername string `json:"pushUsername"` // Password of a user with push access to the registry - PushPassword string `json:"pushPassword"` + PushPassword Password `json:"pushPassword"` // Username of a user with pull-only access to the registry. If not provided for an external registry than the push-user is used PullUsername string `json:"pullUsername"` // Password of a user with pull-only access to the registry. If not provided for an external registry than the push-user is used - PullPassword string `json:"pullPassword"` + PullPassword Password `json:"pullPassword"` // URL address of the registry Address string `json:"address"` // Nodeport of the registry. Only needed if the registry is running inside the kubernetes cluster NodePort int `json:"nodePort"` // Secret value that the registry was seeded with - Secret string `json:"secret"` + Secret Password `json:"secret"` } func (ri RegistryInfo) LogValue() slog.Value { return slog.GroupValue( slog.String("pushUsername", ri.PushUsername), - slog.String("pushPassword", "**sanitized**"), + slog.Any("pushPassword", ri.PushPassword), slog.String("pullUsername", ri.PullUsername), - slog.String("pullPassword", "**sanitized**"), + slog.Any("pullPassword", ri.PullPassword), slog.String("address", ri.Address), slog.Int("nodePort", ri.NodePort), - slog.String("secret", "**sanitized**"), + slog.Any("secret", ri.Secret), ) } @@ -273,7 +290,7 @@ func (ri *RegistryInfo) FillInEmptyValues() error { // Generate a push-user password if not provided by init flag if ri.PushPassword == "" { - if ri.PushPassword, err = helpers.RandomString(ZarfGeneratedPasswordLen); err != nil { + if ri.PushPassword, err = RandomString(); err != nil { return fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) } } @@ -289,7 +306,7 @@ func (ri *RegistryInfo) FillInEmptyValues() error { } if ri.PullPassword == "" { if ri.IsInternal() { - if ri.PullPassword, err = helpers.RandomString(ZarfGeneratedPasswordLen); err != nil { + if ri.PullPassword, err = RandomString(); err != nil { return fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) } } else { @@ -299,7 +316,7 @@ func (ri *RegistryInfo) FillInEmptyValues() error { } if ri.Secret == "" { - if ri.Secret, err = helpers.RandomString(ZarfGeneratedSecretLen); err != nil { + if ri.Secret, err = RandomString(); err != nil { return fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) } } From 87adca85410aa2d5d868eea3ff0d9ab52a560a44 Mon Sep 17 00:00:00 2001 From: Austin Abro Date: Wed, 9 Oct 2024 16:07:07 +0000 Subject: [PATCH 5/6] comment Signed-off-by: Austin Abro --- src/pkg/cluster/state.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkg/cluster/state.go b/src/pkg/cluster/state.go index 97e9278c0a..f622f520b3 100644 --- a/src/pkg/cluster/state.go +++ b/src/pkg/cluster/state.go @@ -215,7 +215,7 @@ func (c *Cluster) debugPrintZarfState(state *types.ZarfState) { if state == nil { return } - // OFC IRL we woul + // IRL we would make this elsewhere logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})) logger.Debug("testing slog", "zarfState", state) } From fc9bf6e7653166859fd5dc8e93bc3bdfb6d27c0a Mon Sep 17 00:00:00 2001 From: Austin Abro Date: Wed, 9 Oct 2024 16:10:54 +0000 Subject: [PATCH 6/6] implement for the others Signed-off-by: Austin Abro --- src/pkg/message/credentials.go | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/pkg/message/credentials.go b/src/pkg/message/credentials.go index ae99d3e6f7..0ef1029146 100644 --- a/src/pkg/message/credentials.go +++ b/src/pkg/message/credentials.go @@ -99,24 +99,18 @@ func PrintCredentialUpdates(oldState *types.ZarfState, newState *types.ZarfState HorizontalRule() switch service { - // case RegistryKey: - // oR := oldState.RegistryInfo - // nR := newState.RegistryInfo - // Title("Registry", "the information used to interact with Zarf's container image registry") - // pterm.Println() - // logger.Info("Registry information", compareStrings(oR.Address, nR.Address), - // compareStrings(oR.PushUsername, nR.PushUsername), comparePasswords(oR.PushPassword, nR.PushPassword), - // compareStrings(oR.PullUsername, nR.PullUsername), comparePasswords(oR.PullPassword, nR.PullPassword)) - // case GitKey: - // oG := oldState.GitServer - // nG := newState.GitServer - // Title("Git Server", "the information used to interact with Zarf's GitOps Git Server") - // pterm.Println() - // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("URL Address"), compareStrings(oG.Address, nG.Address, false)) - // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Push Username"), compareStrings(oG.PushUsername, nG.PushUsername, false)) - // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Push Password"), compareStrings(oG.PushPassword, nG.PushPassword, true)) - // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Pull Username"), compareStrings(oG.PullUsername, nG.PullUsername, false)) - // pterm.Printfln(" %s: %s", pterm.Bold.Sprint("Pull Password"), compareStrings(oG.PullPassword, nG.PullPassword, true)) + case RegistryKey: + oR := oldState.RegistryInfo + nR := newState.RegistryInfo + logger.Info("Registry information", compareStrings("URL Address", oR.Address, nR.Address), + compareStrings("Push Username", oR.PushUsername, nR.PushUsername), comparePasswords("Push Password", oR.PushPassword, nR.PushPassword), + compareStrings("Pull Username", oR.PullUsername, nR.PullUsername), comparePasswords("Push Password", oR.PullPassword, nR.PullPassword)) + case GitKey: + oG := oldState.GitServer + nG := newState.GitServer + logger.Info("Git Server info", compareStrings("URL Address", oG.Address, nG.Address), + compareStrings("Push Username", oG.PushUsername, nG.PushUsername), comparePasswords("Push Password", oG.PushPassword, nG.PushPassword), + compareStrings("Pull Username", oG.PullUsername, nG.PullUsername), comparePasswords("Push Password", oG.PullPassword, nG.PullPassword)) case ArtifactKey: oA := oldState.ArtifactServer nA := newState.ArtifactServer