diff --git a/README.md b/README.md index 6985ea85..7543b2b7 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,7 @@ packages: package: output-var ``` -Variables that you want to make available to other package are in the `export` block of the Zarf package to export a variable from. To have another package ingest an exported variable, use the `imports` key to name both the `variable` and `package` that the variable is exported from. +Variables that you want to make available to other packages are in the `export` block of the Zarf package to export a variable from. By default, all exported variables are available to all of the packages in a bundle. To have another package ingest a specific exported variable, like in the case of variable name collisions, use the `imports` key to name both the `variable` and `package` that the variable is exported from, like in the example above. In the example above, the `OUTPUT` variable is created as part of a Zarf Action in the [output-var](src/test/packages/zarf/no-cluster/output-var) package, and the [receive-var](src/test/packages/zarf/no-cluster/receive-var) package expects a variable called `OUTPUT`. diff --git a/src/pkg/bundle/deploy.go b/src/pkg/bundle/deploy.go index 45c8cb5d..333688db 100644 --- a/src/pkg/bundle/deploy.go +++ b/src/pkg/bundle/deploy.go @@ -212,6 +212,13 @@ func deployPackages(packages []types.Package, resume bool, b *Bundle, zarfPackag func (b *Bundle) loadVariables(pkg types.Package, bundleExportedVars map[string]map[string]string) map[string]string { pkgVars := make(map[string]string) + // load all exported variables + for _, exportedVarMap := range bundleExportedVars { + for varName, varValue := range exportedVarMap { + pkgVars[strings.ToUpper(varName)] = varValue + } + } + // Set variables in order or precendence (least specific to most specific) // imported vars for _, imp := range pkg.Imports { diff --git a/src/test/bundles/02-simple-vars/export-name-collision/uds-bundle.yaml b/src/test/bundles/02-simple-vars/export-name-collision/uds-bundle.yaml new file mode 100644 index 00000000..ad15a689 --- /dev/null +++ b/src/test/bundles/02-simple-vars/export-name-collision/uds-bundle.yaml @@ -0,0 +1,26 @@ +kind: UDSBundle +metadata: + name: export-name-collision + description: show how to specify import vars in case of name collisions + version: 0.0.1 + +packages: + - name: output-var + repository: localhost:888/output-var + ref: 0.0.1 + exports: + - name: OUTPUT + - name: PRECEDENCE + + - name: output-var-collision + repository: localhost:888/output-var-collision + ref: 0.0.1 + exports: + - name: OUTPUT + + - name: receive-var + repository: localhost:888/receive-var + ref: 0.0.1 + imports: + - package: output-var-collision + name: OUTPUT diff --git a/src/test/bundles/02-simple-vars/import-all-bad-name/uds-bundle.yaml b/src/test/bundles/02-simple-vars/import-all-bad-name/uds-bundle.yaml new file mode 100644 index 00000000..34671511 --- /dev/null +++ b/src/test/bundles/02-simple-vars/import-all-bad-name/uds-bundle.yaml @@ -0,0 +1,20 @@ +kind: UDSBundle +metadata: + name: import-all-bad-name + description: show errors for bad imports + version: 0.0.1 + +packages: + - name: output-var + repository: localhost:888/output-var + ref: 0.0.1 + exports: + - name: OUTPUT + - name: PRECEDENCE + + - name: receive-var + repository: localhost:888/receive-var + ref: 0.0.1 + imports: + - package: output-varz + name: OUTPUTZ diff --git a/src/test/bundles/02-simple-vars/import-all/uds-bundle.yaml b/src/test/bundles/02-simple-vars/import-all/uds-bundle.yaml new file mode 100644 index 00000000..7c2e28fa --- /dev/null +++ b/src/test/bundles/02-simple-vars/import-all/uds-bundle.yaml @@ -0,0 +1,17 @@ +kind: UDSBundle +metadata: + name: import-all + description: show how global exports work + version: 0.0.1 + +packages: + - name: output-var + repository: localhost:888/output-var + ref: 0.0.1 + exports: + - name: OUTPUT + - name: PRECEDENCE + + - name: receive-var + repository: localhost:888/receive-var + ref: 0.0.1 diff --git a/src/test/e2e/commands_test.go b/src/test/e2e/commands_test.go index f52c5c06..1cf9e501 100644 --- a/src/test/e2e/commands_test.go +++ b/src/test/e2e/commands_test.go @@ -30,6 +30,12 @@ func createLocal(t *testing.T, bundlePath string, arch string) { require.NoError(t, err) } +func createLocalError(t *testing.T, bundlePath string, arch string) (stderr string) { + cmd := strings.Split(fmt.Sprintf("create %s --insecure --confirm -a %s", bundlePath, arch), " ") + _, stderr, _ = e2e.UDS(cmd...) + return stderr +} + func createRemoteInsecure(t *testing.T, bundlePath, registry, arch string) { cmd := strings.Split(fmt.Sprintf("create %s -o %s --confirm --insecure -a %s", bundlePath, registry, arch), " ") _, _, err := e2e.UDS(cmd...) diff --git a/src/test/e2e/variable_test.go b/src/test/e2e/variable_test.go index 95bbdffa..a8edf1ef 100644 --- a/src/test/e2e/variable_test.go +++ b/src/test/e2e/variable_test.go @@ -39,7 +39,38 @@ func TestBundleVariables(t *testing.T) { os.Setenv("UDS_CONFIG", filepath.Join("src/test/bundles/02-simple-vars", "uds-config.yaml")) _, stderr := deploy(t, bundleTarballPath) + bundleVariablesTestChecks(t, stderr, bundleTarballPath) + remove(t, bundleTarballPath) + // Run same test checks but with package that isn't explicitly importing vars + bundleDir = "src/test/bundles/02-simple-vars/import-all" + bundleTarballPath = filepath.Join(bundleDir, fmt.Sprintf("uds-bundle-import-all-%s-0.0.1.tar.zst", e2e.Arch)) + createLocal(t, bundleDir, e2e.Arch) + _, stderr = deploy(t, bundleTarballPath) + bundleVariablesTestChecks(t, stderr, bundleTarballPath) + + // Test with bad variable name in import + bundleDir = "src/test/bundles/02-simple-vars/import-all-bad-name" + stderr = createLocalError(t, bundleDir, e2e.Arch) + require.Contains(t, stderr, "does not have a matching export") + + // Test name collisions with exported variables + zarfPkgPath3 := "src/test/packages/no-cluster/output-var-collision" + e2e.CreateZarfPkg(t, zarfPkgPath3, false) + + pkg = filepath.Join(zarfPkgPath3, fmt.Sprintf("zarf-package-output-var-collision-%s-0.0.1.tar.zst", e2e.Arch)) + zarfPublish(t, pkg, "localhost:888") + + bundleDir = "src/test/bundles/02-simple-vars/export-name-collision" + bundleTarballPath = filepath.Join(bundleDir, fmt.Sprintf("uds-bundle-export-name-collision-%s-0.0.1.tar.zst", e2e.Arch)) + createLocal(t, bundleDir, e2e.Arch) + createRemoteInsecure(t, bundleDir, "localhost:888", e2e.Arch) + _, stderr = deploy(t, bundleTarballPath) + require.Contains(t, stderr, "This fun-fact was imported: Daffodils are the national flower of Wales") + require.NotContains(t, stderr, "This fun-fact was imported: Unicorns are the national animal of Scotland") +} + +func bundleVariablesTestChecks(t *testing.T, stderr string, bundleTarballPath string) { require.NotContains(t, stderr, "CLIVersion is set to 'unset' which can cause issues with package creation and deployment") require.Contains(t, stderr, "This fun-fact was imported: Unicorns are the national animal of Scotland") require.Contains(t, stderr, "This fun-fact demonstrates precedence: The Red Dragon is the national symbol of Wales") diff --git a/src/test/packages/no-cluster/output-var-collision/zarf.yaml b/src/test/packages/no-cluster/output-var-collision/zarf.yaml new file mode 100644 index 00000000..db6b6f1c --- /dev/null +++ b/src/test/packages/no-cluster/output-var-collision/zarf.yaml @@ -0,0 +1,22 @@ +kind: ZarfPackageConfig +metadata: + name: output-var-collision + description: | + Exports variable with same name as variable exported from output-var package + version: 0.0.1 + +variables: + - name: COUNTRY + default: Wales + - name: FLOWER + default: Daffodils + +components: + - name: echo + required: true + actions: + onDeploy: + after: + - cmd: echo ""${ZARF_VAR_FLOWER}" are the national flower of "${ZARF_VAR_COUNTRY}"" + setVariables: + - name: OUTPUT