Skip to content

Commit

Permalink
move validate compose code to compose
Browse files Browse the repository at this point in the history
Signed-off-by: Austin Abro <[email protected]>
  • Loading branch information
AustinAbro321 committed Aug 12, 2024
1 parent a881426 commit 265df7c
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 134 deletions.
41 changes: 0 additions & 41 deletions src/pkg/lint/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ package lint
import (
"errors"
"fmt"
"path/filepath"
"regexp"
"strings"

"github.com/defenseunicorns/pkg/helpers/v2"
"github.com/zarf-dev/zarf/src/api/v1alpha1"
"k8s.io/apimachinery/pkg/util/validation"
)
Expand Down Expand Up @@ -64,7 +62,6 @@ const (
PkgValidateErrChartNamespaceMissing = "chart %q must include a namespace"
PkgValidateErrChartURLOrPath = "chart %q must have either a url or localPath"
PkgValidateErrChartVersion = "chart %q must include a chart version"
PkgValidateErrImportDefinition = "invalid imported definition for %s: %s"
PkgValidateErrManifestFileOrKustomize = "manifest %q must have at least one file or kustomization"
PkgValidateErrManifestNameLength = "manifest %q exceed the maximum length of %d characters"
PkgValidateErrVariable = "invalid package variable: %w"
Expand Down Expand Up @@ -101,9 +98,6 @@ func ValidatePackage(pkg v1alpha1.ZarfPackage) error {
}
}
for _, component := range pkg.Components {
if compErr := validateComponent(component); compErr != nil {
err = errors.Join(err, compErr)
}
// ensure component name is unique
if _, ok := uniqueComponentNames[component.Name]; ok {
err = errors.Join(err, fmt.Errorf(PkgValidateErrComponentNameNotUnique, component.Name))
Expand Down Expand Up @@ -182,41 +176,6 @@ func validateActions(a v1alpha1.ZarfComponentActions) error {
return err
}

// validateComponent validates the component trying to be imported.
func validateComponent(c v1alpha1.ZarfComponent) error {
var err error
path := c.Import.Path
url := c.Import.URL

// ensure path or url is provided
if path == "" && url == "" {
err = errors.Join(err, fmt.Errorf(PkgValidateErrImportDefinition, c.Name, "neither a path nor a URL was provided"))
}

// ensure path and url are not both provided
if path != "" && url != "" {
err = errors.Join(err, fmt.Errorf(PkgValidateErrImportDefinition, c.Name, "both a path and a URL were provided"))
}

// validation for path
if url == "" && path != "" {
// ensure path is not an absolute path
if filepath.IsAbs(path) {
err = errors.Join(err, fmt.Errorf(PkgValidateErrImportDefinition, c.Name, "path cannot be an absolute path"))
}
}

// validation for url
if url != "" && path == "" {
ok := helpers.IsOCIURL(url)
if !ok {
err = errors.Join(err, fmt.Errorf(PkgValidateErrImportDefinition, c.Name, "URL is not a valid OCI URL"))
}
}

return err
}

// hasSetVariables returns true if any of the actions contain setVariables.
func hasSetVariables(as v1alpha1.ZarfComponentActionSet) bool {
check := func(actions []v1alpha1.ZarfComponentAction) bool {
Expand Down
93 changes: 0 additions & 93 deletions src/pkg/lint/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package lint

import (
"fmt"
"path/filepath"
"strings"
"testing"

Expand Down Expand Up @@ -470,95 +469,3 @@ func TestValidateComponentAction(t *testing.T) {
})
}
}

func TestValidateZarfComponent(t *testing.T) {
t.Parallel()
absPath, err := filepath.Abs("abs")
require.NoError(t, err)
tests := []struct {
component v1alpha1.ZarfComponent
expectedErrs []string
name string
}{
{
name: "valid path",
component: v1alpha1.ZarfComponent{
Name: "component1",
Import: v1alpha1.ZarfComponentImport{
Path: "relative/path",
},
},
expectedErrs: nil,
},
{
name: "valid URL",
component: v1alpha1.ZarfComponent{
Name: "component2",
Import: v1alpha1.ZarfComponentImport{
URL: "oci://example.com/package:v0.0.1",
},
},
expectedErrs: nil,
},
{
name: "neither path nor URL provided",
component: v1alpha1.ZarfComponent{
Name: "neither",
},
expectedErrs: []string{
fmt.Sprintf(PkgValidateErrImportDefinition, "neither", "neither a path nor a URL was provided"),
},
},
{
name: "both path and URL provided",
component: v1alpha1.ZarfComponent{
Name: "both",
Import: v1alpha1.ZarfComponentImport{
Path: "relative/path",
URL: "https://example.com",
},
},
expectedErrs: []string{
fmt.Sprintf(PkgValidateErrImportDefinition, "both", "both a path and a URL were provided"),
},
},
{
name: "absolute path provided",
component: v1alpha1.ZarfComponent{
Name: "abs-path",
Import: v1alpha1.ZarfComponentImport{
Path: absPath,
},
},
expectedErrs: []string{
fmt.Sprintf(PkgValidateErrImportDefinition, "abs-path", "path cannot be an absolute path"),
},
},
{
name: "invalid URL provided",
component: v1alpha1.ZarfComponent{
Name: "bad-url",
Import: v1alpha1.ZarfComponentImport{
URL: "https://example.com",
},
},
expectedErrs: []string{
fmt.Sprintf(PkgValidateErrImportDefinition, "bad-url", "URL is not a valid OCI URL"),
},
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := validateComponent(tt.component)
if tt.expectedErrs == nil {
require.NoError(t, err)
return
}
errs := strings.Split(err.Error(), "\n")
require.ElementsMatch(t, tt.expectedErrs, errs)
})
}
}
38 changes: 38 additions & 0 deletions src/pkg/packager/composer/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package composer

import (
"context"
"errors"
"fmt"
"path/filepath"
"strings"
Expand Down Expand Up @@ -117,6 +118,43 @@ func (ic *ImportChain) append(c v1alpha1.ZarfComponent, index int, originalPacka
}
}

const pkgValidateErrImportDefinition = "invalid imported definition for %s: %s"

// validateComponentCompose validates that a component doesn't break compose rules
func validateComponentCompose(c v1alpha1.ZarfComponent) error {
var err error
path := c.Import.Path
url := c.Import.URL

// ensure path or url is provided
if path == "" && url == "" {
err = errors.Join(err, fmt.Errorf(pkgValidateErrImportDefinition, c.Name, "neither a path nor a URL was provided"))
}

// ensure path and url are not both provided
if path != "" && url != "" {
err = errors.Join(err, fmt.Errorf(pkgValidateErrImportDefinition, c.Name, "both a path and a URL were provided"))
}

// validation for path
if url == "" && path != "" {
// ensure path is not an absolute path
if filepath.IsAbs(path) {
err = errors.Join(err, fmt.Errorf(pkgValidateErrImportDefinition, c.Name, "path cannot be an absolute path"))
}
}

// validation for url
if url != "" && path == "" {
ok := helpers.IsOCIURL(url)
if !ok {
err = errors.Join(err, fmt.Errorf(pkgValidateErrImportDefinition, c.Name, "URL is not a valid OCI URL"))
}
}

return err
}

// NewImportChain creates a new import chain from a component
// Returning the chain on error so we can have additional information to use during lint
func NewImportChain(ctx context.Context, head v1alpha1.ZarfComponent, index int, originalPackageName, arch, flavor string) (*ImportChain, error) {
Expand Down
93 changes: 93 additions & 0 deletions src/pkg/packager/composer/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -540,3 +541,95 @@ func createDummyComponent(t *testing.T, name, importDir, subName string) v1alpha
},
}
}

func TestValidateZarfComponent(t *testing.T) {
t.Parallel()
absPath, err := filepath.Abs("abs")
require.NoError(t, err)
tests := []struct {
component v1alpha1.ZarfComponent
expectedErrs []string
name string
}{
{
name: "valid path",
component: v1alpha1.ZarfComponent{
Name: "component1",
Import: v1alpha1.ZarfComponentImport{
Path: "relative/path",
},
},
expectedErrs: nil,
},
{
name: "valid URL",
component: v1alpha1.ZarfComponent{
Name: "component2",
Import: v1alpha1.ZarfComponentImport{
URL: "oci://example.com/package:v0.0.1",
},
},
expectedErrs: nil,
},
{
name: "neither path nor URL provided",
component: v1alpha1.ZarfComponent{
Name: "neither",
},
expectedErrs: []string{
fmt.Sprintf(pkgValidateErrImportDefinition, "neither", "neither a path nor a URL was provided"),
},
},
{
name: "both path and URL provided",
component: v1alpha1.ZarfComponent{
Name: "both",
Import: v1alpha1.ZarfComponentImport{
Path: "relative/path",
URL: "https://example.com",
},
},
expectedErrs: []string{
fmt.Sprintf(pkgValidateErrImportDefinition, "both", "both a path and a URL were provided"),
},
},
{
name: "absolute path provided",
component: v1alpha1.ZarfComponent{
Name: "abs-path",
Import: v1alpha1.ZarfComponentImport{
Path: absPath,
},
},
expectedErrs: []string{
fmt.Sprintf(pkgValidateErrImportDefinition, "abs-path", "path cannot be an absolute path"),
},
},
{
name: "invalid URL provided",
component: v1alpha1.ZarfComponent{
Name: "bad-url",
Import: v1alpha1.ZarfComponentImport{
URL: "https://example.com",
},
},
expectedErrs: []string{
fmt.Sprintf(pkgValidateErrImportDefinition, "bad-url", "URL is not a valid OCI URL"),
},
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := validateComponentCompose(tt.component)
if tt.expectedErrs == nil {
require.NoError(t, err)
return
}
errs := strings.Split(err.Error(), "\n")
require.ElementsMatch(t, tt.expectedErrs, errs)
})
}
}

0 comments on commit 265df7c

Please sign in to comment.