diff --git a/src/config/lang/english.go b/src/config/lang/english.go index 6c14bafa6a..d14bf0b23d 100644 --- a/src/config/lang/english.go +++ b/src/config/lang/english.go @@ -15,11 +15,11 @@ import "errors" // Debug messages will not be a part of the language strings since they are not intended to be user facing // Include sprintf formatting directives in the string if needed. const ( - ErrLoadState = "Failed to load the Zarf State from the Kubernetes cluster." - ErrSaveState = "Failed to save the Zarf State to the Kubernetes cluster." - ErrLoadPackageSecret = "Failed to load %s's secret from the Kubernetes cluster" - ErrNoClusterConnection = "Failed to connect to the Kubernetes cluster." - ErrTunnelFailed = "Failed to create a tunnel to the Kubernetes cluster." + ErrLoadState = "Failed to load the Zarf State from the cluster." + ErrSaveState = "Failed to save the Zarf State to the cluster." + ErrLoadPackageSecret = "Failed to load %s's secret from the cluster" + ErrNoClusterConnection = "Failed to connect to the cluster." + ErrTunnelFailed = "Failed to create a tunnel to the cluster." ErrUnmarshal = "failed to unmarshal file: %w" ErrWritingFile = "failed to write file %s: %s" ErrDownloading = "failed to download %s: %s" diff --git a/src/pkg/cluster/state.go b/src/pkg/cluster/state.go index af13f4322f..b9025b7b47 100644 --- a/src/pkg/cluster/state.go +++ b/src/pkg/cluster/state.go @@ -13,6 +13,7 @@ import ( "github.com/defenseunicorns/zarf/src/config" "github.com/defenseunicorns/zarf/src/types" + "github.com/fatih/color" "github.com/defenseunicorns/zarf/src/pkg/k8s" "github.com/defenseunicorns/zarf/src/pkg/message" @@ -157,7 +158,7 @@ func (c *Cluster) LoadZarfState() (state *types.ZarfState, err error) { // Set up the API connection secret, err := c.GetSecret(ZarfNamespaceName, ZarfStateSecretName) if err != nil { - return nil, err + return nil, fmt.Errorf("%w. %s", err, utils.ColorWrap("Did you remember to zarf init?", color.Bold)) } err = json.Unmarshal(secret.Data[ZarfStateDataKey], &state) diff --git a/src/pkg/packager/deploy.go b/src/pkg/packager/deploy.go index e4a498f0f8..53dbdb7351 100644 --- a/src/pkg/packager/deploy.go +++ b/src/pkg/packager/deploy.go @@ -14,6 +14,7 @@ import ( "time" "github.com/defenseunicorns/zarf/src/config" + "github.com/defenseunicorns/zarf/src/config/lang" "github.com/defenseunicorns/zarf/src/internal/packager/git" "github.com/defenseunicorns/zarf/src/internal/packager/helm" "github.com/defenseunicorns/zarf/src/internal/packager/images" @@ -74,7 +75,7 @@ func (p *Packager) Deploy() (err error) { // Get a list of all the components we are deploying and actually deploy them deployedComponents, err := p.deployComponents() if err != nil { - return fmt.Errorf("unable to deploy all components in this Zarf Package: %w", err) + return err } if len(deployedComponents) == 0 { message.Warn("No components were selected for deployment. Inspect the package to view the available components and select components interactively or by name with \"--components\"") @@ -165,11 +166,11 @@ func (p *Packager) deployComponents() (deployedComponents []types.DeployedCompon deployedComponents[idx].Status = types.ComponentStatusFailed if p.isConnectedToCluster() { if _, err := p.cluster.RecordPackageDeploymentAndWait(p.cfg.Pkg, deployedComponents, p.connectStrings, p.generation, component, p.cfg.DeployOpts.SkipWebhooks); err != nil { - message.Debugf("Unable to record package deployment for component %s: this will affect features like `zarf package remove`: %s", component.Name, err.Error()) + message.Debugf("Unable to record package deployment for component %q: this will affect features like `zarf package remove`: %s", component.Name, err.Error()) } } - return deployedComponents, fmt.Errorf("unable to deploy component %s: %w", component.Name, deployErr) + return deployedComponents, fmt.Errorf("unable to deploy component %q: %w", component.Name, deployErr) } // Update the package secret to indicate that we successfully deployed this component @@ -177,7 +178,7 @@ func (p *Packager) deployComponents() (deployedComponents []types.DeployedCompon deployedComponents[idx].Status = types.ComponentStatusSucceeded if p.isConnectedToCluster() { if _, err := p.cluster.RecordPackageDeploymentAndWait(p.cfg.Pkg, deployedComponents, p.connectStrings, p.generation, component, p.cfg.DeployOpts.SkipWebhooks); err != nil { - message.Debugf("Unable to record package deployment for component %s: this will affect features like `zarf package remove`: %s", component.Name, err.Error()) + message.Debugf("Unable to record package deployment for component %q: this will affect features like `zarf package remove`: %s", component.Name, err.Error()) } } @@ -222,7 +223,7 @@ func (p *Packager) deployInitComponent(component types.ZarfComponent) (charts [] charts, err = p.deployComponent(component, isAgent /* skip img checksum if isAgent */, isSeedRegistry /* skip image push if isSeedRegistry */) if err != nil { - return charts, fmt.Errorf("unable to deploy component %s: %w", component.Name, err) + return charts, fmt.Errorf("unable to deploy component %q: %w", component.Name, err) } // Do cleanup for when we inject the seed registry during initialization @@ -266,7 +267,7 @@ func (p *Packager) deployComponent(component types.ZarfComponent, noImgChecksum // Setup the state in the config and get the valuesTemplate p.valueTemplate, err = p.setupStateValuesTemplate() if err != nil { - return charts, fmt.Errorf("unable to get the updated value template: %w", err) + return charts, err } // Disable the registry HPA scale down if we are deploying images and it is not already disabled @@ -402,7 +403,7 @@ func (p *Packager) setupStateValuesTemplate() (values *template.Values, err erro state, err := p.cluster.LoadZarfState() // Return on error if we are not in YOLO mode if err != nil && !p.cfg.Pkg.Metadata.YOLO { - return nil, fmt.Errorf("unable to load the Zarf State from the Kubernetes cluster: %w", err) + return nil, fmt.Errorf("%s %w", lang.ErrLoadState, err) } else if state == nil && p.cfg.Pkg.Metadata.YOLO { state = &types.ZarfState{} // YOLO mode, so minimal state needed diff --git a/src/test/common.go b/src/test/common.go index 34d877c659..e760f6e2eb 100644 --- a/src/test/common.go +++ b/src/test/common.go @@ -130,11 +130,14 @@ func (e2e *ZarfE2ETest) GetZarfVersion(t *testing.T) string { return strings.Trim(stdOut, "\n") } -// StripANSICodes strips any ANSI color codes from a given string -func (e2e *ZarfE2ETest) StripANSICodes(input string) string { +// StripMessageFormatting strips any ANSI color codes and extra spaces from a given string +func (e2e *ZarfE2ETest) StripMessageFormatting(input string) string { // Regex to strip any color codes from the output - https://regex101.com/r/YFyIwC/2 ansiRegex := regexp.MustCompile(`\x1b\[(.*?)m`) - return ansiRegex.ReplaceAllString(input, "") + unAnsiInput := ansiRegex.ReplaceAllString(input, "") + // Regex to strip any more than two spaces or newline - https://regex101.com/r/wqQmys/1 + multiSpaceRegex := regexp.MustCompile(`\s{2,}|\n`) + return multiSpaceRegex.ReplaceAllString(unAnsiInput, " ") } // NormalizeYAMLFilenames normalizes YAML filenames / paths across Operating Systems (i.e Windows vs Linux) diff --git a/src/test/e2e/25_helm_test.go b/src/test/e2e/25_helm_test.go index 8bd117e013..b76e2644c6 100644 --- a/src/test/e2e/25_helm_test.go +++ b/src/test/e2e/25_helm_test.go @@ -46,15 +46,15 @@ func testHelmChartsExample(t *testing.T) { evilChartDepsPath := filepath.Join("src", "test", "packages", "25-evil-chart-deps") stdOut, stdErr, err = e2e.Zarf("package", "create", evilChartDepsPath, "--tmpdir", tmpdir, "--confirm") require.Error(t, err, stdOut, stdErr) - require.Contains(t, e2e.StripANSICodes(stdErr), "could not download\n https://charts.jetstack.io/charts/cert-manager-v1.11.1.tgz") + require.Contains(t, e2e.StripMessageFormatting(stdErr), "could not download https://charts.jetstack.io/charts/cert-manager-v1.11.1.tgz") require.FileExists(t, filepath.Join(evilChartDepsPath, "good-chart", "charts", "gitlab-runner-0.55.0.tgz")) // Create a package with a chart name that doesn't exist in a repo evilChartLookupPath := filepath.Join("src", "test", "packages", "25-evil-chart-lookup") stdOut, stdErr, err = e2e.Zarf("package", "create", evilChartLookupPath, "--tmpdir", tmpdir, "--confirm") require.Error(t, err, stdOut, stdErr) - require.Contains(t, e2e.StripANSICodes(stdErr), "chart \"asdf\" version \"6.4.0\" not found") - require.Contains(t, e2e.StripANSICodes(stdErr), "Available charts and versions from \"https://stefanprodan.github.io/podinfo\":") + require.Contains(t, e2e.StripMessageFormatting(stdErr), "chart \"asdf\" version \"6.4.0\" not found") + require.Contains(t, e2e.StripMessageFormatting(stdErr), "Available charts and versions from \"https://stefanprodan.github.io/podinfo\":") // Create the package with a registry override stdOut, stdErr, err = e2e.Zarf("package", "create", "examples/helm-charts", "-o", "build", "--registry-override", "ghcr.io=docker.io", "--tmpdir", tmpdir, "--confirm") diff --git a/src/test/e2e/29_mismatched_checks_test.go b/src/test/e2e/29_mismatched_checks_test.go index 2ce08b44c0..0522f5c04f 100644 --- a/src/test/e2e/29_mismatched_checks_test.go +++ b/src/test/e2e/29_mismatched_checks_test.go @@ -35,7 +35,7 @@ func TestMismatchedArchitectures(t *testing.T) { // Ensure zarf package deploy returns an error because of the mismatched architectures. _, stdErr, err = e2e.Zarf("package", "deploy", mismatchedGamesPackage, "--confirm") require.Error(t, err, stdErr) - require.Contains(t, stdErr, expectedErrorMessage) + require.Contains(t, e2e.StripMessageFormatting(stdErr), expectedErrorMessage) } // TestMismatchedVersions ensures that zarf produces a warning