Skip to content

Commit

Permalink
refactor: move table printing out of pkg
Browse files Browse the repository at this point in the history
Signed-off-by: Philip Laine <[email protected]>
  • Loading branch information
phillebaba committed Sep 4, 2024
1 parent e7f2627 commit 3a67536
Show file tree
Hide file tree
Showing 12 changed files with 243 additions and 274 deletions.
170 changes: 169 additions & 1 deletion src/cmd/common/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,46 @@ package common
import (
"fmt"
"path/filepath"
"strings"

"github.com/defenseunicorns/pkg/helpers/v2"
"github.com/fatih/color"
"github.com/pterm/pterm"

"github.com/zarf-dev/zarf/src/pkg/cluster"
"github.com/zarf-dev/zarf/src/pkg/lint"
"github.com/zarf-dev/zarf/src/pkg/message"
"github.com/zarf-dev/zarf/src/types"
)

// Table prints a padded table containing the specified header and data
func Table(header []string, data [][]string) {
pterm.Println()

// To avoid side effects make copies of the header and data before adding padding
headerCopy := make([]string, len(header))
copy(headerCopy, header)
dataCopy := make([][]string, len(data))
copy(dataCopy, data)
if len(headerCopy) > 0 {
headerCopy[0] = fmt.Sprintf(" %s", headerCopy[0])
}

table := pterm.TableData{
headerCopy,
}

for _, row := range dataCopy {
if len(row) > 0 {
row[0] = fmt.Sprintf(" %s", row[0])
}
table = append(table, pterm.TableData{row}...)
}

//nolint:errcheck // never returns an error
pterm.DefaultTable.WithHasHeader().WithData(table).Render()
}

// PrintFindings prints the findings in the LintError as a table.
func PrintFindings(lintErr *lint.LintError) {
mapOfFindingsByPath := lint.GroupFindingsByPath(lintErr.Findings, lintErr.PackageName)
Expand Down Expand Up @@ -41,7 +73,7 @@ func PrintFindings(lintErr *lint.LintError) {
packagePathFromUser = filepath.Join(lintErr.BaseDir, findings[0].PackagePathOverride)
}
message.Notef("Linting package %q at %s", findings[0].PackageNameOverride, packagePathFromUser)
message.Table([]string{"Type", "Path", "Message"}, lintData)
Table([]string{"Type", "Path", "Message"}, lintData)
}
}

Expand All @@ -51,3 +83,139 @@ func colorWrap(str string, attr color.Attribute) string {
}
return fmt.Sprintf("\x1b[%dm%s\x1b[0m", attr, str)
}

// PrintConnectStringTable prints a table of connect strings.
func PrintConnectStringTable(connectStrings types.ConnectStrings) {
if len(connectStrings) == 0 {
return
}

connectData := [][]string{}
for name, connect := range connectStrings {
name = fmt.Sprintf("zarf connect %s", name)
connectData = append(connectData, []string{name, connect.Description})
}
header := []string{"Connect Command", "Description"}
Table(header, connectData)
}

// PrintCredentialTable displays credentials in a table
func PrintCredentialTable(state *types.ZarfState, componentsToDeploy []types.DeployedComponent) {
if len(componentsToDeploy) == 0 {
componentsToDeploy = []types.DeployedComponent{{Name: "git-server"}}
}

// Pause the logfile's output to avoid credentials being printed to the log file
// if logFile != nil {
// logFile.Pause()
// defer logFile.Resume()
// }

loginData := [][]string{}
if state.RegistryInfo.IsInternal() {
loginData = append(loginData,
[]string{"Registry", state.RegistryInfo.PushUsername, state.RegistryInfo.PushPassword, "zarf connect registry", cluster.RegistryKey},
[]string{"Registry (read-only)", state.RegistryInfo.PullUsername, state.RegistryInfo.PullPassword, "zarf connect registry", cluster.RegistryReadKey},
)
}

for _, component := range componentsToDeploy {
// 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", cluster.GitKey},
[]string{"Git (read-only)", state.GitServer.PullUsername, state.GitServer.PullPassword, "zarf connect git", cluster.GitReadKey},
[]string{"Artifact Token", state.ArtifactServer.PushUsername, state.ArtifactServer.PushToken, "zarf connect git", cluster.ArtifactKey},
)
}
}

if len(loginData) > 0 {
header := []string{"Application", "Username", "Password", "Connect", "Get-Creds Key"}
Table(header, loginData)
}
}

// PrintComponentCredential displays credentials for a single component
func PrintComponentCredential(state *types.ZarfState, componentName string) {
switch strings.ToLower(componentName) {
case cluster.GitKey:
message.Notef("Git Server push password (username: %s):", state.GitServer.PushUsername)
fmt.Println(state.GitServer.PushPassword)

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

Sensitive data returned by an access to PushPassword
flows to a logging call.
case cluster.GitReadKey:
message.Notef("Git Server (read-only) password (username: %s):", state.GitServer.PullUsername)
fmt.Println(state.GitServer.PullPassword)

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

Sensitive data returned by an access to PullPassword
flows to a logging call.
case cluster.ArtifactKey:
message.Notef("Artifact Server token (username: %s):", state.ArtifactServer.PushUsername)
fmt.Println(state.ArtifactServer.PushToken)
case cluster.RegistryKey:
message.Notef("Image Registry password (username: %s):", state.RegistryInfo.PushUsername)
fmt.Println(state.RegistryInfo.PushPassword)

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

Sensitive data returned by an access to PushPassword
flows to a logging call.
case cluster.RegistryReadKey:
message.Notef("Image Registry (read-only) password (username: %s):", state.RegistryInfo.PullUsername)
fmt.Println(state.RegistryInfo.PullPassword)

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

Sensitive data returned by an access to PullPassword
flows to a logging call.
default:
message.Warn("Unknown component: " + componentName)
}
}

// PrintCredentialUpdates displays credentials that will be updated
func PrintCredentialUpdates(oldState *types.ZarfState, newState *types.ZarfState, services []string) {
for _, service := range services {
message.HorizontalRule()

switch service {
case cluster.RegistryKey:
oR := oldState.RegistryInfo
nR := newState.RegistryInfo
message.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 cluster.GitKey:
oG := oldState.GitServer
nG := newState.GitServer
message.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 cluster.ArtifactKey:
oA := oldState.ArtifactServer
nA := newState.ArtifactServer
message.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 cluster.AgentKey:
oT := oldState.AgentTLS
nT := newState.AgentTLS
message.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 {
if new == old {
if secret {
return "**sanitized** (unchanged)"
}
return fmt.Sprintf("%s (unchanged)", old)
}
if secret {
return fmt.Sprintf("%s -> %s", pterm.FgRed.Sprint("**existing (sanitized)**"), pterm.FgGreen.Sprint("**replacement (sanitized)**"))
}
return fmt.Sprintf("%s -> %s", pterm.FgRed.Sprint(old), pterm.FgGreen.Sprint(new))
}
3 changes: 2 additions & 1 deletion src/cmd/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/spf13/cobra"

"github.com/zarf-dev/zarf/src/cmd/common"
"github.com/zarf-dev/zarf/src/config/lang"
"github.com/zarf-dev/zarf/src/pkg/cluster"
"github.com/zarf-dev/zarf/src/pkg/message"
Expand Down Expand Up @@ -98,7 +99,7 @@ var connectListCmd = &cobra.Command{
if err != nil {
return err
}
message.PrintConnectStringTable(connections)
common.PrintConnectStringTable(connections)
return nil
},
}
Expand Down
16 changes: 15 additions & 1 deletion src/cmd/initialize.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,24 @@ var initCmd = &cobra.Command{
}
defer pkgClient.ClearTempPaths()

err = pkgClient.Deploy(cmd.Context())
deployedComponents, err := pkgClient.Deploy(cmd.Context())
if err != nil {
return err
}

// Don't print if cluster is not configured
cluster := pkgClient.GetCluster()
if cluster == nil {
return nil
}

// Grab a fresh copy of the state to print the most up-to-date version of the creds
latestState, err := cluster.LoadZarfState(cmd.Context())
if err != nil {
return err
}
common.PrintCredentialTable(latestState, deployedComponents)

return nil
},
}
Expand Down
18 changes: 14 additions & 4 deletions src/cmd/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,21 @@ var packageDeployCmd = &cobra.Command{
}
defer pkgClient.ClearTempPaths()

ctx := cmd.Context()

if err := pkgClient.Deploy(ctx); err != nil {
deployedComponents, err := pkgClient.Deploy(cmd.Context())
if err != nil {
return fmt.Errorf("failed to deploy package: %w", err)
}

connectStrings := types.ConnectStrings{}
for _, comp := range deployedComponents {
for _, chart := range comp.InstalledCharts {
for k, v := range chart.ConnectStrings {
connectStrings[k] = v
}
}
}
common.PrintConnectStringTable(connectStrings)

return nil
},
}
Expand Down Expand Up @@ -193,7 +203,7 @@ var packageListCmd = &cobra.Command{
}

header := []string{"Package", "Version", "Components"}
message.Table(header, packageData)
common.Table(header, packageData)

// Print out any unmarshalling errors
if err != nil {
Expand Down
20 changes: 10 additions & 10 deletions src/cmd/tools/zarf.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ var getCredsCmd = &cobra.Command{

if len(args) > 0 {
// If a component name is provided, only show that component's credentials
message.PrintComponentCredential(state, args[0])
common.PrintComponentCredential(state, args[0])
} else {
message.PrintCredentialTable(state, nil)
common.PrintCredentialTable(state, nil)
}
return nil
},
Expand All @@ -90,7 +90,7 @@ 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}
validKeys := []string{cluster.RegistryKey, cluster.GitKey, cluster.ArtifactKey, cluster.AgentKey}
if len(args) == 0 {
args = validKeys
} else {
Expand Down Expand Up @@ -122,7 +122,7 @@ var updateCredsCmd = &cobra.Command{
return fmt.Errorf("unable to update Zarf credentials: %w", err)
}

message.PrintCredentialUpdates(oldState, newState, args)
common.PrintCredentialUpdates(oldState, newState, args)

confirm := config.CommonOptions.Confirm

Expand All @@ -139,13 +139,13 @@ var updateCredsCmd = &cobra.Command{

if confirm {
// Update registry and git pull secrets
if slices.Contains(args, message.RegistryKey) {
if slices.Contains(args, cluster.RegistryKey) {
err := c.UpdateZarfManagedImageSecrets(ctx, newState)
if err != nil {
return err
}
}
if slices.Contains(args, message.GitKey) {
if slices.Contains(args, cluster.GitKey) {
err := c.UpdateZarfManagedGitSecrets(ctx, newState)
if err != nil {
return err
Expand All @@ -159,7 +159,7 @@ var updateCredsCmd = &cobra.Command{
}

// Update artifact token (if internal)
if slices.Contains(args, message.ArtifactKey) && newState.ArtifactServer.PushToken == "" && newState.ArtifactServer.IsInternal() && internalGitServerExists {
if slices.Contains(args, cluster.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)
Expand All @@ -175,20 +175,20 @@ var updateCredsCmd = &cobra.Command{
// 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() {
if slices.Contains(args, cluster.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 {
if slices.Contains(args, cluster.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) {
if slices.Contains(args, cluster.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)
Expand Down
Loading

0 comments on commit 3a67536

Please sign in to comment.