From ddeff083723e12a1d88c5868966bad928638ee43 Mon Sep 17 00:00:00 2001 From: Michael Winberry Date: Tue, 1 Mar 2022 14:35:20 -0800 Subject: [PATCH] #208, #351. UPDATE packager/validate: add the ValidateImportPackage method for use with compose.go. UPDATE packager/compose: add the hasValidSubPackage method and replaced the hasSubPackage calls. Updated the hasSubPackage method to validate only that the Component.Import field exists. Clean up index names in prepComponentToCompose. --- cli/internal/packager/compose.go | 43 ++++++++++++++-------- cli/internal/packager/validate/validate.go | 33 +++++++++++++++++ 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/cli/internal/packager/compose.go b/cli/internal/packager/compose.go index c1ada925b6..86530d6bbf 100644 --- a/cli/internal/packager/compose.go +++ b/cli/internal/packager/compose.go @@ -2,6 +2,8 @@ package packager import ( "github.com/defenseunicorns/zarf/cli/config" + "github.com/defenseunicorns/zarf/cli/internal/message" + "github.com/defenseunicorns/zarf/cli/internal/packager/validate" "github.com/defenseunicorns/zarf/cli/internal/utils" "github.com/defenseunicorns/zarf/cli/types" ) @@ -9,7 +11,7 @@ import ( func GetComposedAssets() (components []types.ZarfComponent) { for _, component := range config.GetComponents() { // Build components list by expanding imported components. - if hasSubPackage(&component) { + if hasValidSubPackage(&component) { importedComponents := getSubPackageAssets(component) components = append(components, importedComponents...) @@ -27,7 +29,7 @@ func GetComposedAssets() (components []types.ZarfComponent) { func getSubPackageAssets(importComponent types.ZarfComponent) (components []types.ZarfComponent) { importedPackage := getSubPackage(&importComponent) for _, componentToCompose := range importedPackage.Components { - if hasSubPackage(&componentToCompose) { + if hasValidSubPackage(&componentToCompose) { components = append(components, getSubPackageAssets(componentToCompose)...) } else { prepComponentToCompose(&componentToCompose, importedPackage.Metadata.Name, importComponent.Import.Path) @@ -39,12 +41,23 @@ func getSubPackageAssets(importComponent types.ZarfComponent) (components []type // Confirms inclusion of SubPackage. Need team input. func shouldAddImportedPackage(component *types.ZarfComponent) bool { - return hasSubPackage(component) && (component.Required || ConfirmOptionalComponent(*component)) + return hasValidSubPackage(component) && (component.Required || ConfirmOptionalComponent(*component)) } -// returns true if import has url +// Validates the sub component, errors out if validation fails. +func hasValidSubPackage(component *types.ZarfComponent) bool { + if !hasSubPackage(component) { + return false + } + if err := validate.ValidateImportPackage(component); err != nil { + message.Fatalf(err, "Invalid import definition in the %s component: %s", component.Name, err) + } + return true +} + +// returns true if import field is populated func hasSubPackage(component *types.ZarfComponent) bool { - return len(component.Import.Path) > 0 + return component.Import != types.ZarfImport{} } // Reads the locally imported zarf.yaml @@ -58,31 +71,31 @@ func prepComponentToCompose(component *types.ZarfComponent, parentPackageName st component.Name = parentPackageName + "-" + component.Name // Add import path to local component files. - for idx, file := range component.Files { + for fileIdx, file := range component.Files { if !utils.IsUrl(file.Source) { - component.Files[idx].Source = importPath + file.Source + component.Files[fileIdx].Source = importPath + file.Source } } // Add import path to local chart values files. - for chartIndex, chart := range component.Charts { - for valuesIndex, valuesFile := range chart.ValuesFiles { + for chartIdx, chart := range component.Charts { + for valuesIdx, valuesFile := range chart.ValuesFiles { if !utils.IsUrl(valuesFile) { - component.Charts[chartIndex].ValuesFiles[valuesIndex] = importPath + valuesFile + component.Charts[chartIdx].ValuesFiles[valuesIdx] = importPath + valuesFile } } } // Add import path to local manifest files and kustomizations - for manifestIndex, manifest := range component.Manifests { - for fileIndex, file := range manifest.Files { + for manifestIdx, manifest := range component.Manifests { + for fileIdx, file := range manifest.Files { if !utils.IsUrl(file) { - component.Manifests[manifestIndex].Files[fileIndex] = importPath + file + component.Manifests[manifestIdx].Files[fileIdx] = importPath + file } } - for kustomizationIndex, kustomization := range manifest.Kustomizations { + for kustomIdx, kustomization := range manifest.Kustomizations { if !utils.IsUrl(kustomization) { - component.Manifests[manifestIndex].Kustomizations[kustomizationIndex] = importPath + kustomization + component.Manifests[manifestIdx].Kustomizations[kustomIdx] = importPath + kustomization } } } diff --git a/cli/internal/packager/validate/validate.go b/cli/internal/packager/validate/validate.go index 4cacae99ab..cb3da64837 100644 --- a/cli/internal/packager/validate/validate.go +++ b/cli/internal/packager/validate/validate.go @@ -2,8 +2,11 @@ package validate import ( "fmt" + "strings" + "github.com/defenseunicorns/zarf/cli/config" "github.com/defenseunicorns/zarf/cli/internal/message" + "github.com/defenseunicorns/zarf/cli/internal/utils" "github.com/defenseunicorns/zarf/cli/types" ) @@ -81,3 +84,33 @@ func validateManifest(manifest types.ZarfManifest) error { return nil } + +func ValidateImportPackage(composedComponent *types.ZarfComponent) error { + intro := fmt.Sprintf("imported package %s", composedComponent.Name) + path := composedComponent.Import.Path + packageSuffix := "zarf.yaml" + + // ensure path exists + if !(len(path) > 0) { + return fmt.Errorf("%s must include a path", intro) + } + + // remove zarf.yaml from path if path has zarf.yaml suffix + if strings.HasSuffix(path, packageSuffix) { + path = strings.Split(path, packageSuffix)[0] + } + + // add a forward slash to end of path if it does not have one + if !strings.HasSuffix(path, "/") { + path = path + "/" + } + + // ensure there is a zarf.yaml in provided path + if utils.InvalidPath(path + packageSuffix) { + return fmt.Errorf("invalid file path \"%s\" provided directory must contain a valid zarf.yaml file", composedComponent.Import.Path) + } + + // replace component path with doctored path + composedComponent.Import.Path = path + return nil +}