From 546e6651d77ffd25fed422f41b596de7706071ac Mon Sep 17 00:00:00 2001 From: Philip Laine Date: Fri, 16 Aug 2024 04:58:52 +0200 Subject: [PATCH 01/22] refactor: store managed secrets and add tests (#2892) Signed-off-by: Philip Laine --- src/cmd/tools/zarf.go | 10 +- src/pkg/cluster/secrets.go | 112 ++++++------- src/pkg/cluster/secrets_test.go | 274 +++++++++++++++++++++----------- 3 files changed, 243 insertions(+), 153 deletions(-) diff --git a/src/cmd/tools/zarf.go b/src/cmd/tools/zarf.go index 7c6ba91e88..39c622c714 100644 --- a/src/cmd/tools/zarf.go +++ b/src/cmd/tools/zarf.go @@ -141,10 +141,16 @@ var updateCredsCmd = &cobra.Command{ if confirm { // Update registry and git pull secrets if slices.Contains(args, message.RegistryKey) { - c.UpdateZarfManagedImageSecrets(ctx, newState) + err := c.UpdateZarfManagedImageSecrets(ctx, newState) + if err != nil { + return err + } } if slices.Contains(args, message.GitKey) { - c.UpdateZarfManagedGitSecrets(ctx, newState) + err := c.UpdateZarfManagedGitSecrets(ctx, newState) + if err != nil { + return err + } } // Update artifact token (if internal) diff --git a/src/pkg/cluster/secrets.go b/src/pkg/cluster/secrets.go index 43c3402b64..aa693c6a44 100644 --- a/src/pkg/cluster/secrets.go +++ b/src/pkg/cluster/secrets.go @@ -13,6 +13,7 @@ import ( "maps" corev1 "k8s.io/api/core/v1" + kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/zarf-dev/zarf/src/config" @@ -112,78 +113,79 @@ func (c *Cluster) GenerateGitPullCreds(namespace, name string, gitServerInfo typ } // UpdateZarfManagedImageSecrets updates all Zarf-managed image secrets in all namespaces based on state -// TODO: Refactor to return errors properly. -func (c *Cluster) UpdateZarfManagedImageSecrets(ctx context.Context, state *types.ZarfState) { +func (c *Cluster) UpdateZarfManagedImageSecrets(ctx context.Context, state *types.ZarfState) error { spinner := message.NewProgressSpinner("Updating existing Zarf-managed image secrets") defer spinner.Stop() namespaceList, err := c.Clientset.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) if err != nil { - spinner.Errorf(err, "Unable to get k8s namespaces") - } else { - // Update all image pull secrets - for _, namespace := range namespaceList.Items { - currentRegistrySecret, err := c.Clientset.CoreV1().Secrets(namespace.Name).Get(ctx, config.ZarfImagePullSecretName, metav1.GetOptions{}) - if err != nil { - continue - } - - // Check if this is a Zarf managed secret or is in a namespace the Zarf agent will take action in - if currentRegistrySecret.Labels[ZarfManagedByLabel] == "zarf" || - (namespace.Labels[AgentLabel] != "skip" && namespace.Labels[AgentLabel] != "ignore") { - spinner.Updatef("Updating existing Zarf-managed image secret for namespace: '%s'", namespace.Name) - - newRegistrySecret, err := c.GenerateRegistryPullCreds(ctx, namespace.Name, config.ZarfImagePullSecretName, state.RegistryInfo) - if err != nil { - message.WarnErrf(err, "Unable to generate registry creds") - continue - } - if !maps.EqualFunc(currentRegistrySecret.Data, newRegistrySecret.Data, func(v1, v2 []byte) bool { return bytes.Equal(v1, v2) }) { - _, err := c.Clientset.CoreV1().Secrets(newRegistrySecret.Namespace).Update(ctx, newRegistrySecret, metav1.UpdateOptions{}) - if err != nil { - message.WarnErrf(err, "Problem creating registry secret for the %s namespace", namespace.Name) - } - } - } + return err + } + // Update all image pull secrets + for _, namespace := range namespaceList.Items { + currentRegistrySecret, err := c.Clientset.CoreV1().Secrets(namespace.Name).Get(ctx, config.ZarfImagePullSecretName, metav1.GetOptions{}) + if kerrors.IsNotFound(err) { + continue + } + if err != nil { + return err + } + // Skip if namespace is skipped and secret is not managed by Zarf. + if currentRegistrySecret.Labels[ZarfManagedByLabel] != "zarf" && (namespace.Labels[AgentLabel] == "skip" || namespace.Labels[AgentLabel] == "ignore") { + continue + } + newRegistrySecret, err := c.GenerateRegistryPullCreds(ctx, namespace.Name, config.ZarfImagePullSecretName, state.RegistryInfo) + if err != nil { + return err + } + if maps.EqualFunc(currentRegistrySecret.Data, newRegistrySecret.Data, func(v1, v2 []byte) bool { return bytes.Equal(v1, v2) }) { + continue + } + spinner.Updatef("Updating existing Zarf-managed image secret for namespace: '%s'", namespace.Name) + _, err = c.Clientset.CoreV1().Secrets(newRegistrySecret.Namespace).Update(ctx, newRegistrySecret, metav1.UpdateOptions{}) + if err != nil { + return err } - spinner.Success() } + + spinner.Success() + return nil } // UpdateZarfManagedGitSecrets updates all Zarf-managed git secrets in all namespaces based on state -// TODO: Refactor to return errors properly. -func (c *Cluster) UpdateZarfManagedGitSecrets(ctx context.Context, state *types.ZarfState) { +func (c *Cluster) UpdateZarfManagedGitSecrets(ctx context.Context, state *types.ZarfState) error { spinner := message.NewProgressSpinner("Updating existing Zarf-managed git secrets") defer spinner.Stop() namespaceList, err := c.Clientset.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) if err != nil { - spinner.Errorf(err, "Unable to get k8s namespaces") - } else { - // Update all git pull secrets - for _, namespace := range namespaceList.Items { - currentGitSecret, err := c.Clientset.CoreV1().Secrets(namespace.Name).Get(ctx, config.ZarfGitServerSecretName, metav1.GetOptions{}) - if err != nil { - continue - } - - // Check if this is a Zarf managed secret or is in a namespace the Zarf agent will take action in - if currentGitSecret.Labels[ZarfManagedByLabel] == "zarf" || - (namespace.Labels[AgentLabel] != "skip" && namespace.Labels[AgentLabel] != "ignore") { - spinner.Updatef("Updating existing Zarf-managed git secret for namespace: '%s'", namespace.Name) - - // Create the secret - newGitSecret := c.GenerateGitPullCreds(namespace.Name, config.ZarfGitServerSecretName, state.GitServer) - if !maps.Equal(currentGitSecret.StringData, newGitSecret.StringData) { - _, err := c.Clientset.CoreV1().Secrets(newGitSecret.Namespace).Update(ctx, newGitSecret, metav1.UpdateOptions{}) - if err != nil { - message.WarnErrf(err, "Problem creating git server secret for the %s namespace", namespace.Name) - } - } - } + return err + } + for _, namespace := range namespaceList.Items { + currentGitSecret, err := c.Clientset.CoreV1().Secrets(namespace.Name).Get(ctx, config.ZarfGitServerSecretName, metav1.GetOptions{}) + if kerrors.IsNotFound(err) { + continue + } + if err != nil { + continue + } + // Skip if namespace is skipped and secret is not managed by Zarf. + if currentGitSecret.Labels[ZarfManagedByLabel] != "zarf" && (namespace.Labels[AgentLabel] == "skip" || namespace.Labels[AgentLabel] == "ignore") { + continue + } + newGitSecret := c.GenerateGitPullCreds(namespace.Name, config.ZarfGitServerSecretName, state.GitServer) + if maps.Equal(currentGitSecret.StringData, newGitSecret.StringData) { + continue + } + spinner.Updatef("Updating existing Zarf-managed git secret for namespace: %s", namespace.Name) + _, err = c.Clientset.CoreV1().Secrets(newGitSecret.Namespace).Update(ctx, newGitSecret, metav1.UpdateOptions{}) + if err != nil { + return err } - spinner.Success() } + + spinner.Success() + return nil } // GetServiceInfoFromRegistryAddress gets the service info for a registry address if it is a NodePort diff --git a/src/pkg/cluster/secrets_test.go b/src/pkg/cluster/secrets_test.go index 80cd33b933..0ee731dfe9 100644 --- a/src/pkg/cluster/secrets_test.go +++ b/src/pkg/cluster/secrets_test.go @@ -4,7 +4,6 @@ package cluster import ( - "context" "testing" "github.com/stretchr/testify/require" @@ -12,114 +11,197 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" + "github.com/zarf-dev/zarf/src/config" + "github.com/zarf-dev/zarf/src/test/testutil" "github.com/zarf-dev/zarf/src/types" ) -func TestGenerateRegistryPullCredsWithOutSvc(t *testing.T) { - c := &Cluster{Clientset: fake.NewSimpleClientset()} - ctx := context.Background() - ri := types.RegistryInfo{ - PullUsername: "pull-user", - PullPassword: "pull-password", - Address: "example.com", - } - secret, err := c.GenerateRegistryPullCreds(ctx, "foo", "bar", ri) - require.NoError(t, err) - expectedSecret := corev1.Secret{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Secret", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "bar", - Namespace: "foo", - Labels: map[string]string{ - ZarfManagedByLabel: "zarf", - }, - }, - Type: corev1.SecretTypeDockerConfigJson, - Data: map[string][]byte{ - ".dockerconfigjson": []byte(`{"auths":{"example.com":{"auth":"cHVsbC11c2VyOnB1bGwtcGFzc3dvcmQ="}}}`), - }, - } - require.Equal(t, expectedSecret, *secret) -} +func TestUpdateZarfManagedSecrets(t *testing.T) { + ctx := testutil.TestContext(t) -func TestGenerateRegistryPullCredsWithSvc(t *testing.T) { - c := &Cluster{Clientset: fake.NewSimpleClientset()} - ctx := context.Background() - svc := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: "good-service", - Namespace: "whatever", + tests := []struct { + name string + namespaceLabels map[string]string + secretLabels map[string]string + updatedImageSecret bool + updatedGitSecret bool + }{ + { + name: "modify", + updatedImageSecret: true, + updatedGitSecret: true, }, - Spec: corev1.ServiceSpec{ - Type: corev1.ServiceTypeNodePort, - Ports: []corev1.ServicePort{ - { - NodePort: 30001, - Port: 3333, - }, + { + name: "skip namespace", + namespaceLabels: map[string]string{ + AgentLabel: "skip", }, - ClusterIP: "10.11.12.13", }, - } - - _, err := c.Clientset.CoreV1().Services("whatever").Create(ctx, svc, metav1.CreateOptions{}) - require.NoError(t, err) - - ri := types.RegistryInfo{ - PullUsername: "pull-user", - PullPassword: "pull-password", - Address: "127.0.0.1:30001", - } - secret, err := c.GenerateRegistryPullCreds(ctx, "foo", "bar", ri) - require.NoError(t, err) - expectedSecret := corev1.Secret{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Secret", + { + name: "ignore namespace", + namespaceLabels: map[string]string{ + AgentLabel: "ignore", + }, }, - ObjectMeta: metav1.ObjectMeta{ - Name: "bar", - Namespace: "foo", - Labels: map[string]string{ + { + name: "skip namespace managed secret", + namespaceLabels: map[string]string{ + AgentLabel: "skip", + }, + secretLabels: map[string]string{ ZarfManagedByLabel: "zarf", }, + updatedImageSecret: true, + updatedGitSecret: true, }, - Type: corev1.SecretTypeDockerConfigJson, - Data: map[string][]byte{ - ".dockerconfigjson": []byte(`{"auths":{"10.11.12.13:3333":{"auth":"cHVsbC11c2VyOnB1bGwtcGFzc3dvcmQ="},"127.0.0.1:30001":{"auth":"cHVsbC11c2VyOnB1bGwtcGFzc3dvcmQ="}}}`), - }, - } - require.Equal(t, expectedSecret, *secret) -} - -func TestGenerateGitPullCreds(t *testing.T) { - c := &Cluster{} - gi := types.GitServerInfo{ - PullUsername: "pull-user", - PullPassword: "pull-password", - } - secret := c.GenerateGitPullCreds("foo", "bar", gi) - expectedSecret := corev1.Secret{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Secret", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "bar", - Namespace: "foo", - Labels: map[string]string{ + { + name: "ignore namespace managed secret", + namespaceLabels: map[string]string{ + AgentLabel: "ignore", + }, + secretLabels: map[string]string{ ZarfManagedByLabel: "zarf", }, + updatedImageSecret: true, + updatedGitSecret: true, }, - Type: corev1.SecretTypeOpaque, - Data: map[string][]byte{}, - StringData: map[string]string{ - "username": "pull-user", - "password": "pull-password", - }, } - require.Equal(t, expectedSecret, *secret) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Cluster{ + Clientset: fake.NewSimpleClientset(), + } + + namespace := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Labels: tt.namespaceLabels, + }, + } + _, err := c.Clientset.CoreV1().Namespaces().Create(ctx, namespace, metav1.CreateOptions{}) + require.NoError(t, err) + svc := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "good-service", + Namespace: namespace.ObjectMeta.Name, + }, + Spec: corev1.ServiceSpec{ + Type: corev1.ServiceTypeNodePort, + Ports: []corev1.ServicePort{ + { + NodePort: 30001, + Port: 3333, + }, + }, + ClusterIP: "10.11.12.13", + }, + } + _, err = c.Clientset.CoreV1().Services(namespace.ObjectMeta.Name).Create(ctx, svc, metav1.CreateOptions{}) + require.NoError(t, err) + imageSecret := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: config.ZarfImagePullSecretName, + Namespace: namespace.ObjectMeta.Name, + Labels: tt.secretLabels, + }, + } + _, err = c.Clientset.CoreV1().Secrets(imageSecret.ObjectMeta.Namespace).Create(ctx, imageSecret, metav1.CreateOptions{}) + require.NoError(t, err) + gitSecret := &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: config.ZarfGitServerSecretName, + Namespace: namespace.ObjectMeta.Name, + Labels: tt.secretLabels, + }, + } + _, err = c.Clientset.CoreV1().Secrets(gitSecret.ObjectMeta.Namespace).Create(ctx, gitSecret, metav1.CreateOptions{}) + require.NoError(t, err) + + state := &types.ZarfState{ + GitServer: types.GitServerInfo{ + PullUsername: "pull-user", + PullPassword: "pull-password", + }, + RegistryInfo: types.RegistryInfo{ + PullUsername: "pull-user", + PullPassword: "pull-password", + Address: "127.0.0.1:30001", + }, + } + err = c.UpdateZarfManagedImageSecrets(ctx, state) + require.NoError(t, err) + err = c.UpdateZarfManagedGitSecrets(ctx, state) + require.NoError(t, err) + + // Make sure no new namespaces or secrets have been created. + namespaceList, err := c.Clientset.CoreV1().Namespaces().List(ctx, metav1.ListOptions{}) + require.NoError(t, err) + require.Len(t, namespaceList.Items, 1) + for _, ns := range namespaceList.Items { + secretList, err := c.Clientset.CoreV1().Secrets(ns.ObjectMeta.Name).List(ctx, metav1.ListOptions{}) + require.NoError(t, err) + require.Len(t, secretList.Items, 2) + } + + // Check image registry secret + updatedImageSecret, err := c.Clientset.CoreV1().Secrets(namespace.ObjectMeta.Name).Get(ctx, config.ZarfImagePullSecretName, metav1.GetOptions{}) + require.NoError(t, err) + expectedImageSecret := corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: config.ZarfImagePullSecretName, + Namespace: namespace.ObjectMeta.Name, + Labels: map[string]string{ + ZarfManagedByLabel: "zarf", + }, + }, + Type: corev1.SecretTypeDockerConfigJson, + Data: map[string][]byte{ + ".dockerconfigjson": []byte(`{"auths":{"10.11.12.13:3333":{"auth":"cHVsbC11c2VyOnB1bGwtcGFzc3dvcmQ="},"127.0.0.1:30001":{"auth":"cHVsbC11c2VyOnB1bGwtcGFzc3dvcmQ="}}}`), + }, + } + if !tt.updatedImageSecret { + expectedImageSecret = *imageSecret + } + require.Equal(t, expectedImageSecret, *updatedImageSecret) + + // Check git secret + updatedGitSecret, err := c.Clientset.CoreV1().Secrets(namespace.ObjectMeta.Name).Get(ctx, config.ZarfGitServerSecretName, metav1.GetOptions{}) + require.NoError(t, err) + expectedGitSecret := corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: config.ZarfGitServerSecretName, + Namespace: namespace.ObjectMeta.Name, + Labels: map[string]string{ + ZarfManagedByLabel: "zarf", + }, + }, + Type: corev1.SecretTypeOpaque, + Data: map[string][]byte{}, + StringData: map[string]string{ + "username": state.GitServer.PullUsername, + "password": state.GitServer.PullPassword, + }, + } + if !tt.updatedGitSecret { + expectedGitSecret = *gitSecret + } + require.Equal(t, expectedGitSecret, *updatedGitSecret) + }) + } } From 88370b6c770c64be930b3575ff08b36432ecc03f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 12:15:49 -0400 Subject: [PATCH 02/22] chore(deps): bump github/codeql-action from 3.26.1 to 3.26.2 (#2888) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scan-codeql.yml | 4 ++-- .github/workflows/scorecard.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scan-codeql.yml b/.github/workflows/scan-codeql.yml index 3c7bff10ec..6303f782c2 100644 --- a/.github/workflows/scan-codeql.yml +++ b/.github/workflows/scan-codeql.yml @@ -53,7 +53,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@29d86d22a34ea372b1bbf3b2dced2e25ca6b3384 # v3.26.1 + uses: github/codeql-action/init@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2 with: languages: ${{ matrix.language }} config-file: ./.github/codeql.yaml @@ -62,6 +62,6 @@ jobs: run: make build-cli-linux-amd - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@29d86d22a34ea372b1bbf3b2dced2e25ca6b3384 # v3.26.1 + uses: github/codeql-action/analyze@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml index 9ece5ff012..f677160391 100644 --- a/.github/workflows/scorecard.yaml +++ b/.github/workflows/scorecard.yaml @@ -44,6 +44,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@29d86d22a34ea372b1bbf3b2dced2e25ca6b3384 # v3.26.1 + uses: github/codeql-action/upload-sarif@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2 with: sarif_file: results.sarif From 3103295efcfb05470177141d1f0cf944841fc817 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 12:16:04 -0400 Subject: [PATCH 03/22] chore(deps): bump actions/setup-go from 5.0.0 to 5.0.2 (#2901) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/test-import.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-import.yaml b/.github/workflows/test-import.yaml index 72ad5e770f..1cc6784f04 100644 --- a/.github/workflows/test-import.yaml +++ b/.github/workflows/test-import.yaml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Setup Go - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: go-version-file: 'go.mod' cache: true From 4d3bf5d59eb9638d7aba6fad342a0daf7727d836 Mon Sep 17 00:00:00 2001 From: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Date: Tue, 20 Aug 2024 12:16:44 -0400 Subject: [PATCH 04/22] fix: update injector (#2910) Signed-off-by: Austin Abro --- packages/zarf-registry/zarf.yaml | 4 ++-- src/test/e2e/00_use_cli_test.go | 4 ++-- zarf-config.toml | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/zarf-registry/zarf.yaml b/packages/zarf-registry/zarf.yaml index 2da03ccda6..190eeba4c0 100644 --- a/packages/zarf-registry/zarf.yaml +++ b/packages/zarf-registry/zarf.yaml @@ -111,7 +111,7 @@ components: architecture: amd64 files: # Rust Injector Binary - - source: https://zarf-public.s3-us-gov-west-1.amazonaws.com/injector/###ZARF_PKG_TMPL_INJECTOR_VERSION###/zarf-injector-amd64 + - source: https://zarf-init.s3.us-east-2.amazonaws.com/injector/###ZARF_PKG_TMPL_INJECTOR_VERSION###/zarf-injector-amd64 target: "###ZARF_TEMP###/zarf-injector" shasum: "###ZARF_PKG_TMPL_INJECTOR_AMD64_SHASUM###" executable: true @@ -126,7 +126,7 @@ components: architecture: arm64 files: # Rust Injector Binary - - source: https://zarf-public.s3-us-gov-west-1.amazonaws.com/injector/###ZARF_PKG_TMPL_INJECTOR_VERSION###/zarf-injector-arm64 + - source: https://zarf-init.s3.us-east-2.amazonaws.com/injector/###ZARF_PKG_TMPL_INJECTOR_VERSION###/zarf-injector-arm64 target: "###ZARF_TEMP###/zarf-injector" shasum: "###ZARF_PKG_TMPL_INJECTOR_ARM64_SHASUM###" executable: true diff --git a/src/test/e2e/00_use_cli_test.go b/src/test/e2e/00_use_cli_test.go index b663d58454..de0c5a7a51 100644 --- a/src/test/e2e/00_use_cli_test.go +++ b/src/test/e2e/00_use_cli_test.go @@ -43,9 +43,9 @@ func TestUseCLI(t *testing.T) { t.Run("zarf prepare sha256sum ", func(t *testing.T) { t.Parallel() // Test `zarf prepare sha256sum` for a remote asset - expectedShasum := "c3cdea0573ba5a058ec090b5d2683bf398e8b1614c37ec81136ed03b78167617\n" + expectedShasum := "b905e647e0d7876cfd5b665632cfc43ad919dc60408f7236c5b541c53277b503\n" - stdOut, stdErr, err := e2e.Zarf(t, "prepare", "sha256sum", "https://zarf-public.s3-us-gov-west-1.amazonaws.com/pipelines/zarf-prepare-shasum-remote-test-file.txt") + stdOut, stdErr, err := e2e.Zarf(t, "prepare", "sha256sum", "https://zarf-init.s3.us-east-2.amazonaws.com/injector/2024-07-22/zarf-injector-arm64") require.NoError(t, err, stdOut, stdErr) require.Contains(t, stdOut, expectedShasum, "The expected SHASUM should equal the actual SHASUM") }) diff --git a/zarf-config.toml b/zarf-config.toml index 09afb3eed3..70f2ac615a 100644 --- a/zarf-config.toml +++ b/zarf-config.toml @@ -5,9 +5,9 @@ agent_image = 'zarf-dev/zarf/agent' agent_image_tag = 'local' # Tag for the zarf injector binary to use -injector_version = '2024-05-15' -injector_amd64_shasum = '1b34519ac30daf0e5a4a2f0a0766dbcd0852c0b5364b35576eea4ac9e22d9e82' -injector_arm64_shasum = 'ca20f427f9cf91ff42646a785c4772be5892a6752fa14924c5085b2d0109b008' +injector_version = '2024-07-22' +injector_amd64_shasum = '8463bfd66930a4b26c665b51f25e8a32ed5948068bae49987013c89173394478' +injector_arm64_shasum = 'b905e647e0d7876cfd5b665632cfc43ad919dc60408f7236c5b541c53277b503' # The image reference to use for the registry that Zarf deploys into the cluster From c34906bfde46eba140fe5152a6211356df192fd3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 10:20:16 -0400 Subject: [PATCH 05/22] chore(deps): bump github/codeql-action from 3.26.2 to 3.26.4 (#2916) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scan-codeql.yml | 4 ++-- .github/workflows/scorecard.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scan-codeql.yml b/.github/workflows/scan-codeql.yml index 6303f782c2..9ac8ca9b44 100644 --- a/.github/workflows/scan-codeql.yml +++ b/.github/workflows/scan-codeql.yml @@ -53,7 +53,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2 + uses: github/codeql-action/init@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 # v3.26.4 with: languages: ${{ matrix.language }} config-file: ./.github/codeql.yaml @@ -62,6 +62,6 @@ jobs: run: make build-cli-linux-amd - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2 + uses: github/codeql-action/analyze@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 # v3.26.4 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml index f677160391..09c0be4927 100644 --- a/.github/workflows/scorecard.yaml +++ b/.github/workflows/scorecard.yaml @@ -44,6 +44,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2 + uses: github/codeql-action/upload-sarif@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 # v3.26.4 with: sarif_file: results.sarif From db367cdcdd013415c4f3cd421c96de52dff71b0b Mon Sep 17 00:00:00 2001 From: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Date: Thu, 22 Aug 2024 10:56:29 -0400 Subject: [PATCH 06/22] fix: update creds not breaking when internal git server not deployed (#2904) Signed-off-by: Austin Abro --- src/cmd/tools/zarf.go | 72 ++++++--------------------- src/config/lang/english.go | 2 - src/pkg/cluster/zarf.go | 70 ++++++++++++++++++++++++++ src/pkg/cluster/zarf_test.go | 38 ++++++++++++++ src/test/e2e/21_connect_creds_test.go | 13 ++++- 5 files changed, 134 insertions(+), 61 deletions(-) diff --git a/src/cmd/tools/zarf.go b/src/cmd/tools/zarf.go index 39c622c714..5a9cd11718 100644 --- a/src/cmd/tools/zarf.go +++ b/src/cmd/tools/zarf.go @@ -21,7 +21,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/gitea" "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" @@ -70,7 +69,7 @@ var getCredsCmd = &cobra.Command{ } // TODO: Determine if this is actually needed. if state.Distro == "" { - return errors.New("Zarf state secret did not load properly") + return errors.New("zarf state secret did not load properly") } if len(args) > 0 { @@ -97,7 +96,7 @@ var updateCredsCmd = &cobra.Command{ } else { if !slices.Contains(validKeys, args[0]) { cmd.Help() - return fmt.Errorf("invalid service key specified, valid keys are: %s, %s, and %s", message.RegistryKey, message.GitKey, message.ArtifactKey) + return fmt.Errorf("invalid service key specified, valid key choices are: %v", validKeys) } } @@ -116,7 +115,7 @@ var updateCredsCmd = &cobra.Command{ } // TODO: Determine if this is actually needed. if oldState.Distro == "" { - return errors.New("Zarf state secret did not load properly") + return errors.New("zarf state secret did not load properly") } newState, err := cluster.MergeZarfState(oldState, updateCredsInitOpts, args) if err != nil { @@ -152,34 +151,18 @@ var updateCredsCmd = &cobra.Command{ 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() { - tunnel, err := c.NewTunnel(cluster.ZarfNamespaceName, cluster.SvcResource, cluster.ZarfGitServerName, "", 0, cluster.ZarfGitServerPort) + 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 err - } - _, err = tunnel.Connect(cmd.Context()) - if err != nil { - return err - } - defer tunnel.Close() - tunnelURL := tunnel.HTTPEndpoint() - giteaClient, err := gitea.NewClient(tunnelURL, oldState.GitServer.PushUsername, oldState.GitServer.PushPassword) - if err != nil { - return err - } - err = tunnel.Wrap(func() error { - tokenSha1, err := giteaClient.CreatePackageRegistryToken(ctx) - if err != nil { - return err - } - newState.ArtifactServer.PushToken = tokenSha1 - return nil - }) - if err != nil { - // Warn if we couldn't actually update the git server (it might not be installed and we should try to continue) - message.Warnf(lang.CmdToolsUpdateCredsUnableCreateToken, err.Error()) + return fmt.Errorf("unable to create the new Gitea artifact token: %w", err) } } @@ -199,35 +182,10 @@ var updateCredsCmd = &cobra.Command{ message.Warnf(lang.CmdToolsUpdateCredsUnableUpdateRegistry, err.Error()) } } - if slices.Contains(args, message.GitKey) && newState.GitServer.IsInternal() { - tunnel, err := c.NewTunnel(cluster.ZarfNamespaceName, cluster.SvcResource, cluster.ZarfGitServerName, "", 0, cluster.ZarfGitServerPort) - if err != nil { - return err - } - _, err = tunnel.Connect(cmd.Context()) - if err != nil { - return err - } - defer tunnel.Close() - tunnelURL := tunnel.HTTPEndpoint() - giteaClient, err := gitea.NewClient(tunnelURL, oldState.GitServer.PushUsername, oldState.GitServer.PushPassword) - if err != nil { - return err - } - err = tunnel.Wrap(func() error { - err := giteaClient.UpdateGitUser(ctx, newState.GitServer.PullUsername, newState.GitServer.PullPassword) - if err != nil { - return err - } - err = giteaClient.UpdateGitUser(ctx, newState.GitServer.PushUsername, newState.GitServer.PushPassword) - if err != nil { - return err - } - return nil - }) + if slices.Contains(args, message.GitKey) && newState.GitServer.IsInternal() && internalGitServerExists { + err := c.UpdateInternalGitServerSecret(cmd.Context(), oldState.GitServer, newState.GitServer) if err != nil { - // Warn if we couldn't actually update the git server (it might not be installed and we should try to continue) - message.Warnf(lang.CmdToolsUpdateCredsUnableUpdateGit, err.Error()) + return fmt.Errorf("unable to update Zarf Git Server values: %w", err) } } if slices.Contains(args, message.AgentKey) { diff --git a/src/config/lang/english.go b/src/config/lang/english.go index 1bca5f773a..50ce790c44 100644 --- a/src/config/lang/english.go +++ b/src/config/lang/english.go @@ -576,9 +576,7 @@ $ zarf tools update-creds artifact --artifact-push-username={USERNAME} --artifac CmdToolsUpdateCredsConfirmFlag = "Confirm updating credentials without prompting" CmdToolsUpdateCredsConfirmProvided = "Confirm flag specified, continuing without prompting." CmdToolsUpdateCredsConfirmContinue = "Continue with these changes?" - CmdToolsUpdateCredsUnableCreateToken = "Unable to create the new Gitea artifact token: %s" CmdToolsUpdateCredsUnableUpdateRegistry = "Unable to update Zarf Registry values: %s" - CmdToolsUpdateCredsUnableUpdateGit = "Unable to update Zarf Git Server values: %s" CmdToolsUpdateCredsUnableUpdateAgent = "Unable to update Zarf Agent TLS secrets: %s" CmdToolsUpdateCredsUnableUpdateCreds = "Unable to update Zarf credentials" diff --git a/src/pkg/cluster/zarf.go b/src/pkg/cluster/zarf.go index 7145349fea..14c3e2f31a 100644 --- a/src/pkg/cluster/zarf.go +++ b/src/pkg/cluster/zarf.go @@ -20,6 +20,7 @@ import ( "github.com/avast/retry-go/v4" "github.com/zarf-dev/zarf/src/api/v1alpha1" "github.com/zarf-dev/zarf/src/config" + "github.com/zarf-dev/zarf/src/internal/gitea" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/types" ) @@ -288,3 +289,72 @@ func (c *Cluster) GetInstalledChartsForComponent(ctx context.Context, packageNam return installedCharts, nil } + +// UpdateInternalArtifactServerToken updates the the artifact server token on the internal gitea server and returns it +func (c *Cluster) UpdateInternalArtifactServerToken(ctx context.Context, oldGitServer types.GitServerInfo) (string, error) { + tunnel, err := c.NewTunnel(ZarfNamespaceName, SvcResource, ZarfGitServerName, "", 0, ZarfGitServerPort) + if err != nil { + return "", err + } + _, err = tunnel.Connect(ctx) + if err != nil { + return "", err + } + defer tunnel.Close() + tunnelURL := tunnel.HTTPEndpoint() + giteaClient, err := gitea.NewClient(tunnelURL, oldGitServer.PushUsername, oldGitServer.PushPassword) + if err != nil { + return "", err + } + var newToken string + err = tunnel.Wrap(func() error { + newToken, err = giteaClient.CreatePackageRegistryToken(ctx) + if err != nil { + return err + } + return nil + }) + return newToken, err +} + +// UpdateInternalGitServerSecret updates the internal gitea server secrets with the new git server info +func (c *Cluster) UpdateInternalGitServerSecret(ctx context.Context, oldGitServer types.GitServerInfo, newGitServer types.GitServerInfo) error { + tunnel, err := c.NewTunnel(ZarfNamespaceName, SvcResource, ZarfGitServerName, "", 0, ZarfGitServerPort) + if err != nil { + return err + } + _, err = tunnel.Connect(ctx) + if err != nil { + return err + } + defer tunnel.Close() + tunnelURL := tunnel.HTTPEndpoint() + giteaClient, err := gitea.NewClient(tunnelURL, oldGitServer.PushUsername, oldGitServer.PushPassword) + if err != nil { + return err + } + err = tunnel.Wrap(func() error { + err := giteaClient.UpdateGitUser(ctx, newGitServer.PullUsername, newGitServer.PullPassword) + if err != nil { + return err + } + err = giteaClient.UpdateGitUser(ctx, newGitServer.PushUsername, newGitServer.PushPassword) + if err != nil { + return err + } + return nil + }) + if err != nil { + return err + } + return nil +} + +// InternalGitServerExists checks if the Zarf internal git server exists in the cluster. +func (c *Cluster) InternalGitServerExists(ctx context.Context) (bool, error) { + _, err := c.Clientset.CoreV1().Services(ZarfNamespaceName).Get(ctx, ZarfGitServerName, metav1.GetOptions{}) + if err != nil && !kerrors.IsNotFound(err) { + return false, err + } + return !kerrors.IsNotFound(err), nil +} diff --git a/src/pkg/cluster/zarf_test.go b/src/pkg/cluster/zarf_test.go index fe8b91d188..d2f3aefcde 100644 --- a/src/pkg/cluster/zarf_test.go +++ b/src/pkg/cluster/zarf_test.go @@ -285,3 +285,41 @@ func TestRegistryHPA(t *testing.T) { require.NoError(t, err) require.Equal(t, autoscalingv2.DisabledPolicySelect, *disableHpa.Spec.Behavior.ScaleDown.SelectPolicy) } + +func TestInternalGitServerExists(t *testing.T) { + tests := []struct { + name string + svc *corev1.Service + expectedExist bool + expectedErr error + }{ + { + name: "Git server exists", + svc: &corev1.Service{ObjectMeta: metav1.ObjectMeta{Name: ZarfGitServerName, Namespace: ZarfNamespaceName}}, + expectedExist: true, + expectedErr: nil, + }, + { + name: "Git server does not exist", + svc: nil, + expectedExist: false, + expectedErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cs := fake.NewSimpleClientset() + cluster := &Cluster{Clientset: cs} + ctx := context.Background() + if tt.svc != nil { + _, err := cs.CoreV1().Services(tt.svc.Namespace).Create(ctx, tt.svc, metav1.CreateOptions{}) + require.NoError(t, err) + } + + exists, err := cluster.InternalGitServerExists(ctx) + require.Equal(t, tt.expectedExist, exists) + require.Equal(t, tt.expectedErr, err) + }) + } +} diff --git a/src/test/e2e/21_connect_creds_test.go b/src/test/e2e/21_connect_creds_test.go index e794de3f3e..c58244a736 100644 --- a/src/test/e2e/21_connect_creds_test.go +++ b/src/test/e2e/21_connect_creds_test.go @@ -23,11 +23,16 @@ type RegistryResponse struct { func TestConnectAndCreds(t *testing.T) { t.Log("E2E: Connect") + ctx := context.Background() prevAgentSecretData, _, err := e2e.Kubectl(t, "get", "secret", "agent-hook-tls", "-n", "zarf", "-o", "jsonpath={.data}") require.NoError(t, err) - ctx := context.Background() + c, err := cluster.NewCluster() + require.NoError(t, err) + // Init the state variable + oldState, err := c.LoadZarfState(ctx) + require.NoError(t, err) connectToZarfServices(ctx, t) @@ -36,7 +41,11 @@ func TestConnectAndCreds(t *testing.T) { newAgentSecretData, _, err := e2e.Kubectl(t, "get", "secret", "agent-hook-tls", "-n", "zarf", "-o", "jsonpath={.data}") require.NoError(t, err) - require.NotEqual(t, prevAgentSecretData, newAgentSecretData, "agent secrets should not be the same") + newState, err := c.LoadZarfState(ctx) + require.NoError(t, err) + require.NotEqual(t, prevAgentSecretData, newAgentSecretData) + require.NotEqual(t, oldState.ArtifactServer.PushToken, newState.ArtifactServer.PushToken) + require.NotEqual(t, oldState.GitServer.PushPassword, newState.GitServer.PushPassword) connectToZarfServices(ctx, t) } From e90d5c8c4a4a4e20df64c0d972983fec28e19ba9 Mon Sep 17 00:00:00 2001 From: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Date: Thu, 22 Aug 2024 13:28:39 -0400 Subject: [PATCH 07/22] feat: better error message on helm fail (#2914) Signed-off-by: Austin Abro --- src/cmd/root.go | 3 ++- src/internal/packager/helm/chart.go | 12 ++++++------ src/test/e2e/09_component_compose_test.go | 2 +- src/test/e2e/20_zarf_init_test.go | 2 +- src/test/e2e/31_checksum_and_signature_test.go | 2 +- src/test/e2e/34_custom_init_package_test.go | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/cmd/root.go b/src/cmd/root.go index 876efdf20e..62e0582c8e 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -96,7 +96,8 @@ func Execute(ctx context.Context) { if len(comps) > 1 && comps[1] == "tools" && slices.Contains(defaultPrintCmds, comps[2]) { cmd.PrintErrln(cmd.ErrPrefix(), err.Error()) } else { - pterm.Error.Println(err.Error()) + errParagraph := message.Paragraph(err.Error()) + pterm.Error.Println(errParagraph) } os.Exit(1) } diff --git a/src/internal/packager/helm/chart.go b/src/internal/packager/helm/chart.go index 134bb4c493..daf59902e5 100644 --- a/src/internal/packager/helm/chart.go +++ b/src/internal/packager/helm/chart.go @@ -91,6 +91,9 @@ func (h *Helm) InstallOrUpgradeChart(ctx context.Context) (types.ConnectStrings, return nil }, retry.Context(ctx), retry.Attempts(uint(h.retries)), retry.Delay(500*time.Millisecond)) if err != nil { + removeMsg := "if you need to remove the failed chart, use `zarf package remove`" + installErr := fmt.Errorf("unable to install chart after %d attempts: %w: %s", h.retries, err, removeMsg) + releases, _ := histClient.Run(h.chart.ReleaseName) previouslyDeployedVersion := 0 @@ -101,21 +104,18 @@ func (h *Helm) InstallOrUpgradeChart(ctx context.Context) (types.ConnectStrings, } } - removeMsg := "if you need to remove the failed chart, use `zarf package remove`" - // No prior releases means this was an initial install. if previouslyDeployedVersion == 0 { - return nil, "", fmt.Errorf("unable to install chart after %d attempts: %s", h.retries, removeMsg) + return nil, "", installErr } // Attempt to rollback on a failed upgrade. spinner.Updatef("Performing chart rollback") err = h.rollbackChart(h.chart.ReleaseName, previouslyDeployedVersion) if err != nil { - return nil, "", fmt.Errorf("unable to upgrade chart after %d attempts and unable to rollback: %s", h.retries, removeMsg) + return nil, "", fmt.Errorf("%w: unable to rollback: %w", installErr, err) } - - return nil, "", fmt.Errorf("unable to upgrade chart after %d attempts: %s", h.retries, removeMsg) + return nil, "", installErr } // return any collected connect strings for zarf connect. diff --git a/src/test/e2e/09_component_compose_test.go b/src/test/e2e/09_component_compose_test.go index 37a905456a..e5809df6eb 100644 --- a/src/test/e2e/09_component_compose_test.go +++ b/src/test/e2e/09_component_compose_test.go @@ -185,7 +185,7 @@ func (suite *CompositionSuite) Test_2_ComposabilityBadLocalOS() { _, stdErr, err := e2e.Zarf(suite.T(), "package", "create", composeTestBadLocalOS, "-o", "build", "--no-color", "--confirm") suite.Error(err) - suite.Contains(stdErr, "\"only.localOS\" \"linux\" cannot be redefined as \"windows\" during compose") + suite.Contains(e2e.StripMessageFormatting(stdErr), "\"only.localOS\" \"linux\" cannot be redefined as \"windows\" during compose") } func TestCompositionSuite(t *testing.T) { diff --git a/src/test/e2e/20_zarf_init_test.go b/src/test/e2e/20_zarf_init_test.go index 6f788ef3b1..c94bfa4226 100644 --- a/src/test/e2e/20_zarf_init_test.go +++ b/src/test/e2e/20_zarf_init_test.go @@ -44,7 +44,7 @@ func TestZarfInit(t *testing.T) { // We need to use the --architecture flag here to force zarf to find the package. _, stdErr, err = e2e.Zarf(t, "init", "--architecture", mismatchedArch, "--components=k3s", "--confirm") require.Error(t, err, stdErr) - require.Contains(t, stdErr, expectedErrorMessage) + require.Contains(t, e2e.StripMessageFormatting(stdErr), expectedErrorMessage) } if !e2e.ApplianceMode { diff --git a/src/test/e2e/31_checksum_and_signature_test.go b/src/test/e2e/31_checksum_and_signature_test.go index e8aed4c1cb..b80e83e699 100644 --- a/src/test/e2e/31_checksum_and_signature_test.go +++ b/src/test/e2e/31_checksum_and_signature_test.go @@ -37,7 +37,7 @@ func TestChecksumAndSignature(t *testing.T) { // Test that we get an error when trying to deploy a package without providing the public key stdOut, stdErr, err = e2e.Zarf(t, "package", "deploy", pkgName, "--confirm") require.Error(t, err, stdOut, stdErr) - require.Contains(t, stdErr, "failed to deploy package: unable to load the package: package is signed but no key was provided - add a key with the --key flag or use the --insecure flag and run the command again") + require.Contains(t, e2e.StripMessageFormatting(stdErr), "failed to deploy package: unable to load the package: package is signed but no key was provided - add a key with the --key flag or use the --insecure flag and run the command again") // Test that we don't get an error when we remember to provide the public key stdOut, stdErr, err = e2e.Zarf(t, "package", "deploy", pkgName, publicKeyFlag, "--confirm") diff --git a/src/test/e2e/34_custom_init_package_test.go b/src/test/e2e/34_custom_init_package_test.go index c61cf91e2d..e4d3307fc4 100644 --- a/src/test/e2e/34_custom_init_package_test.go +++ b/src/test/e2e/34_custom_init_package_test.go @@ -38,7 +38,7 @@ func TestCustomInit(t *testing.T) { // Test that we get an error when trying to deploy a package without providing the public key stdOut, stdErr, err = e2e.Zarf(t, "init", "--confirm") require.Error(t, err, stdOut, stdErr) - require.Contains(t, stdErr, "unable to load the package: package is signed but no key was provided - add a key with the --key flag or use the --insecure flag and run the command again") + require.Contains(t, e2e.StripMessageFormatting(stdErr), "unable to load the package: package is signed but no key was provided - add a key with the --key flag or use the --insecure flag and run the command again") /* Test operations during package deploy */ // Test that we can deploy the package with the public key From 46ddb3ba85e7fb1a00319559dc17a5b7a4192af1 Mon Sep 17 00:00:00 2001 From: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Date: Thu, 22 Aug 2024 14:04:11 -0400 Subject: [PATCH 08/22] ci: increase lint timeout (#2919) Signed-off-by: Austin Abro --- .golangci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.golangci.yaml b/.golangci.yaml index 6f46337df5..6423df7732 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,5 +1,5 @@ run: - timeout: 5m + timeout: 10m linters: disable-all: true enable: From 15fa1198bb14a3749d57092b09fe56e3855fe223 Mon Sep 17 00:00:00 2001 From: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Date: Thu, 22 Aug 2024 14:44:21 -0400 Subject: [PATCH 09/22] fix: evaulate templates on schema check (#2911) Signed-off-by: Austin Abro --- .pre-commit-config.yaml | 12 ----------- src/pkg/lint/lint.go | 14 ++++++------- src/pkg/lint/lint_test.go | 12 +++++------ src/pkg/lint/schema.go | 7 ++++++- src/pkg/lint/schema_test.go | 20 +++++++++++++++++++ .../testdata/package-with-templates/zarf.yaml | 5 +++++ src/pkg/packager/creator/normal.go | 2 +- src/pkg/packager/creator/skeleton.go | 2 +- src/pkg/packager/creator/utils.go | 4 ++-- src/pkg/packager/dev.go | 2 +- 10 files changed, 48 insertions(+), 32 deletions(-) create mode 100644 src/pkg/lint/testdata/package-with-templates/zarf.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ad9ea6d447..22ea750052 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -40,15 +40,3 @@ repos: types: [go] language: golang pass_filenames: false - - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.14.0 - hooks: - - id: check-jsonschema - name: "Validate Zarf Configs Against Schema" - files: "zarf.yaml" - types: [yaml] - args: ["--schemafile", "zarf.schema.json"] - exclude: | - (?x)^( - src/test/packages/12-lint/.* - )$ diff --git a/src/pkg/lint/lint.go b/src/pkg/lint/lint.go index 9c0132f2e8..3c4be87eaf 100644 --- a/src/pkg/lint/lint.go +++ b/src/pkg/lint/lint.go @@ -36,7 +36,7 @@ func Validate(ctx context.Context, createOpts types.ZarfCreateOptions) error { return err } findings = append(findings, compFindings...) - schemaFindings, err := ValidatePackageSchema() + schemaFindings, err := ValidatePackageSchema(createOpts.SetVariables) if err != nil { return err } @@ -71,7 +71,7 @@ func lintComponents(ctx context.Context, pkg v1alpha1.ZarfPackage, createOpts ty node := chain.Head() for node != nil { component := node.ZarfComponent - compFindings, err := fillComponentTemplate(&component, createOpts) + compFindings, err := templateZarfObj(&component, createOpts.SetVariables) if err != nil { return nil, err } @@ -87,12 +87,12 @@ func lintComponents(ctx context.Context, pkg v1alpha1.ZarfPackage, createOpts ty return findings, nil } -func fillComponentTemplate(c *v1alpha1.ZarfComponent, createOpts types.ZarfCreateOptions) ([]PackageFinding, error) { +func templateZarfObj(zarfObj any, setVariables map[string]string) ([]PackageFinding, error) { var findings []PackageFinding templateMap := map[string]string{} setVarsAndWarn := func(templatePrefix string, deprecated bool) error { - yamlTemplates, err := utils.FindYamlTemplates(c, templatePrefix, "###") + yamlTemplates, err := utils.FindYamlTemplates(zarfObj, templatePrefix, "###") if err != nil { return err } @@ -105,7 +105,7 @@ func fillComponentTemplate(c *v1alpha1.ZarfComponent, createOpts types.ZarfCreat Severity: SevWarn, }) } - if _, present := createOpts.SetVariables[key]; !present { + if _, present := setVariables[key]; !present { unSetTemplates = true } } @@ -115,7 +115,7 @@ func fillComponentTemplate(c *v1alpha1.ZarfComponent, createOpts types.ZarfCreat Severity: SevWarn, }) } - for key, value := range createOpts.SetVariables { + for key, value := range setVariables { templateMap[fmt.Sprintf("%s%s###", templatePrefix, key)] = value } return nil @@ -130,7 +130,7 @@ func fillComponentTemplate(c *v1alpha1.ZarfComponent, createOpts types.ZarfCreat return nil, err } - if err := utils.ReloadYamlTemplate(c, templateMap); err != nil { + if err := utils.ReloadYamlTemplate(zarfObj, templateMap); err != nil { return nil, err } return findings, nil diff --git a/src/pkg/lint/lint_test.go b/src/pkg/lint/lint_test.go index d6ad24ad82..d499ba6e45 100644 --- a/src/pkg/lint/lint_test.go +++ b/src/pkg/lint/lint_test.go @@ -32,12 +32,10 @@ func TestLintComponents(t *testing.T) { require.Error(t, err) }) } -func TestFillComponentTemplate(t *testing.T) { - createOpts := types.ZarfCreateOptions{ - SetVariables: map[string]string{ - "KEY1": "value1", - "KEY2": "value2", - }, +func TestFillObjTemplate(t *testing.T) { + SetVariables := map[string]string{ + "KEY1": "value1", + "KEY2": "value2", } component := v1alpha1.ZarfComponent{ @@ -48,7 +46,7 @@ func TestFillComponentTemplate(t *testing.T) { }, } - findings, err := fillComponentTemplate(&component, createOpts) + findings, err := templateZarfObj(&component, SetVariables) require.NoError(t, err) expectedFindings := []PackageFinding{ { diff --git a/src/pkg/lint/schema.go b/src/pkg/lint/schema.go index ae3e991863..adf41e935b 100644 --- a/src/pkg/lint/schema.go +++ b/src/pkg/lint/schema.go @@ -18,7 +18,7 @@ import ( var ZarfSchema fs.ReadFileFS // ValidatePackageSchema checks the Zarf package in the current directory against the Zarf schema -func ValidatePackageSchema() ([]PackageFinding, error) { +func ValidatePackageSchema(setVariables map[string]string) ([]PackageFinding, error) { var untypedZarfPackage interface{} if err := utils.ReadYaml(layout.ZarfYAML, &untypedZarfPackage); err != nil { return nil, err @@ -29,6 +29,11 @@ func ValidatePackageSchema() ([]PackageFinding, error) { return nil, err } + _, err = templateZarfObj(&untypedZarfPackage, setVariables) + if err != nil { + return nil, err + } + return getSchemaFindings(jsonSchema, untypedZarfPackage) } diff --git a/src/pkg/lint/schema_test.go b/src/pkg/lint/schema_test.go index bd8b576a83..8ebcdc26bf 100644 --- a/src/pkg/lint/schema_test.go +++ b/src/pkg/lint/schema_test.go @@ -7,11 +7,13 @@ package lint import ( "fmt" "os" + "path/filepath" "testing" goyaml "github.com/goccy/go-yaml" "github.com/stretchr/testify/require" "github.com/zarf-dev/zarf/src/api/v1alpha1" + "github.com/zarf-dev/zarf/src/test/testutil" ) func TestZarfSchema(t *testing.T) { @@ -190,6 +192,24 @@ components: }) } +func TestValidatePackageSchema(t *testing.T) { + ZarfSchema = testutil.LoadSchema(t, "../../../zarf.schema.json") + setVariables := map[string]string{ + "PACKAGE_NAME": "test-package", + "MY_COMP_NAME": "test-comp", + } + cwd, err := os.Getwd() + require.NoError(t, err) + err = os.Chdir(filepath.Join("testdata", "package-with-templates")) + require.NoError(t, err) + defer func() { + require.NoError(t, os.Chdir(cwd)) + }() + findings, err := ValidatePackageSchema(setVariables) + require.Empty(t, findings) + require.NoError(t, err) +} + func TestYqCompat(t *testing.T) { t.Parallel() t.Run("Wrap standalone numbers in bracket", func(t *testing.T) { diff --git a/src/pkg/lint/testdata/package-with-templates/zarf.yaml b/src/pkg/lint/testdata/package-with-templates/zarf.yaml new file mode 100644 index 0000000000..f32ec32bab --- /dev/null +++ b/src/pkg/lint/testdata/package-with-templates/zarf.yaml @@ -0,0 +1,5 @@ +kind: ZarfPackageConfig +metadata: + name: "###ZARF_PKG_VAR_PACKAGE_NAME###" +components: + - name: "###ZARF_PKG_TMPL_MY_COMP_NAME###" diff --git a/src/pkg/packager/creator/normal.go b/src/pkg/packager/creator/normal.go index 79c58250c0..847a22003e 100644 --- a/src/pkg/packager/creator/normal.go +++ b/src/pkg/packager/creator/normal.go @@ -119,7 +119,7 @@ func (pc *PackageCreator) LoadPackageDefinition(ctx context.Context, src *layout } } - if err := Validate(pkg, pc.createOpts.BaseDir); err != nil { + if err := Validate(pkg, pc.createOpts.BaseDir, pc.createOpts.SetVariables); err != nil { return v1alpha1.ZarfPackage{}, nil, err } diff --git a/src/pkg/packager/creator/skeleton.go b/src/pkg/packager/creator/skeleton.go index 218830b75f..648fb562b3 100644 --- a/src/pkg/packager/creator/skeleton.go +++ b/src/pkg/packager/creator/skeleton.go @@ -71,7 +71,7 @@ func (sc *SkeletonCreator) LoadPackageDefinition(ctx context.Context, src *layou message.Warn(warning) } - if err := Validate(pkg, sc.createOpts.BaseDir); err != nil { + if err := Validate(pkg, sc.createOpts.BaseDir, sc.createOpts.SetVariables); err != nil { return v1alpha1.ZarfPackage{}, nil, err } diff --git a/src/pkg/packager/creator/utils.go b/src/pkg/packager/creator/utils.go index b138ce7af2..1bb88750e0 100644 --- a/src/pkg/packager/creator/utils.go +++ b/src/pkg/packager/creator/utils.go @@ -19,12 +19,12 @@ import ( // Validate errors if a package violates the schema or any runtime validations // This must be run while in the parent directory of the zarf.yaml being validated -func Validate(pkg v1alpha1.ZarfPackage, baseDir string) error { +func Validate(pkg v1alpha1.ZarfPackage, baseDir string, setVariables map[string]string) error { if err := lint.ValidatePackage(pkg); err != nil { return fmt.Errorf("package validation failed: %w", err) } - findings, err := lint.ValidatePackageSchema() + findings, err := lint.ValidatePackageSchema(setVariables) if err != nil { return fmt.Errorf("unable to check schema: %w", err) } diff --git a/src/pkg/packager/dev.go b/src/pkg/packager/dev.go index 1c1208be14..49232ddc1b 100644 --- a/src/pkg/packager/dev.go +++ b/src/pkg/packager/dev.go @@ -53,7 +53,7 @@ func (p *Packager) DevDeploy(ctx context.Context) error { return err } - if err := creator.Validate(p.cfg.Pkg, p.cfg.CreateOpts.BaseDir); err != nil { + if err := creator.Validate(p.cfg.Pkg, p.cfg.CreateOpts.BaseDir, p.cfg.CreateOpts.SetVariables); err != nil { return fmt.Errorf("package validation failed: %w", err) } From 186c5d05d61fb057516d9b182602e32aa7bccff8 Mon Sep 17 00:00:00 2001 From: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Date: Thu, 22 Aug 2024 15:54:47 -0400 Subject: [PATCH 10/22] chore: update workflow to use new key (#2920) Signed-off-by: Austin Abro --- .../publish-application-packages.yml | 13 +++++++--- .github/workflows/release.yml | 12 ++++++--- cosign.pub | 26 +++++++++---------- src/pkg/utils/cosign.go | 8 ------ src/test/e2e/11_oci_pull_inspect_test.go | 2 +- src/test/e2e/27_deploy_regression_test.go | 16 +----------- 6 files changed, 33 insertions(+), 44 deletions(-) diff --git a/.github/workflows/publish-application-packages.yml b/.github/workflows/publish-application-packages.yml index 3944aa0abb..de96965506 100644 --- a/.github/workflows/publish-application-packages.yml +++ b/.github/workflows/publish-application-packages.yml @@ -1,6 +1,7 @@ name: Zarf Application Package Publishing permissions: + id-token: write contents: read on: @@ -22,6 +23,14 @@ jobs: with: ref: ${{ github.event.inputs.branchName }} + - name: Auth with AWS + uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + with: + role-to-assume: ${{ secrets.AWS_KMS_ROLE }} + role-session-name: ${{ github.job || github.event.client_payload.pull_request.head.sha || github.sha }} + aws-region: us-east-2 + role-duration-seconds: 3600 + - name: Install The Latest Release Version of Zarf uses: defenseunicorns/setup-zarf@10e539efed02f75ec39eb8823e22a5c795f492ae #v1.0.1 @@ -44,7 +53,3 @@ jobs: # Publish a skeleton of the dos-games package zarf package publish examples/dos-games oci://ghcr.io/zarf-dev/packages - env: - AWS_REGION: ${{ secrets.COSIGN_AWS_REGION }} - AWS_ACCESS_KEY_ID: ${{ secrets.COSIGN_AWS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.COSIGN_AWS_ACCESS_KEY }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 52b3d38b31..f7af1a32de 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,6 +1,7 @@ name: Release CLI and Packages on Tag permissions: + id-token: write contents: read on: @@ -53,13 +54,18 @@ jobs: rm build/zarf-linux-arm64 echo ZARF_AGENT_IMAGE_DIGEST=$(docker buildx imagetools inspect ghcr.io/zarf-dev/zarf/agent:$GITHUB_REF_NAME --format '{{ json . }}' | jq -r .manifest.digest) >> $GITHUB_ENV + - name: Auth with AWS + uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + with: + role-to-assume: ${{ secrets.AWS_KMS_ROLE }} + role-session-name: ${{ github.job || github.event.client_payload.pull_request.head.sha || github.sha }} + aws-region: us-east-2 + role-duration-seconds: 3600 + - name: "Zarf Agent: Sign the Image" run: cosign sign --key awskms:///${{ secrets.COSIGN_AWS_KMS_KEY }} -a release-engineer=https://github.com/${{ github.actor }} -a version=$GITHUB_REF_NAME ghcr.io/zarf-dev/zarf/agent@$ZARF_AGENT_IMAGE_DIGEST -y env: COSIGN_EXPERIMENTAL: 1 - AWS_REGION: ${{ secrets.COSIGN_AWS_REGION }} - AWS_ACCESS_KEY_ID: ${{ secrets.COSIGN_AWS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.COSIGN_AWS_ACCESS_KEY }} # Builds init packages since GoReleaser won't handle this for us - name: Build init-packages For Release diff --git a/cosign.pub b/cosign.pub index 6c8e8e4eb5..a2677f32b0 100644 --- a/cosign.pub +++ b/cosign.pub @@ -1,14 +1,14 @@ -----BEGIN PUBLIC KEY----- -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9u472y/wY0tjIiR2T6rY -zOG1q4qwx5ZdmnoGsiG0Zc3rYo2DMiuKciG0MI4opCf4IID7kfYOD4aWILymwFID -xW0L6pEbxknHRQacWZSf/qfA+aAcjbKOY3ZWU8/uLJJeq37Y4OLc17ThJ7ZOj1Yf -Uvj81Uz9ZWVW7kYY31vWCruJh4VxZLsUAmFc6CsQUtzSGordLhh1b1rDP6ZRAaIP -mQnniULogwIBqnUTkIVwxiRYG+V2a3IC5vqlBLQRQ3UOWQ9mgZcfcXuTA6Fh8bwO -2lG768UfI1RBYioXAgXbPwXK+kM3Idvjcr+X2F3VpYWhHTscMIQF0ERzK7BkRqRI -x9l/RRm5lP+9a1kt6giYtvX2OqEsWaG3lTen3ocwblaHRlmqnaiVBtAnVny6QDHX -9p1HPMD/NjWjZucxWMjtdL5FZxBywbJVlxhe7sFByMoBZYhea9vGGSn2M2Q9kPiq -Bgl6bKZdeYIhaKQ7wrNkS6YVHMIqqpCIUI6/YGYwnu0hodbjR0yA2LFx4TgFZAuY -uGEiRP4Oi7WEOPkjRjP7kPXGpEBB7ulZ/Wohq1B6pB1Odo8WlfJRAek319F2aqqh -J1c3YdZ/w3EvCLKd+Inp1UNbamb79UN6jtwhqwKw72YbZh/yP0rim49lQ++umwPX -JWqG8iY/UzGB/3ch4/Wb09UCAwEAAQ== ------END PUBLIC KEY----- \ No newline at end of file +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAr6pqXju3qrkVae35GIuG +F58+zMd5XGMVgPkxFrdrJZ/3Ag65y7j4QsrcCFkXYAYNIy9iZliXypsxrr3oajJv +EgLDAc0CqtWYa0tuT2kAP4YHzxVkLC8MZLhQ1fuj9QKylm3OIMf18ZAnp12upmK8 +SBvrYxtWfTOv4KBgRGdIO0U9M/dwNnodGosY0znyHD9dp1G7qRA7BNpOsuXoaLa/ +aSQ2X0icoq5N8BLLOl3/23w6nCV+G32HFD0/AurDZVMC8o6N91AkX3smfWINkNk+ +QUrCkjhlAMxtBPi2TCYB4PimOKLpO/q/hwfixkHJcx8zPY/UZCCJGrsOcdFdvN/M +FkxqVZ2vBv+8LaElSAmbzsjVpg4w3QMk/6fVuU2rBtwog7DekuV/J5SwGCyTfC/4 +R8SetTsEpYgtDWp8+vugcfZTg5+7rPnMfNG16HdwJoC+LnWbeot6X2ZepTu4CrkV +qCAfFlu9G9sy2ZrwT5gnFT9JoKPVRTgkYmADgSfF0njKjuFKfk+aEVIrKRCVbExe +VtfmM1A9OfP4vCtCKw7tE5fFhmAa5v2D6LS/rG2m99fbZjDdeK9y22OZZyUCZaUN +TM+VQTuY1bwXY0/XEhUHxP0Fzk2VGQVslwXgW305SzR8Yh/bTbE4pkNGpOta+4s2 +E5ZMlZgQX8x4gSfbxmBHgP0CAwEAAQ== +-----END PUBLIC KEY----- diff --git a/src/pkg/utils/cosign.go b/src/pkg/utils/cosign.go index eb16d6159f..1e129ffb5c 100644 --- a/src/pkg/utils/cosign.go +++ b/src/pkg/utils/cosign.go @@ -8,7 +8,6 @@ import ( "context" "fmt" "io" - "os" "strings" "github.com/defenseunicorns/pkg/helpers/v2" @@ -16,7 +15,6 @@ import ( "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/pkg/errors" - "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/config/lang" "github.com/zarf-dev/zarf/src/pkg/message" @@ -41,12 +39,6 @@ import ( func Sget(ctx context.Context, image, key string, out io.Writer) error { message.Warnf(lang.WarnSGetDeprecation) - // If this is a DefenseUnicorns package, use an internal sget public key - if strings.HasPrefix(image, fmt.Sprintf("%s://defenseunicorns", helpers.SGETURLScheme)) { - os.Setenv("DU_SGET_KEY", config.CosignPublicKey) - key = "env://DU_SGET_KEY" - } - // Remove the custom protocol header from the url image = strings.TrimPrefix(image, helpers.SGETURLPrefix) diff --git a/src/test/e2e/11_oci_pull_inspect_test.go b/src/test/e2e/11_oci_pull_inspect_test.go index a992a50f55..cd045ae0a6 100644 --- a/src/test/e2e/11_oci_pull_inspect_test.go +++ b/src/test/e2e/11_oci_pull_inspect_test.go @@ -55,7 +55,7 @@ func (suite *PullInspectTestSuite) Test_0_Pull() { // Verify the package was pulled correctly. suite.FileExists(out) - stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "inspect", out, "--key", "https://zarf.dev/cosign.pub", "--sbom-out", sbomTmp) + stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "inspect", out, "--key", "https://raw.githubusercontent.com/zarf-dev/zarf/v0.38.2/cosign.pub", "--sbom-out", sbomTmp) suite.NoError(err, stdOut, stdErr) suite.Contains(stdErr, "Validating SBOM checksums") suite.Contains(stdErr, "Package signature validated!") diff --git a/src/test/e2e/27_deploy_regression_test.go b/src/test/e2e/27_deploy_regression_test.go index f16c3d243a..87663469f9 100644 --- a/src/test/e2e/27_deploy_regression_test.go +++ b/src/test/e2e/27_deploy_regression_test.go @@ -9,7 +9,6 @@ import ( "testing" "github.com/stretchr/testify/require" - "github.com/zarf-dev/zarf/src/pkg/utils/exec" ) func TestGHCRDeploy(t *testing.T) { @@ -25,20 +24,7 @@ func TestGHCRDeploy(t *testing.T) { } // Test with command from https://docs.zarf.dev/getting-started/install/ - stdOut, stdErr, err := e2e.Zarf(t, "package", "deploy", fmt.Sprintf("oci://🦄/dos-games:1.0.0-%s@sha256:%s", e2e.Arch, sha), "--key=https://zarf.dev/cosign.pub", "--confirm") - require.NoError(t, err, stdOut, stdErr) - - stdOut, stdErr, err = e2e.Zarf(t, "package", "remove", "dos-games", "--confirm") - require.NoError(t, err, stdOut, stdErr) -} - -func TestCosignDeploy(t *testing.T) { - t.Log("E2E: Cosign deploy") - - // Test with command from https://docs.zarf.dev/getting-started/install/ - command := fmt.Sprintf("%s package deploy sget://defenseunicorns/zarf-hello-world:$(uname -m) --confirm", e2e.ZarfBinPath) - - stdOut, stdErr, err := exec.CmdWithTesting(t, exec.PrintCfg(), "sh", "-c", command) + stdOut, stdErr, err := e2e.Zarf(t, "package", "deploy", fmt.Sprintf("oci://🦄/dos-games:1.0.0-%s@sha256:%s", e2e.Arch, sha), "--key=https://raw.githubusercontent.com/zarf-dev/zarf/v0.38.2/cosign.pub", "--confirm") require.NoError(t, err, stdOut, stdErr) stdOut, stdErr, err = e2e.Zarf(t, "package", "remove", "dos-games", "--confirm") From 4f0c94974752c6b62c343a6a074f9244fdc62057 Mon Sep 17 00:00:00 2001 From: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Date: Thu, 22 Aug 2024 16:55:03 -0400 Subject: [PATCH 11/22] ci: permission at job level (#2922) Signed-off-by: Austin Abro --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f7af1a32de..dd5943aeb6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,6 @@ name: Release CLI and Packages on Tag permissions: - id-token: write contents: read on: @@ -13,6 +12,7 @@ jobs: build-release: runs-on: ubuntu-latest permissions: + id-token: write packages: write steps: # Checkout the repo and setup the tooling for this job From db13db9ff7478a70d5fa3dd05e36ba2ca3eacc11 Mon Sep 17 00:00:00 2001 From: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:12:02 -0400 Subject: [PATCH 12/22] chore: update dos games release (#2921) Signed-off-by: Austin Abro --- .github/workflows/publish-application-packages.yml | 11 ++--------- examples/dos-games/zarf.yaml | 2 +- src/test/e2e/05_tarball_test.go | 2 +- src/test/e2e/06_create_sbom_test.go | 2 +- src/test/e2e/25_helm_test.go | 4 ++-- src/test/e2e/26_simple_packages_test.go | 2 +- src/test/e2e/31_checksum_and_signature_test.go | 2 +- src/test/e2e/32_component_webhooks_test.go | 2 +- 8 files changed, 10 insertions(+), 17 deletions(-) diff --git a/.github/workflows/publish-application-packages.yml b/.github/workflows/publish-application-packages.yml index de96965506..d8e1c34d05 100644 --- a/.github/workflows/publish-application-packages.yml +++ b/.github/workflows/publish-application-packages.yml @@ -6,11 +6,6 @@ permissions: on: workflow_dispatch: - inputs: - branchName: - description: "Branch to build the packages from" - required: true - default: "main" jobs: publish-packages: @@ -20,8 +15,6 @@ jobs: steps: - name: "Checkout Repo" uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - with: - ref: ${{ github.event.inputs.branchName }} - name: Auth with AWS uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 @@ -48,8 +41,8 @@ jobs: zarf package create -o build -a arm64 examples/dos-games --signing-key=awskms:///${{ secrets.COSIGN_AWS_KMS_KEY }} --confirm # Publish a the signed dos-games package - zarf package publish ./build/zarf-package-dos-games-amd64-1.0.0.tar.zst oci://ghcr.io/zarf-dev/packages --key=https://zarf.dev/cosign.pub - zarf package publish ./build/zarf-package-dos-games-arm64-1.0.0.tar.zst oci://ghcr.io/zarf-dev/packages --key=https://zarf.dev/cosign.pub + zarf package publish ./build/zarf-package-dos-games-amd64-1.1.0.tar.zst oci://ghcr.io/zarf-dev/packages --key=https://zarf.dev/cosign.pub + zarf package publish ./build/zarf-package-dos-games-arm64-1.1.0.tar.zst oci://ghcr.io/zarf-dev/packages --key=https://zarf.dev/cosign.pub # Publish a skeleton of the dos-games package zarf package publish examples/dos-games oci://ghcr.io/zarf-dev/packages diff --git a/examples/dos-games/zarf.yaml b/examples/dos-games/zarf.yaml index 49d49f5be8..87042ca58d 100644 --- a/examples/dos-games/zarf.yaml +++ b/examples/dos-games/zarf.yaml @@ -2,7 +2,7 @@ kind: ZarfPackageConfig metadata: name: dos-games description: Simple example to load classic DOS games into K8s in the airgap - version: 1.0.0 + version: 1.1.0 components: - name: baseline diff --git a/src/test/e2e/05_tarball_test.go b/src/test/e2e/05_tarball_test.go index a9af583002..d1646899cf 100644 --- a/src/test/e2e/05_tarball_test.go +++ b/src/test/e2e/05_tarball_test.go @@ -83,7 +83,7 @@ func TestReproducibleTarballs(t *testing.T) { var ( createPath = filepath.Join("examples", "dos-games") tmp = t.TempDir() - tb = filepath.Join(tmp, fmt.Sprintf("zarf-package-dos-games-%s-1.0.0.tar.zst", e2e.Arch)) + tb = filepath.Join(tmp, fmt.Sprintf("zarf-package-dos-games-%s-1.1.0.tar.zst", e2e.Arch)) unpack1 = filepath.Join(tmp, "unpack1") unpack2 = filepath.Join(tmp, "unpack2") ) diff --git a/src/test/e2e/06_create_sbom_test.go b/src/test/e2e/06_create_sbom_test.go index 26890ccaf9..a3ee3b4118 100644 --- a/src/test/e2e/06_create_sbom_test.go +++ b/src/test/e2e/06_create_sbom_test.go @@ -18,7 +18,7 @@ func TestCreateSBOM(t *testing.T) { tmpdir := t.TempDir() sbomPath := filepath.Join(tmpdir, ".sbom-location") - pkgName := fmt.Sprintf("zarf-package-dos-games-%s-1.0.0.tar.zst", e2e.Arch) + pkgName := fmt.Sprintf("zarf-package-dos-games-%s-1.1.0.tar.zst", e2e.Arch) stdOut, stdErr, err := e2e.Zarf(t, "package", "create", "examples/dos-games", "--sbom-out", sbomPath, "--confirm") require.NoError(t, err, stdOut, stdErr) diff --git a/src/test/e2e/25_helm_test.go b/src/test/e2e/25_helm_test.go index 322d3c89dd..b37c3ad39a 100644 --- a/src/test/e2e/25_helm_test.go +++ b/src/test/e2e/25_helm_test.go @@ -115,7 +115,7 @@ func testHelmEscaping(t *testing.T) { func testHelmUninstallRollback(t *testing.T) { t.Log("E2E: Helm Uninstall and Rollback") - goodPath := fmt.Sprintf("build/zarf-package-dos-games-%s-1.0.0.tar.zst", e2e.Arch) + goodPath := fmt.Sprintf("build/zarf-package-dos-games-%s-1.1.0.tar.zst", e2e.Arch) evilPath := fmt.Sprintf("zarf-package-dos-games-%s.tar.zst", e2e.Arch) // Create the evil package (with the bad service). @@ -172,7 +172,7 @@ func testHelmUninstallRollback(t *testing.T) { func testHelmAdoption(t *testing.T) { t.Log("E2E: Helm Adopt a Deployment") - packagePath := fmt.Sprintf("build/zarf-package-dos-games-%s-1.0.0.tar.zst", e2e.Arch) + packagePath := fmt.Sprintf("build/zarf-package-dos-games-%s-1.1.0.tar.zst", e2e.Arch) deploymentManifest := "src/test/packages/25-manifest-adoption/deployment.yaml" // Deploy dos-games manually into the cluster without Zarf diff --git a/src/test/e2e/26_simple_packages_test.go b/src/test/e2e/26_simple_packages_test.go index 6e4c20bd8a..08df1d709b 100644 --- a/src/test/e2e/26_simple_packages_test.go +++ b/src/test/e2e/26_simple_packages_test.go @@ -18,7 +18,7 @@ import ( func TestDosGames(t *testing.T) { t.Log("E2E: Dos games") - path := filepath.Join("build", fmt.Sprintf("zarf-package-dos-games-%s-1.0.0.tar.zst", e2e.Arch)) + path := filepath.Join("build", fmt.Sprintf("zarf-package-dos-games-%s-1.1.0.tar.zst", e2e.Arch)) // Deploy the game stdOut, stdErr, err := e2e.Zarf(t, "package", "deploy", path, "--confirm") diff --git a/src/test/e2e/31_checksum_and_signature_test.go b/src/test/e2e/31_checksum_and_signature_test.go index b80e83e699..c83888fe00 100644 --- a/src/test/e2e/31_checksum_and_signature_test.go +++ b/src/test/e2e/31_checksum_and_signature_test.go @@ -15,7 +15,7 @@ func TestChecksumAndSignature(t *testing.T) { t.Log("E2E: Checksum and Signature") testPackageDirPath := "examples/dos-games" - pkgName := fmt.Sprintf("zarf-package-dos-games-%s-1.0.0.tar.zst", e2e.Arch) + pkgName := fmt.Sprintf("zarf-package-dos-games-%s-1.1.0.tar.zst", e2e.Arch) privateKeyFlag := "--signing-key=src/test/packages/zarf-test.prv-key" publicKeyFlag := "--key=src/test/packages/zarf-test.pub" diff --git a/src/test/e2e/32_component_webhooks_test.go b/src/test/e2e/32_component_webhooks_test.go index 7d6d761835..18c9ed33cc 100644 --- a/src/test/e2e/32_component_webhooks_test.go +++ b/src/test/e2e/32_component_webhooks_test.go @@ -23,7 +23,7 @@ func TestComponentWebhooks(t *testing.T) { defer e2e.CleanFiles(webhookPath) // Ensure package deployments wait for webhooks to complete. - gamesPath := fmt.Sprintf("build/zarf-package-dos-games-%s-1.0.0.tar.zst", e2e.Arch) + gamesPath := fmt.Sprintf("build/zarf-package-dos-games-%s-1.1.0.tar.zst", e2e.Arch) stdOut, stdErr, err = e2e.Zarf(t, "package", "deploy", gamesPath, "--confirm") require.NoError(t, err, stdOut, stdErr) require.Contains(t, stdErr, "Waiting for webhook \"test-webhook\" to complete for component \"baseline\"") From 72e833488cfed3f1f374039fb2fd239d11c0ed31 Mon Sep 17 00:00:00 2001 From: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:33:50 -0400 Subject: [PATCH 13/22] ci: id-token write application packages (#2923) Signed-off-by: Austin Abro --- .github/workflows/publish-application-packages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-application-packages.yml b/.github/workflows/publish-application-packages.yml index d8e1c34d05..680fd2eee4 100644 --- a/.github/workflows/publish-application-packages.yml +++ b/.github/workflows/publish-application-packages.yml @@ -1,7 +1,6 @@ name: Zarf Application Package Publishing permissions: - id-token: write contents: read on: @@ -11,6 +10,7 @@ jobs: publish-packages: runs-on: ubuntu-latest permissions: + id-token: write packages: write steps: - name: "Checkout Repo" From 951b4e6893c0143f3ae5c813dfa726a7bc22ca69 Mon Sep 17 00:00:00 2001 From: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Date: Fri, 23 Aug 2024 09:01:10 -0400 Subject: [PATCH 14/22] docs: update dos games example (#2924) Signed-off-by: Austin Abro --- examples/composable-packages/zarf.yaml | 2 +- site/src/content/docs/getting-started/index.mdx | 4 ++-- src/test/e2e/09_component_compose_test.go | 2 +- src/test/e2e/12_lint_test.go | 4 ++-- src/test/e2e/27_deploy_regression_test.go | 6 +++--- src/test/packages/12-lint/linted-import/zarf.yaml | 2 +- src/test/packages/12-lint/zarf.yaml | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/composable-packages/zarf.yaml b/examples/composable-packages/zarf.yaml index 35dab0b33e..e1cca3388d 100644 --- a/examples/composable-packages/zarf.yaml +++ b/examples/composable-packages/zarf.yaml @@ -31,7 +31,7 @@ components: # default: false # the initial value overrides the child component import: # The URL to the skeleton package containing this component's package definition - url: oci://🦄/dos-games:1.0.0 + url: oci://ghcr.io/zarf-dev/packages/dos-games:1.1.0 # Example optional custom name to point to in the imported package (default is to use this component's name) name: baseline # Un'name'd Zarf primitives will be appended to the end of the primitive's list for that component. diff --git a/site/src/content/docs/getting-started/index.mdx b/site/src/content/docs/getting-started/index.mdx index 2e294ab9b3..c2f4ca042b 100644 --- a/site/src/content/docs/getting-started/index.mdx +++ b/site/src/content/docs/getting-started/index.mdx @@ -23,7 +23,7 @@ import { Tabs, TabItem, LinkCard, CardGrid } from '@astrojs/starlight/components # (Select optional components as desired) # Now you are ready to deploy any Zarf Package, try out our Retro Arcade!! - zarf package deploy oci://🦄/dos-games:1.0.0 --key=https://zarf.dev/cosign.pub + zarf package deploy oci://ghcr.io/zarf-dev/packages/dos-games:1.1.0 --key=https://zarf.dev/cosign.pub # (Select 'Y' to confirm deployment) ``` @@ -39,7 +39,7 @@ import { Tabs, TabItem, LinkCard, CardGrid } from '@astrojs/starlight/components zarf init --confirm # Deploy the DOS Games package - zarf package deploy oci://🦄/dos-games:1.0.0 \ + zarf package deploy oci://ghcr.io/zarf-dev/packages/dos-games:1.1.0 \ --key=https://zarf.dev/cosign.pub \ --confirm ``` diff --git a/src/test/e2e/09_component_compose_test.go b/src/test/e2e/09_component_compose_test.go index e5809df6eb..8c369feab9 100644 --- a/src/test/e2e/09_component_compose_test.go +++ b/src/test/e2e/09_component_compose_test.go @@ -61,7 +61,7 @@ func (suite *CompositionSuite) Test_0_ComposabilityExample() { // Ensure that the action was appended suite.Contains(stdErr, ` - - defenseunicorns/zarf-game:multi-tile-dark + - ghcr.io/zarf-dev/doom-game:0.0.1 actions: onDeploy: before: diff --git a/src/test/e2e/12_lint_test.go b/src/test/e2e/12_lint_test.go index 58e19536ce..dea06dd678 100644 --- a/src/test/e2e/12_lint_test.go +++ b/src/test/e2e/12_lint_test.go @@ -46,14 +46,14 @@ func TestLint(t *testing.T) { // Testing import / compose + variables are working require.Contains(t, strippedStderr, ".components.[2].images.[3] | Image not pinned with digest - busybox:latest") // Testing OCI imports get linted - require.Contains(t, strippedStderr, ".components.[0].images.[0] | Image not pinned with digest - defenseunicorns/zarf-game:multi-tile-dark") + require.Contains(t, strippedStderr, ".components.[0].images.[0] | Image not pinned with digest - ghcr.io/zarf-dev/doom-game:0.0.1") // Check flavors require.NotContains(t, strippedStderr, "image-in-bad-flavor-component:unpinned") require.Contains(t, strippedStderr, "image-in-good-flavor-component:unpinned") // Check reported filepaths - require.Contains(t, strippedStderr, "Linting package \"dos-games\" at oci://🦄/dos-games:1.0.0") + require.Contains(t, strippedStderr, "Linting package \"dos-games\" at oci://ghcr.io/zarf-dev/packages/dos-games:1.1.0") require.Contains(t, strippedStderr, fmt.Sprintf("Linting package \"lint\" at %s", testPackagePath)) }) } diff --git a/src/test/e2e/27_deploy_regression_test.go b/src/test/e2e/27_deploy_regression_test.go index 87663469f9..a4ba8e014f 100644 --- a/src/test/e2e/27_deploy_regression_test.go +++ b/src/test/e2e/27_deploy_regression_test.go @@ -18,13 +18,13 @@ func TestGHCRDeploy(t *testing.T) { // shas for package published 2023-08-08T22:13:51Z switch e2e.Arch { case "arm64": - sha = "ac7d7684ca9b4edb061a7732aefc17cfb7b7c983fec23e1fe319cf535618a8b6" + sha = "844dff9aa60345c67b597d5315db5e263cbda01b50643a8d0b7f5ec721f8a16f" case "amd64": - sha = "aca4d4cf24532d69a8941a446067fc3d8474581507236b37bb7188836d93bf89" + sha = "a44d17160cd6ce7b7b6d4687e7d3f75dad4fedba6670c79665af2e8665a7868e" } // Test with command from https://docs.zarf.dev/getting-started/install/ - stdOut, stdErr, err := e2e.Zarf(t, "package", "deploy", fmt.Sprintf("oci://🦄/dos-games:1.0.0-%s@sha256:%s", e2e.Arch, sha), "--key=https://raw.githubusercontent.com/zarf-dev/zarf/v0.38.2/cosign.pub", "--confirm") + stdOut, stdErr, err := e2e.Zarf(t, "package", "deploy", fmt.Sprintf("oci://ghcr.io/zarf-dev/packages/dos-games:1.1.0@sha256:%s", sha), "--key=https://zarf.dev/cosign.pub", "--confirm") require.NoError(t, err, stdOut, stdErr) stdOut, stdErr, err = e2e.Zarf(t, "package", "remove", "dos-games", "--confirm") diff --git a/src/test/packages/12-lint/linted-import/zarf.yaml b/src/test/packages/12-lint/linted-import/zarf.yaml index 04fdcd47f2..d4a190f9e6 100644 --- a/src/test/packages/12-lint/linted-import/zarf.yaml +++ b/src/test/packages/12-lint/linted-import/zarf.yaml @@ -19,5 +19,5 @@ components: - name: oci-games-url import: - url: oci://🦄/dos-games:1.0.0 + url: oci://ghcr.io/zarf-dev/packages/dos-games:1.1.0 name: baseline diff --git a/src/test/packages/12-lint/zarf.yaml b/src/test/packages/12-lint/zarf.yaml index c4c80ba6ea..8d4d9cd1d1 100644 --- a/src/test/packages/12-lint/zarf.yaml +++ b/src/test/packages/12-lint/zarf.yaml @@ -32,7 +32,7 @@ components: - name: oci-games-url import: - url: oci://🦄/dos-games:1.0.0 + url: oci://ghcr.io/zarf-dev/packages/dos-games:1.1.0 name: baseline - name: oci-games-url From 19cdbba65d520eac9350bf26482c59b9c62cae30 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 08:57:42 -0400 Subject: [PATCH 15/22] chore(deps): bump github/codeql-action from 3.26.4 to 3.26.5 (#2927) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scan-codeql.yml | 4 ++-- .github/workflows/scorecard.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scan-codeql.yml b/.github/workflows/scan-codeql.yml index 9ac8ca9b44..7812ffb0f7 100644 --- a/.github/workflows/scan-codeql.yml +++ b/.github/workflows/scan-codeql.yml @@ -53,7 +53,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 # v3.26.4 + uses: github/codeql-action/init@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 with: languages: ${{ matrix.language }} config-file: ./.github/codeql.yaml @@ -62,6 +62,6 @@ jobs: run: make build-cli-linux-amd - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 # v3.26.4 + uses: github/codeql-action/analyze@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml index 09c0be4927..2e36bc9c86 100644 --- a/.github/workflows/scorecard.yaml +++ b/.github/workflows/scorecard.yaml @@ -44,6 +44,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 # v3.26.4 + uses: github/codeql-action/upload-sarif@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 with: sarif_file: results.sarif From d7eb999851bc20ac68155fe11a23ed2b151a975d Mon Sep 17 00:00:00 2001 From: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Date: Tue, 27 Aug 2024 13:50:05 -0400 Subject: [PATCH 16/22] chore: schema adr (#2600) Signed-off-by: Austin Abro --- adr/0026-schema.md | 100 +++++++++ adr/0026-schema.yaml | 507 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 607 insertions(+) create mode 100644 adr/0026-schema.md create mode 100644 adr/0026-schema.yaml diff --git a/adr/0026-schema.md b/adr/0026-schema.md new file mode 100644 index 0000000000..d62d1d4041 --- /dev/null +++ b/adr/0026-schema.md @@ -0,0 +1,100 @@ +# 25. Zarf Schema for v1 + +Date: 2024-06-07 + +## Status + +Proposed + +## Terms +v0 = any version of Zarf prior to v1 + +## Context + +Zarf currently does not have explicit schema versions. Any schema changes are embedded into Zarf and can change with new versions. There are several examples of deprecated keys throughout Zarf's lifespan such as: + +- `setVariable` deprecated in favor of `setVariables` +- `scripts` deprecated in favor of `actions` +- `group` deprecated in favor of `flavor`, however these work functionally different and cannot be automatically migrated +- `cosignKeyPath` deprecated in favor of specifying the key path at create time + +Zarf has not disabled any deprecated keys thus far. On create the user is always warned when using a deprecated field, however the field still exists in the schema and functions properly. Some of the deprecated keys can be migrated automatically as the old item is a subset or directly related to it's replacement. For example, setVariable is automatically migrated to a single item list of setVariables. This migration occurs on the zarf.yaml fed into the package during package create, however the original field is not deleted from the packaged zarf.yaml because the Zarf binary used in the airgap or delivery environment is not assumed to have the new schema fields that the deprecated key was migrated to. + +The release of v1 will provide an opportunity to delete deprecated features that Zarf has warned will be dropped in v1. + +Creating a v1 schema will allow Zarf to establish a contract with it's user base that features will be supported long term. When a feature is deprecated in the v1 schema, it will remain usable in the schema for the lifetime of v1. + +## Decision + +Zarf will begin having proper schema versions. A top level key, `apiVersion`, will be introduced to allow users to specify the schema. At the release of v1 the only valid user input for `apiVersion` will be v1. Zarf will not allow users to build using the v0 schema. `zarf package create` will fail if the user has deprecated keys or if `apiVersion` is missing and the user will be instructed to run the new `zarf dev migrate-schema` command. `zarf dev migrate-schema` will automatically migrate deprecated fields in the users `zarf.yaml` where possible. It will also add the apiVersion key and set it to v1. + +The existing go types which comprise the Zarf schema will be moved to types/alpha and will never change. An updated copy of these types without the deprecated fields will be created in a package types/v1 and any future schema changes will affect these objects. Internally, Zarf will introduce translation functions which will take the alpha schema and return the v1 schema. From that point on, all function signatures that have a struct that is included in the Zarf schema will change from `types.structName` to `v1.structName`. + +All deprecated features will cause an error on create. Deprecated features with a direct migration path will still be deployed if the package was created with schema v1, as migrations will add the non deprecated fields. If a feature does not have a direct automatic migration path (cosignKeyPath & groups) the package will fail on deploy. This will happen until the alpha schema is entirely removed from Zarf, which will happen one year after v1 is released. + +At create time Zarf will package both a `zarf.yaml` and a `zarfv1.yaml`. If a `zarfv1.yaml` exists Zarf will use that. If a `zarfv1.yaml` does not exist, then Zarf will know that the package was created prior to v1 and use the regular `zarf.yaml`. If the package is deployed with v0 it will read the `zarf.yaml` as normal even if the package has a `zarfv1.yaml`. This will make it simpler to drop deprecated items with migration paths from the v1 schema while remaining backwards compatible as those deprecated items will exist in the `zarf.yaml` + +When Zarf introduces new keys that they are not ready to promise long term support for they will mark them as experimental in the schema. A key is assumed to be stable if it's not experimental or deprecated. + +There are several other keys Zarf will deprecate which will have automated migrations to new fields +- `.metadata.aggregateChecksum` -> `.build.aggregateChecksum` +- `.components[x].required` -> `.components[x].optional`. Optional will default to false. This is a change in behavior as currently `required` defaults to true. However, automatic migration will work since we can set optional to true on any components which do not already have required. +- Metadata fields `image`, `source`, `documentation`, `url`, `authors`, `vendors` -> will become a map of `annotations` +- `noWait` -> `wait` which will default to true. This change will happen on both `.components.[x].manifests` and `components.[x].charts` +- `yolo` -> `airgap` which will default to true +- `.components.[x].actions.[default/onAny].maxRetries` -> `.components.[x].actions.[default/onAny].retries` +- `.components.[x].actions.[default/onAny].maxTotalSeconds` -> `.components.[x].actions.[default/onAny].timeout`, which must be in a [Go recognized duration string format](https://pkg.go.dev/time#ParseDuration) +- charts will change to avoid [current confusion with keys](https://github.com/defenseunicorns/zarf/issues/2245). Exactly one of the following fields will exist for each `components.[x].charts`. +```yaml + helm: + url: https://stefanprodan.github.io/podinfo + RepoName: podinfo # replaces repoName since it's only applicable for helm repos + + git: + url: https://stefanprodan.github.io/podinfo + path: charts/podinfo + + oci: + url: oci://ghcr.io/stefanprodan/charts/podinfo + + local: + path: chart +``` +- A new field called `.components.[x].healthChecks` will be introduced and will utilize [kstatus](https://github.com/kubernetes-sigs/cli-utils/blob/master/pkg/kstatus/README.md) to wait for resources to be ready after deployment. Read [#2718](https://github.com/zarf-dev/zarf/issues/2718) for more detail. +- a new field `.components.[x].wait` will be introduced. It will default to true, and automatically run `healthchecks` for every object in the cluster. +- `.components.[x].extensions` will be removed in favor of `zarf dev generate bigbang`. See #2875 + +### BDD scenarios +The following are [behavior driven development](https://en.wikipedia.org/wiki/Behavior-driven_development) scenarios to provide context of what Zarf will do in specific situations given the above decisions. + +#### v1 create with deprecated keys +- *Given* Zarf version is v1 +- *and* the `zarf.yaml` has no apiVersion or deprecated keys +- *when* the user runs `zarf package create` +- *then* they will receive an error and be told to run `zarf dev migrate-schema` or how to migrate off cosign key paths or how to use flavors over groups depending on the error + +#### v0 create -> v1 deploy +- *Given*: A package is created with Zarf v0 +- *and* that package has deprecated keys that can be automatically migrated (required, scripts, & set variables) +- *when* the package is deployed with Zarf v1 +- *then* the keys will be automatically migrated & the package will be deployed without error. + +#### v0 create with removed feature -> v1 deploy +- *Given*: A package is created with Zarf v0 +- *and* that package has deprecated keys that cannot be automatically migrated (groups, cosignKeyPath) +- *when* the package is deployed with Zarf v1 +- *then* then deploy of that package will fail and the user will be instructed to update their package + +#### v1 create -> v0 deploy +- *Given*: A package is created with Zarf v1 +- *and* that package uses keys that don't exist in v0 +- *when* the package is deployed with Zarf v0 +- *then* Zarf v0 will deploy the package without issues. Additionally if the users is on a v0 version of Zarf after issue [2728](https://github.com/defenseunicorns/zarf/issues/2728) has been implemented, if there are fields unrecognized by the v0 schema, then the user will be warned they are deploying a package that has features that do not exist in the current version of Zarf. + +## Consequences +- As long as the only deprecated features in a package have a migration path, and the package was built after the feature was deprecated so migrations were run, Zarf will be successful in both creating a package with v1 and deploying with v0, and creating a package with v0 and deploying with v1. +- Users of deprecated `group`, `cosignKeyPath`, and `action.Wait` keys outside of `onDeploy` might be frustrated if their packages, created v0, error out on Zarf v1, however this is preferable to unexpected behavior occurring in the cluster. +- Users may be frustrated that they have to run `zarf dev migrate-schema` to edit their `zarf.yaml` to remove the deprecated fields and add `apiVersion`. +- The Zarf codebase will contain two Zarf package objects, v1 and v0. Many fields on these objects will be unchanged across v0 and v1, however, v0 will not include new fields, and v1 will exclude deprecated fields. This approach is similar to the strategies used by [Kubernetes](https://github.com/kubernetes/api/tree/master/storage) and [flux](https://github.com/fluxcd/source-controller/tree/main/api) + +Look at [0026-schema.yaml](0026-schema.yaml) to see an example v1 zarf.yaml with, somewhat, reasonable & nonempty values for every key. diff --git a/adr/0026-schema.yaml b/adr/0026-schema.yaml new file mode 100644 index 0000000000..4240d79621 --- /dev/null +++ b/adr/0026-schema.yaml @@ -0,0 +1,507 @@ +kind: ZarfPackageConfig +apiVersion: v1 +metadata: + name: everything-zarf-package + description: A zarf package with a non empty value for every key - this is an invalid package and is here to exhibit the proposed v1 schema by 0026-schema.md + version: v1.0.0 + uncompressed: true + architecture: amd64 + airgap: true # changed from yolo + annotations: # All of these are v0 fields that will be deprecated in favor of a choose your own adventure label map + authors: cool-kidz + documentation: https://my-package-documentation.com + source: https://my-git-server/my-package + url: https://my-package-website.com + vendor: my-vendor + image: https://my-image-url-to-use-in-deprecated-zarf-ui + anyway-you-want-it: thats-the-way-you-need-it +build: # Everything here is created by Zarf not be users + terminal: my-computer + user: my-user + architecture: amd64 + timestamp: 2021-09-01T00:00:00Z + version: v1.0.0 + migrations: + - scripts-to-actions + registryOverrides: + gcr.io: my-gcr.com + differential: true + differentialPackageVersion: "v0.99.9" + differentialMissing: + - missing-component + flavor: cool-flavor + lastNonBreakingVersion: "v0.99.9" + aggregateChecksum: shasum # this is moved from .metadata +components: +- name: a-component + description: Zarf description + default: false # Austin to check if we remove this + only: + localOS: darwin + cluster: + architecture: amd64 + distros: + - ubuntu + flavor: a-flavor # this will only be used when there are multiple components + import: + name: other-component-name + path: ABCD # Only path or URL will be used, not both + url: oci:// + manifests: + - name: manifest + namespace: manifest-ns + files: + - a-file.yaml + kustomizeAllowAnyDirectory: false + kustomizations: + - a-kustomization.yaml + wait: false + charts: + - name: chart + namespace: chart-ns + version: v1.0.0 + releaseName: chart-release + wait: true + valuesFiles: + - values.yaml + variables: + - name: REPLICA_COUNT + description: "Override the number of pod replicas" + path: replicaCount + # Everything below this line is changing https://github.com/defenseunicorns/zarf/issues/2245 + helm: # Only one of helm, git, oci, url, or local is allowed + url: https://stefanprodan.github.io/podinfo + name: podinfo # replaces repoName since it's only applicable in this situation + git: + url: https://stefanprodan.github.io/podinfo + path: charts/podinfo + oci: + url: oci://ghcr.io/stefanprodan/charts/podinfo + local: + path: chart + dataInjections: + - source: zim-data + target: + namespace: my-namespace + selector: app=my-app + container: data-loader + path: /data + compress: true + files: + - source: source-file.txt + target: target-file.txt + shasum: shasum + executable: false + symlinks: + - /path/to/symlink + extractPath: /path/to/extract + images: + - podinfo@v1 + repos: + - https://github.com/defenseunicorns/zarf + wait: true + healthChecks: + - apiVersion: v1 + kind: pod + name: my-pod + namespace: my-namespace + actions: + onCreate: + defaults: + mute: true + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + shell: + darwin: sh + linux: sh + windows: powershell + before: + - mute: false + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + cmd: echo hello + shell: + darwin: sh + linux: sh + windows: powershell + setVariables: + - name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: action-description + wait: + cluster: # Only one of cluster / network can be used + kind: pod + name: my-pod + namespace: pod-ns + condition: ready + network: + protocol: http + address: github.com + code: 200 + after: + - mute: false + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + cmd: echo hello + shell: + darwin: sh + linux: sh + windows: powershell + setVariables: + - name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: action-description + wait: + cluster: # Only one of cluster / network can be used + kind: pod + name: my-pod + namespace: pod-ns + condition: ready + network: + protocol: http + address: github.com + code: 200 + onSuccess: + - mute: false + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + cmd: echo hello + shell: + darwin: sh + linux: sh + windows: powershell + setVariables: + - name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: action-description + wait: + cluster: # Only one of cluster / network can be used + kind: pod + name: my-pod + namespace: pod-ns + condition: ready + network: + protocol: http + address: github.com + code: 200 + onFailure: + - mute: false + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + cmd: echo hello + shell: + darwin: sh + linux: sh + windows: powershell + setVariables: + - name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: action-description + wait: + cluster: # Only one of cluster / network can be used + kind: pod + name: my-pod + namespace: pod-ns + condition: ready + network: + protocol: http + address: github.com + code: 200 + onDeploy: + defaults: + mute: true + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + shell: + darwin: sh + linux: sh + windows: powershell + before: + - mute: false + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + cmd: echo hello + shell: + darwin: sh + linux: sh + windows: powershell + setVariables: + - name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: action-description + wait: + cluster: # Only one of cluster / network can be used + kind: pod + name: my-pod + namespace: pod-ns + condition: ready + network: + protocol: http + address: github.com + code: 200 + after: + - mute: false + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + cmd: echo hello + shell: + darwin: sh + linux: sh + windows: powershell + setVariables: + - name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: action-description + wait: + cluster: # Only one of cluster / network can be used + kind: pod + name: my-pod + namespace: pod-ns + condition: ready + network: + protocol: http + address: github.com + code: 200 + onSuccess: + - mute: false + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + cmd: echo hello + shell: + darwin: sh + linux: sh + windows: powershell + setVariables: + - name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: action-description + wait: + cluster: # Only one of cluster / network can be used + kind: pod + name: my-pod + namespace: pod-ns + condition: ready + network: + protocol: http + address: github.com + code: 200 + onFailure: + - mute: false + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + cmd: echo hello + shell: + darwin: sh + linux: sh + windows: powershell + setVariables: + - name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: action-description + wait: + cluster: # Only one of cluster / network can be used + kind: pod + name: my-pod + namespace: pod-ns + condition: ready + network: + protocol: http + address: github.com + code: 200 + onRemove: + defaults: + mute: true + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + shell: + darwin: sh + linux: sh + windows: powershell + before: + - mute: false + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + cmd: echo hello + shell: + darwin: sh + linux: sh + windows: powershell + setVariables: + - name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: action-description + wait: + cluster: # Only one of cluster / network can be used + kind: pod + name: my-pod + namespace: pod-ns + condition: ready + network: + protocol: http + address: github.com + code: 200 + after: + - mute: false + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + cmd: echo hello + shell: + darwin: sh + linux: sh + windows: powershell + setVariables: + - name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: action-description + wait: + cluster: # Only one of cluster / network can be used + kind: pod + name: my-pod + namespace: pod-ns + condition: ready + network: + protocol: http + address: github.com + code: 200 + onSuccess: + - mute: false + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + cmd: echo hello + shell: + darwin: sh + linux: sh + windows: powershell + setVariables: + - name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: action-description + wait: + cluster: # Only one of cluster / network can be used + kind: pod + name: my-pod + namespace: pod-ns + condition: ready + network: + protocol: http + address: github.com + code: 200 + onFailure: + - mute: false + timeout: 1m + retries: 0 + dir: dir + env: + - ENV_VAR=FOO + cmd: echo hello + shell: + darwin: sh + linux: sh + windows: powershell + setVariables: + - name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: action-description + wait: + cluster: # Only one of cluster / network can be used + kind: pod + name: my-pod + namespace: pod-ns + condition: ready + network: + protocol: http + address: github.com + code: 200 +constants: +- name: CONSTANT + value: constant-value + description: constant-value + autoIndent: false + pattern: ".+" +variables: +- name: VAR + sensitive: false + autoIndent: true + pattern: ".+" + type: raw + description: var + default: whatever + prompt: false From 41db046e91fab5628c03da2201283f8170729b42 Mon Sep 17 00:00:00 2001 From: Philip Laine Date: Thu, 29 Aug 2024 19:50:01 +0200 Subject: [PATCH 17/22] fix: remove use of pkg/errors (#2937) Signed-off-by: Philip Laine --- src/pkg/utils/cosign.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pkg/utils/cosign.go b/src/pkg/utils/cosign.go index 1e129ffb5c..21bfc282bd 100644 --- a/src/pkg/utils/cosign.go +++ b/src/pkg/utils/cosign.go @@ -6,6 +6,7 @@ package utils import ( "context" + "errors" "fmt" "io" "strings" @@ -14,10 +15,6 @@ import ( "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" "github.com/google/go-containerregistry/pkg/v1/remote" - "github.com/pkg/errors" - "github.com/zarf-dev/zarf/src/config/lang" - "github.com/zarf-dev/zarf/src/pkg/message" - "github.com/sigstore/cosign/v2/cmd/cosign/cli/fulcio" "github.com/sigstore/cosign/v2/cmd/cosign/cli/options" "github.com/sigstore/cosign/v2/cmd/cosign/cli/sign" @@ -31,6 +28,9 @@ import ( _ "github.com/sigstore/sigstore/pkg/signature/kms/azure" _ "github.com/sigstore/sigstore/pkg/signature/kms/gcp" _ "github.com/sigstore/sigstore/pkg/signature/kms/hashivault" + + "github.com/zarf-dev/zarf/src/config/lang" + "github.com/zarf-dev/zarf/src/pkg/message" ) // Sget performs a cosign signature verification on a given image using the specified public key. From 4b58792690f1c649391822ac1e87bc0b4d4d27b9 Mon Sep 17 00:00:00 2001 From: Philip Laine Date: Thu, 29 Aug 2024 20:25:11 +0200 Subject: [PATCH 18/22] refactor: remove use of named returns in packager (#2940) Signed-off-by: Philip Laine --- src/pkg/packager/common.go | 7 ++-- src/pkg/packager/deploy.go | 61 ++++++++++++++++++--------------- src/pkg/packager/generate.go | 2 +- src/pkg/packager/inspect.go | 5 +-- src/pkg/packager/interactive.go | 3 +- src/pkg/packager/pull.go | 4 +-- src/pkg/packager/remove.go | 5 +-- 7 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/pkg/packager/common.go b/src/pkg/packager/common.go index 6a3ec004e7..a3c5529e5a 100644 --- a/src/pkg/packager/common.go +++ b/src/pkg/packager/common.go @@ -130,15 +130,16 @@ func (p *Packager) GetVariableConfig() *variables.VariableConfig { } // connectToCluster attempts to connect to a cluster if a connection is not already established -func (p *Packager) connectToCluster(ctx context.Context) (err error) { +func (p *Packager) connectToCluster(ctx context.Context) error { if p.isConnectedToCluster() { return nil } - p.cluster, err = cluster.NewClusterWithWait(ctx) + cluster, err := cluster.NewClusterWithWait(ctx) if err != nil { return err } + p.cluster = cluster return p.attemptClusterChecks(ctx) } @@ -150,7 +151,7 @@ func (p *Packager) isConnectedToCluster() bool { // attemptClusterChecks attempts to connect to the cluster and check for useful metadata and config mismatches. // NOTE: attemptClusterChecks should only return an error if there is a problem significant enough to halt a deployment, otherwise it should return nil and print a warning message. -func (p *Packager) attemptClusterChecks(ctx context.Context) (err error) { +func (p *Packager) attemptClusterChecks(ctx context.Context) error { spinner := message.NewProgressSpinner("Gathering additional cluster information (if available)") defer spinner.Stop() diff --git a/src/pkg/packager/deploy.go b/src/pkg/packager/deploy.go index 2c5f2e5f2d..5f4a24e09b 100644 --- a/src/pkg/packager/deploy.go +++ b/src/pkg/packager/deploy.go @@ -138,7 +138,9 @@ func (p *Packager) Deploy(ctx context.Context) error { } // deployComponents loops through a list of ZarfComponents and deploys them. -func (p *Packager) deployComponents(ctx context.Context) (deployedComponents []types.DeployedComponent, err error) { +func (p *Packager) deployComponents(ctx context.Context) ([]types.DeployedComponent, error) { + deployedComponents := []types.DeployedComponent{} + // Process all the components we are deploying for _, component := range p.cfg.Pkg.Components { // Connect to cluster if a component requires it. @@ -168,10 +170,11 @@ func (p *Packager) deployComponents(ctx context.Context) (deployedComponents []t // Ensure we don't overwrite any installedCharts data when updating the package secret if p.isConnectedToCluster() { - deployedComponent.InstalledCharts, err = p.cluster.GetInstalledChartsForComponent(ctx, p.cfg.Pkg.Metadata.Name, component) + installedCharts, err := p.cluster.GetInstalledChartsForComponent(ctx, p.cfg.Pkg.Metadata.Name, component) if err != nil { message.Debugf("Unable to fetch installed Helm charts for component '%s': %s", component.Name, err.Error()) } + deployedComponent.InstalledCharts = installedCharts } deployedComponents = append(deployedComponents, deployedComponent) @@ -211,8 +214,7 @@ func (p *Packager) deployComponents(ctx context.Context) (deployedComponents []t 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 %q: %w", component.Name, deployErr) + return nil, fmt.Errorf("unable to deploy component %q: %w", component.Name, deployErr) } // Update the package secret to indicate that we successfully deployed this component @@ -226,14 +228,14 @@ func (p *Packager) deployComponents(ctx context.Context) (deployedComponents []t if err := actions.Run(ctx, onDeploy.Defaults, onDeploy.OnSuccess, p.variableConfig); err != nil { onFailure() - return deployedComponents, fmt.Errorf("unable to run component success action: %w", err) + return nil, fmt.Errorf("unable to run component success action: %w", err) } } return deployedComponents, nil } -func (p *Packager) deployInitComponent(ctx context.Context, component v1alpha1.ZarfComponent) (charts []types.InstalledChart, err error) { +func (p *Packager) deployInitComponent(ctx context.Context, component v1alpha1.ZarfComponent) ([]types.InstalledChart, error) { hasExternalRegistry := p.cfg.InitOpts.RegistryInfo.Address != "" isSeedRegistry := component.Name == "zarf-seed-registry" isRegistry := component.Name == "zarf-registry" @@ -247,7 +249,7 @@ func (p *Packager) deployInitComponent(ctx context.Context, component v1alpha1.Z // Always init the state before the first component that requires the cluster (on most deployments, the zarf-seed-registry) if component.RequiresCluster() && p.state == nil { - err = p.cluster.InitZarfState(ctx, p.cfg.InitOpts) + err := p.cluster.InitZarfState(ctx, p.cfg.InitOpts) if err != nil { return nil, fmt.Errorf("unable to initialize Zarf state: %w", err) } @@ -271,7 +273,9 @@ func (p *Packager) deployInitComponent(ctx context.Context, component v1alpha1.Z } } - charts, err = p.deployComponent(ctx, component, isAgent /* skip img checksum if isAgent */, isSeedRegistry /* skip image push if isSeedRegistry */) + // Skip image checksum if component is agent. + // Skip image push if component is seed registry. + charts, err := p.deployComponent(ctx, component, isAgent, isSeedRegistry) if err != nil { return nil, err } @@ -287,7 +291,7 @@ func (p *Packager) deployInitComponent(ctx context.Context, component v1alpha1.Z } // Deploy a Zarf Component. -func (p *Packager) deployComponent(ctx context.Context, component v1alpha1.ZarfComponent, noImgChecksum bool, noImgPush bool) (charts []types.InstalledChart, err error) { +func (p *Packager) deployComponent(ctx context.Context, component v1alpha1.ZarfComponent, noImgChecksum bool, noImgPush bool) ([]types.InstalledChart, error) { // Toggles for general deploy operations componentPath := p.layout.Components.Dirs[component.Name] @@ -305,9 +309,9 @@ func (p *Packager) deployComponent(ctx context.Context, component v1alpha1.ZarfC if component.RequiresCluster() { // Setup the state in the config if p.state == nil { - err = p.setupState(ctx) + err := p.setupState(ctx) if err != nil { - return charts, err + return nil, err } } @@ -321,30 +325,30 @@ func (p *Packager) deployComponent(ctx context.Context, component v1alpha1.ZarfC } } - err = p.populateComponentAndStateTemplates(component.Name) + err := p.populateComponentAndStateTemplates(component.Name) if err != nil { - return charts, err + return nil, err } if err = actions.Run(ctx, onDeploy.Defaults, onDeploy.Before, p.variableConfig); err != nil { - return charts, fmt.Errorf("unable to run component before action: %w", err) + return nil, fmt.Errorf("unable to run component before action: %w", err) } if hasFiles { if err := p.processComponentFiles(component, componentPath.Files); err != nil { - return charts, fmt.Errorf("unable to process the component files: %w", err) + return nil, fmt.Errorf("unable to process the component files: %w", err) } } if hasImages { if err := p.pushImagesToRegistry(ctx, component.Images, noImgChecksum); err != nil { - return charts, fmt.Errorf("unable to push images to the registry: %w", err) + return nil, fmt.Errorf("unable to push images to the registry: %w", err) } } if hasRepos { if err = p.pushReposToRepository(ctx, componentPath.Repos, component.Repos); err != nil { - return charts, fmt.Errorf("unable to push the repos to the repository: %w", err) + return nil, fmt.Errorf("unable to push the repos to the repository: %w", err) } } @@ -355,14 +359,15 @@ func (p *Packager) deployComponent(ctx context.Context, component v1alpha1.ZarfC }) } + charts := []types.InstalledChart{} if hasCharts || hasManifests { if charts, err = p.installChartAndManifests(ctx, componentPath, component); err != nil { - return charts, err + return nil, err } } if err = actions.Run(ctx, onDeploy.Defaults, onDeploy.After, p.variableConfig); err != nil { - return charts, fmt.Errorf("unable to run component after action: %w", err) + return nil, fmt.Errorf("unable to run component after action: %w", err) } err = g.Wait() @@ -452,7 +457,7 @@ func (p *Packager) processComponentFiles(component v1alpha1.ZarfComponent, pkgLo } // setupState fetches the current ZarfState from the k8s cluster and sets the packager to use it -func (p *Packager) setupState(ctx context.Context) (err error) { +func (p *Packager) setupState(ctx context.Context) error { // If we are touching K8s, make sure we can talk to it once per deployment spinner := message.NewProgressSpinner("Loading the Zarf State from the Kubernetes cluster") defer spinner.Stop() @@ -637,7 +642,9 @@ func (p *Packager) generateValuesOverrides(chart v1alpha1.ZarfChart, componentNa } // Install all Helm charts and raw k8s manifests into the k8s cluster. -func (p *Packager) installChartAndManifests(ctx context.Context, componentPaths *layout.ComponentPaths, component v1alpha1.ZarfComponent) (installedCharts []types.InstalledChart, err error) { +func (p *Packager) installChartAndManifests(ctx context.Context, componentPaths *layout.ComponentPaths, component v1alpha1.ZarfComponent) ([]types.InstalledChart, error) { + installedCharts := []types.InstalledChart{} + for _, chart := range component.Charts { // Do not wait for the chart to be ready if data injections are present. if len(component.DataInjections) > 0 { @@ -648,7 +655,7 @@ func (p *Packager) installChartAndManifests(ctx context.Context, componentPaths for idx := range chart.ValuesFiles { valueFilePath := helm.StandardValuesName(componentPaths.Values, chart, idx) if err := p.variableConfig.ReplaceTextTemplate(valueFilePath); err != nil { - return installedCharts, err + return nil, err } } @@ -656,7 +663,7 @@ func (p *Packager) installChartAndManifests(ctx context.Context, componentPaths // Values overrides are to be applied in order of Helm Chart Defaults -> Zarf `valuesFiles` -> Zarf `variables` -> DeployOpts overrides valuesOverrides, err := p.generateValuesOverrides(chart, component.Name) if err != nil { - return installedCharts, err + return nil, err } helmCfg := helm.New( @@ -675,7 +682,7 @@ func (p *Packager) installChartAndManifests(ctx context.Context, componentPaths addedConnectStrings, installedChartName, err := helmCfg.InstallOrUpgradeChart(ctx) if err != nil { - return installedCharts, err + return nil, err } installedCharts = append(installedCharts, types.InstalledChart{Namespace: chart.Namespace, ChartName: installedChartName}) @@ -691,7 +698,7 @@ func (p *Packager) installChartAndManifests(ctx context.Context, componentPaths // The path is likely invalid because of how we compose OCI components, add an index suffix to the filename manifest.Files[idx] = fmt.Sprintf("%s-%d.yaml", manifest.Name, idx) if helpers.InvalidPath(filepath.Join(componentPaths.Manifests, manifest.Files[idx])) { - return installedCharts, fmt.Errorf("unable to find manifest file %s", manifest.Files[idx]) + return nil, fmt.Errorf("unable to find manifest file %s", manifest.Files[idx]) } } } @@ -722,13 +729,13 @@ func (p *Packager) installChartAndManifests(ctx context.Context, componentPaths p.cfg.PkgOpts.Retries), ) if err != nil { - return installedCharts, err + return nil, err } // Install the chart. addedConnectStrings, installedChartName, err := helmCfg.InstallOrUpgradeChart(ctx) if err != nil { - return installedCharts, err + return nil, err } installedCharts = append(installedCharts, types.InstalledChart{Namespace: manifest.Namespace, ChartName: installedChartName}) diff --git a/src/pkg/packager/generate.go b/src/pkg/packager/generate.go index 068808b171..5d92d56b8d 100644 --- a/src/pkg/packager/generate.go +++ b/src/pkg/packager/generate.go @@ -21,7 +21,7 @@ import ( ) // Generate generates a Zarf package definition. -func (p *Packager) Generate(ctx context.Context) (err error) { +func (p *Packager) Generate(ctx context.Context) error { generatedZarfYAMLPath := filepath.Join(p.cfg.GenerateOpts.Output, layout.ZarfYAML) spinner := message.NewProgressSpinner("Generating package for %q at %s", p.cfg.GenerateOpts.Name, generatedZarfYAMLPath) diff --git a/src/pkg/packager/inspect.go b/src/pkg/packager/inspect.go index 88b1de88d8..ae850498b8 100644 --- a/src/pkg/packager/inspect.go +++ b/src/pkg/packager/inspect.go @@ -15,13 +15,14 @@ import ( ) // Inspect list the contents of a package. -func (p *Packager) Inspect(ctx context.Context) (err error) { +func (p *Packager) Inspect(ctx context.Context) error { wantSBOM := p.cfg.InspectOpts.ViewSBOM || p.cfg.InspectOpts.SBOMOutputDir != "" - p.cfg.Pkg, _, err = p.source.LoadPackageMetadata(ctx, p.layout, wantSBOM, true) + pkg, _, err := p.source.LoadPackageMetadata(ctx, p.layout, wantSBOM, true) if err != nil { return err } + p.cfg.Pkg = pkg if p.cfg.InspectOpts.ListImages { imageList := []string{} diff --git a/src/pkg/packager/interactive.go b/src/pkg/packager/interactive.go index 3a09595eab..bd44342e7f 100644 --- a/src/pkg/packager/interactive.go +++ b/src/pkg/packager/interactive.go @@ -18,7 +18,7 @@ import ( "github.com/zarf-dev/zarf/src/pkg/utils" ) -func (p *Packager) confirmAction(stage string, warnings []string, sbomViewFiles []string) (confirm bool) { +func (p *Packager) confirmAction(stage string, warnings []string, sbomViewFiles []string) bool { pterm.Println() message.HeaderInfof("📦 PACKAGE DEFINITION") utils.ColorPrintYAML(p.cfg.Pkg, p.getPackageYAMLHints(stage), true) @@ -77,6 +77,7 @@ func (p *Packager) confirmAction(stage string, warnings []string, sbomViewFiles pterm.Println() // Prompt the user for confirmation, on abort return false + var confirm bool if err := survey.AskOne(prompt, &confirm); err != nil || !confirm { // User aborted or declined, cancel the action return false diff --git a/src/pkg/packager/pull.go b/src/pkg/packager/pull.go index 7c00d36c9c..a80f36497c 100644 --- a/src/pkg/packager/pull.go +++ b/src/pkg/packager/pull.go @@ -10,12 +10,12 @@ import ( ) // Pull pulls a Zarf package and saves it as a compressed tarball. -func (p *Packager) Pull(ctx context.Context) (err error) { +func (p *Packager) Pull(ctx context.Context) error { if p.cfg.PkgOpts.OptionalComponents != "" { return fmt.Errorf("pull does not support optional components") } - _, err = p.source.Collect(ctx, p.cfg.PullOpts.OutputDirectory) + _, err := p.source.Collect(ctx, p.cfg.PullOpts.OutputDirectory) if err != nil { return err } diff --git a/src/pkg/packager/remove.go b/src/pkg/packager/remove.go index 4edcdd5b05..322db5570f 100644 --- a/src/pkg/packager/remove.go +++ b/src/pkg/packager/remove.go @@ -30,7 +30,7 @@ import ( ) // Remove removes a package that was already deployed onto a cluster, uninstalling all installed helm charts. -func (p *Packager) Remove(ctx context.Context) (err error) { +func (p *Packager) Remove(ctx context.Context) error { _, isClusterSource := p.source.(*sources.ClusterSource) if isClusterSource { p.cluster = p.source.(*sources.ClusterSource).Cluster @@ -40,10 +40,11 @@ func (p *Packager) Remove(ctx context.Context) (err error) { // we do not want to allow removal of signed packages without a signature if there are remove actions // as this is arbitrary code execution from an untrusted source - p.cfg.Pkg, _, err = p.source.LoadPackageMetadata(ctx, p.layout, false, false) + pkg, _, err := p.source.LoadPackageMetadata(ctx, p.layout, false, false) if err != nil { return err } + p.cfg.Pkg = pkg packageName := p.cfg.Pkg.Metadata.Name // Build a list of components to remove and determine if we need a cluster connection From f60b2f48727bbe4be3ebbe90366ecdd4ef8b3f39 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Aug 2024 07:51:01 +0200 Subject: [PATCH 19/22] chore(deps): bump github/codeql-action from 3.26.5 to 3.26.6 (#2948) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scan-codeql.yml | 4 ++-- .github/workflows/scorecard.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/scan-codeql.yml b/.github/workflows/scan-codeql.yml index 7812ffb0f7..d1815026c9 100644 --- a/.github/workflows/scan-codeql.yml +++ b/.github/workflows/scan-codeql.yml @@ -53,7 +53,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 + uses: github/codeql-action/init@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 with: languages: ${{ matrix.language }} config-file: ./.github/codeql.yaml @@ -62,6 +62,6 @@ jobs: run: make build-cli-linux-amd - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 + uses: github/codeql-action/analyze@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml index 2e36bc9c86..16bd6597df 100644 --- a/.github/workflows/scorecard.yaml +++ b/.github/workflows/scorecard.yaml @@ -44,6 +44,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 + uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6 with: sarif_file: results.sarif From 10bf7465c4b0fc0b0477bb55f5189cd2b85d0d01 Mon Sep 17 00:00:00 2001 From: Philip Laine Date: Fri, 30 Aug 2024 17:35:10 +0200 Subject: [PATCH 20/22] refactor: remove printing available Helm charts and versions when the Chart is not found (#2944) Signed-off-by: Philip Laine --- src/internal/packager/helm/repo.go | 76 ++++-------------------------- src/test/e2e/25_helm_test.go | 1 - 2 files changed, 10 insertions(+), 67 deletions(-) diff --git a/src/internal/packager/helm/repo.go b/src/internal/packager/helm/repo.go index 24f3a7f4b0..378b12c9cf 100644 --- a/src/internal/packager/helm/repo.go +++ b/src/internal/packager/helm/repo.go @@ -13,23 +13,22 @@ import ( "strings" "github.com/defenseunicorns/pkg/helpers/v2" - "github.com/zarf-dev/zarf/src/config" - "github.com/zarf-dev/zarf/src/config/lang" - "github.com/zarf-dev/zarf/src/internal/git" - "github.com/zarf-dev/zarf/src/pkg/message" - "github.com/zarf-dev/zarf/src/pkg/transform" - "github.com/zarf-dev/zarf/src/pkg/utils" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart" - "helm.sh/helm/v3/pkg/cli" - "helm.sh/helm/v3/pkg/helmpath" - "helm.sh/helm/v3/pkg/registry" - "k8s.io/client-go/util/homedir" - "helm.sh/helm/v3/pkg/chart/loader" + "helm.sh/helm/v3/pkg/cli" "helm.sh/helm/v3/pkg/downloader" "helm.sh/helm/v3/pkg/getter" + "helm.sh/helm/v3/pkg/registry" "helm.sh/helm/v3/pkg/repo" + "k8s.io/client-go/util/homedir" + + "github.com/zarf-dev/zarf/src/config" + "github.com/zarf-dev/zarf/src/config/lang" + "github.com/zarf-dev/zarf/src/internal/git" + "github.com/zarf-dev/zarf/src/pkg/message" + "github.com/zarf-dev/zarf/src/pkg/transform" + "github.com/zarf-dev/zarf/src/pkg/utils" ) // PackageChart creates a chart archive from a path to a chart on the host os and builds chart dependencies @@ -181,10 +180,6 @@ func (h *Helm) DownloadPublishedChart(ctx context.Context, cosignKeyPath string) chartURL, err = repo.FindChartInAuthRepoURL(h.chart.URL, username, password, chartName, h.chart.Version, pull.CertFile, pull.KeyFile, pull.CaFile, getter.All(pull.Settings)) if err != nil { - if strings.Contains(err.Error(), "not found") { - // Intentionally dogsled this error since this is just a nice to have helper - _ = h.listAvailableChartsAndVersions(pull) - } return fmt.Errorf("unable to pull the helm chart: %w", err) } } @@ -337,54 +332,3 @@ func (h *Helm) loadAndValidateChart(location string) (loader.ChartLoader, *chart return cl, chart, nil } - -func (h *Helm) listAvailableChartsAndVersions(pull *action.Pull) error { - c := repo.Entry{ - URL: h.chart.URL, - CertFile: pull.CertFile, - KeyFile: pull.KeyFile, - CAFile: pull.CaFile, - Name: h.chart.Name, - } - - r, err := repo.NewChartRepository(&c, getter.All(pull.Settings)) - if err != nil { - return err - } - idx, err := r.DownloadIndexFile() - if err != nil { - return fmt.Errorf("looks like %q is not a valid chart repository or cannot be reached: %w", h.chart.URL, err) - } - defer func() { - os.RemoveAll(filepath.Join(r.CachePath, helmpath.CacheChartsFile(r.Config.Name))) - os.RemoveAll(filepath.Join(r.CachePath, helmpath.CacheIndexFile(r.Config.Name))) - }() - - // Read the index file for the repository to get chart information and return chart URL - repoIndex, err := repo.LoadIndexFile(idx) - if err != nil { - return err - } - - chartData := [][]string{} - for name, entries := range repoIndex.Entries { - versions := "" - for idx, entry := range entries { - separator := "" - if idx < len(entries)-1 { - separator = ", " - } - versions += entry.Version + separator - } - - versions = helpers.Truncate(versions, 75, false) - chartData = append(chartData, []string{name, versions}) - } - - message.Notef("Available charts and versions from %q:", h.chart.URL) - - // Print out the table for the user - header := []string{"Chart", "Versions"} - message.Table(header, chartData) - return nil -} diff --git a/src/test/e2e/25_helm_test.go b/src/test/e2e/25_helm_test.go index b37c3ad39a..e1814d4b1e 100644 --- a/src/test/e2e/25_helm_test.go +++ b/src/test/e2e/25_helm_test.go @@ -52,7 +52,6 @@ func testHelmChartsExample(t *testing.T) { stdOut, stdErr, err = e2e.Zarf(t, "package", "create", evilChartLookupPath, "--tmpdir", tmpdir, "--confirm") require.Error(t, err, stdOut, stdErr) 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 a test package (with a registry override (host+subpath to host+subpath) to test that as well) stdOut, stdErr, err = e2e.Zarf(t, "package", "create", "examples/helm-charts", "-o", "build", "--registry-override", "ghcr.io/stefanprodan=docker.io/stefanprodan", "--tmpdir", tmpdir, "--confirm") From e23985732fa40a01b7e334ffea1d57f9834d1662 Mon Sep 17 00:00:00 2001 From: Philip Laine Date: Tue, 3 Sep 2024 10:25:56 +0200 Subject: [PATCH 21/22] refactor: remove connect strings from packager property (#2941) Signed-off-by: Philip Laine --- src/pkg/cluster/zarf.go | 16 ++++++++++++--- src/pkg/packager/common.go | 1 - src/pkg/packager/deploy.go | 41 ++++++++++++++++++-------------------- src/pkg/packager/dev.go | 3 --- src/types/k8s.go | 5 +++-- 5 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/pkg/cluster/zarf.go b/src/pkg/cluster/zarf.go index 14c3e2f31a..3557544e14 100644 --- a/src/pkg/cluster/zarf.go +++ b/src/pkg/cluster/zarf.go @@ -134,8 +134,8 @@ func (c *Cluster) PackageSecretNeedsWait(deployedPackage *types.DeployedPackage, } // RecordPackageDeploymentAndWait records the deployment of a package to the cluster and waits for any webhooks to complete. -func (c *Cluster) RecordPackageDeploymentAndWait(ctx context.Context, pkg v1alpha1.ZarfPackage, components []types.DeployedComponent, connectStrings types.ConnectStrings, generation int, component v1alpha1.ZarfComponent, skipWebhooks bool) (*types.DeployedPackage, error) { - deployedPackage, err := c.RecordPackageDeployment(ctx, pkg, components, connectStrings, generation) +func (c *Cluster) RecordPackageDeploymentAndWait(ctx context.Context, pkg v1alpha1.ZarfPackage, components []types.DeployedComponent, generation int, component v1alpha1.ZarfComponent, skipWebhooks bool) (*types.DeployedPackage, error) { + deployedPackage, err := c.RecordPackageDeployment(ctx, pkg, components, generation) if err != nil { return nil, err } @@ -174,7 +174,7 @@ func (c *Cluster) RecordPackageDeploymentAndWait(ctx context.Context, pkg v1alph } // RecordPackageDeployment saves metadata about a package that has been deployed to the cluster. -func (c *Cluster) RecordPackageDeployment(ctx context.Context, pkg v1alpha1.ZarfPackage, components []types.DeployedComponent, connectStrings types.ConnectStrings, generation int) (deployedPackage *types.DeployedPackage, err error) { +func (c *Cluster) RecordPackageDeployment(ctx context.Context, pkg v1alpha1.ZarfPackage, components []types.DeployedComponent, generation int) (deployedPackage *types.DeployedPackage, err error) { packageName := pkg.Metadata.Name // Attempt to load information about webhooks for the package @@ -187,6 +187,16 @@ func (c *Cluster) RecordPackageDeployment(ctx context.Context, pkg v1alpha1.Zarf componentWebhooks = existingPackageSecret.ComponentWebhooks } + // TODO: This is done for backwards compartibility and could be removed in the future. + connectStrings := types.ConnectStrings{} + for _, comp := range components { + for _, chart := range comp.InstalledCharts { + for k, v := range chart.ConnectStrings { + connectStrings[k] = v + } + } + } + deployedPackage = &types.DeployedPackage{ Name: packageName, CLIVersion: config.CLIVersion, diff --git a/src/pkg/packager/common.go b/src/pkg/packager/common.go index a3c5529e5a..1325a70b46 100644 --- a/src/pkg/packager/common.go +++ b/src/pkg/packager/common.go @@ -36,7 +36,6 @@ type Packager struct { cluster *cluster.Cluster layout *layout.PackagePaths hpaModified bool - connectStrings types.ConnectStrings source sources.PackageSource } diff --git a/src/pkg/packager/deploy.go b/src/pkg/packager/deploy.go index 5f4a24e09b..517bff7d60 100644 --- a/src/pkg/packager/deploy.go +++ b/src/pkg/packager/deploy.go @@ -113,7 +113,6 @@ func (p *Packager) Deploy(ctx context.Context) error { } p.hpaModified = false - p.connectStrings = make(types.ConnectStrings) // Reset registry HPA scale down whether an error occurs or not defer p.resetRegistryHPA(ctx) @@ -182,7 +181,7 @@ func (p *Packager) deployComponents(ctx context.Context) ([]types.DeployedCompon // Update the package secret to indicate that we are attempting to deploy this component if p.isConnectedToCluster() { - if _, err := p.cluster.RecordPackageDeploymentAndWait(ctx, p.cfg.Pkg, deployedComponents, p.connectStrings, packageGeneration, component, p.cfg.DeployOpts.SkipWebhooks); err != nil { + if _, err := p.cluster.RecordPackageDeploymentAndWait(ctx, p.cfg.Pkg, deployedComponents, packageGeneration, 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()) } } @@ -193,7 +192,7 @@ func (p *Packager) deployComponents(ctx context.Context) ([]types.DeployedCompon if p.cfg.Pkg.IsInitConfig() { charts, deployErr = p.deployInitComponent(ctx, component) } else { - charts, deployErr = p.deployComponent(ctx, component, false /* keep img checksum */, false /* always push images */) + charts, deployErr = p.deployComponent(ctx, component, false, false) } onDeploy := component.Actions.OnDeploy @@ -210,7 +209,7 @@ func (p *Packager) deployComponents(ctx context.Context) ([]types.DeployedCompon // Update the package secret to indicate that we failed to deploy this component deployedComponents[idx].Status = types.ComponentStatusFailed if p.isConnectedToCluster() { - if _, err := p.cluster.RecordPackageDeploymentAndWait(ctx, p.cfg.Pkg, deployedComponents, p.connectStrings, packageGeneration, component, p.cfg.DeployOpts.SkipWebhooks); err != nil { + if _, err := p.cluster.RecordPackageDeploymentAndWait(ctx, p.cfg.Pkg, deployedComponents, packageGeneration, component, p.cfg.DeployOpts.SkipWebhooks); err != nil { message.Debugf("Unable to record package deployment for component %q: this will affect features like `zarf package remove`: %s", component.Name, err.Error()) } } @@ -221,7 +220,7 @@ func (p *Packager) deployComponents(ctx context.Context) ([]types.DeployedCompon deployedComponents[idx].InstalledCharts = charts deployedComponents[idx].Status = types.ComponentStatusSucceeded if p.isConnectedToCluster() { - if _, err := p.cluster.RecordPackageDeploymentAndWait(ctx, p.cfg.Pkg, deployedComponents, p.connectStrings, packageGeneration, component, p.cfg.DeployOpts.SkipWebhooks); err != nil { + if _, err := p.cluster.RecordPackageDeploymentAndWait(ctx, p.cfg.Pkg, deployedComponents, packageGeneration, component, p.cfg.DeployOpts.SkipWebhooks); err != nil { message.Debugf("Unable to record package deployment for component %q: this will affect features like `zarf package remove`: %s", component.Name, err.Error()) } } @@ -361,7 +360,8 @@ func (p *Packager) deployComponent(ctx context.Context, component v1alpha1.ZarfC charts := []types.InstalledChart{} if hasCharts || hasManifests { - if charts, err = p.installChartAndManifests(ctx, componentPath, component); err != nil { + charts, err = p.installChartAndManifests(ctx, componentPath, component) + if err != nil { return nil, err } } @@ -680,16 +680,11 @@ func (p *Packager) installChartAndManifests(ctx context.Context, componentPaths p.cfg.PkgOpts.Retries), ) - addedConnectStrings, installedChartName, err := helmCfg.InstallOrUpgradeChart(ctx) + connectStrings, installedChartName, err := helmCfg.InstallOrUpgradeChart(ctx) if err != nil { return nil, err } - installedCharts = append(installedCharts, types.InstalledChart{Namespace: chart.Namespace, ChartName: installedChartName}) - - // Iterate over any connectStrings and add to the main map - for name, description := range addedConnectStrings { - p.connectStrings[name] = description - } + installedCharts = append(installedCharts, types.InstalledChart{Namespace: chart.Namespace, ChartName: installedChartName, ConnectStrings: connectStrings}) } for _, manifest := range component.Manifests { @@ -733,17 +728,11 @@ func (p *Packager) installChartAndManifests(ctx context.Context, componentPaths } // Install the chart. - addedConnectStrings, installedChartName, err := helmCfg.InstallOrUpgradeChart(ctx) + connectStrings, installedChartName, err := helmCfg.InstallOrUpgradeChart(ctx) if err != nil { return nil, err } - - installedCharts = append(installedCharts, types.InstalledChart{Namespace: manifest.Namespace, ChartName: installedChartName}) - - // Iterate over any connectStrings and add to the main map - for name, description := range addedConnectStrings { - p.connectStrings[name] = description - } + installedCharts = append(installedCharts, types.InstalledChart{Namespace: manifest.Namespace, ChartName: installedChartName, ConnectStrings: connectStrings}) } return installedCharts, nil @@ -752,7 +741,15 @@ func (p *Packager) installChartAndManifests(ctx context.Context, componentPaths func (p *Packager) printTablesForDeployment(ctx context.Context, componentsToDeploy []types.DeployedComponent) error { // If not init config, print the application connection table if !p.cfg.Pkg.IsInitConfig() { - message.PrintConnectStringTable(p.connectStrings) + connectStrings := types.ConnectStrings{} + for _, comp := range componentsToDeploy { + for _, chart := range comp.InstalledCharts { + for k, v := range chart.ConnectStrings { + connectStrings[k] = v + } + } + } + message.PrintConnectStringTable(connectStrings) return nil } // Don't print if cluster is not configured diff --git a/src/pkg/packager/dev.go b/src/pkg/packager/dev.go index 49232ddc1b..de7af6f4af 100644 --- a/src/pkg/packager/dev.go +++ b/src/pkg/packager/dev.go @@ -16,7 +16,6 @@ import ( "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/packager/creator" "github.com/zarf-dev/zarf/src/pkg/packager/filters" - "github.com/zarf-dev/zarf/src/types" ) // DevDeploy creates + deploys a package in one shot @@ -75,8 +74,6 @@ func (p *Packager) DevDeploy(ctx context.Context) error { message.HeaderInfof("📦 PACKAGE DEPLOY %s", p.cfg.Pkg.Metadata.Name) - p.connectStrings = make(types.ConnectStrings) - if !p.cfg.CreateOpts.NoYOLO { p.cfg.Pkg.Metadata.YOLO = true } else { diff --git a/src/types/k8s.go b/src/types/k8s.go index 84ad8d7994..696be20b79 100644 --- a/src/types/k8s.go +++ b/src/types/k8s.go @@ -119,8 +119,9 @@ type Webhook struct { // InstalledChart contains information about a Helm Chart that has been deployed to a cluster. type InstalledChart struct { - Namespace string `json:"namespace"` - ChartName string `json:"chartName"` + Namespace string `json:"namespace"` + ChartName string `json:"chartName"` + ConnectStrings ConnectStrings `json:"connectStrings,omitempty"` } // GitServerInfo contains information Zarf uses to communicate with a git repository to push/pull repositories to. From e505683f9187ce2ea9ebb195ee15a5b100513d03 Mon Sep 17 00:00:00 2001 From: Austin Abro <37223396+AustinAbro321@users.noreply.github.com> Date: Tue, 3 Sep 2024 09:40:20 -0400 Subject: [PATCH 22/22] fix(ci): test-imports workflow breaks when called from a fork (#2946) Signed-off-by: Austin Abro --- .github/workflows/test-import.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-import.yaml b/.github/workflows/test-import.yaml index 1cc6784f04..c5571593fe 100644 --- a/.github/workflows/test-import.yaml +++ b/.github/workflows/test-import.yaml @@ -28,7 +28,7 @@ jobs: cd $(mktemp -d) echo "$GO_MAIN" > main.go go mod init github.com/zarf-dev/test-import - go mod edit -replace github.com/zarf-dev/zarf=github.com/${{ github.repository }}@${COMMIT_SHA:0:12} + go mod edit -replace github.com/zarf-dev/zarf=github.com/${{ github.event.pull_request.head.repo.full_name }}@${COMMIT_SHA:0:12} go mod tidy cat go.mod | grep -q ${COMMIT_SHA:0:12} go run main.go