Skip to content

Commit

Permalink
Migrated artifact registry into new validation framework
Browse files Browse the repository at this point in the history
  • Loading branch information
jdob committed Jan 18, 2024
1 parent 6d3902c commit 980a961
Show file tree
Hide file tree
Showing 6 changed files with 405 additions and 65 deletions.
6 changes: 5 additions & 1 deletion pkg/combustion/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ var haulerManifest string
var registryScript string

func configureRegistry(ctx *image.Context) ([]string, error) {
if image.IsEmbeddedArtifactRegistryEmpty(ctx.ImageDefinition.EmbeddedArtifactRegistry) {
if IsEmbeddedArtifactRegistryEmpty(ctx.ImageDefinition.EmbeddedArtifactRegistry) {
log.AuditComponentSkipped(registryComponentName)
return nil, nil
}
Expand Down Expand Up @@ -172,3 +172,7 @@ func createRegistryCommand(ctx *image.Context, commandName string, args []string

return cmd, logFile, nil
}

func IsEmbeddedArtifactRegistryEmpty(registry image.EmbeddedArtifactRegistry) bool {
return len(registry.HelmCharts) == 0 && len(registry.ContainerImages) == 0
}
64 changes: 64 additions & 0 deletions pkg/combustion/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,67 @@ func TestCopyHaulerBinaryNoFile(t *testing.T) {
// Verify
require.ErrorContains(t, err, "no such file")
}

func TestIsEmbeddedArtifactRegistryEmpty(t *testing.T) {
tests := []struct {
name string
registry image.EmbeddedArtifactRegistry
isEmpty bool
}{
{
name: "Both Defined",
registry: image.EmbeddedArtifactRegistry{
HelmCharts: []image.HelmChart{
{
Name: "rancher",
RepoURL: "https://releases.rancher.com/server-charts/stable",
Version: "2.8.0",
},
},
ContainerImages: []image.ContainerImage{
{
Name: "hello-world:latest",
SupplyChainKey: "",
},
},
},
isEmpty: false,
},
{
name: "Chart Defined",
registry: image.EmbeddedArtifactRegistry{
HelmCharts: []image.HelmChart{
{
Name: "rancher",
RepoURL: "https://releases.rancher.com/server-charts/stable",
Version: "2.8.0",
},
},
},
isEmpty: false,
},
{
name: "Image Defined",
registry: image.EmbeddedArtifactRegistry{
ContainerImages: []image.ContainerImage{
{
Name: "hello-world:latest",
SupplyChainKey: "",
},
},
},
isEmpty: false,
},
{
name: "None Defined",
isEmpty: true,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
result := IsEmbeddedArtifactRegistryEmpty(test.registry)
assert.Equal(t, test.isEmpty, result)
})
}
}
97 changes: 97 additions & 0 deletions pkg/image/validation/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package validation

import (
"fmt"
"strings"

"github.com/suse-edge/edge-image-builder/pkg/combustion"
"github.com/suse-edge/edge-image-builder/pkg/image"
)

const (
registryComponent = "Artifact Registry"
)

func validateEmbeddedArtefactRegistry(ctx *image.Context) []FailedValidation {
var failures []FailedValidation
def := ctx.ImageDefinition

if combustion.IsEmbeddedArtifactRegistryEmpty(def.EmbeddedArtifactRegistry) {
return failures
}

failures = append(failures, validateContainerImages(&ctx.ImageDefinition.EmbeddedArtifactRegistry)...)
failures = append(failures, validateHelmCharts(&ctx.ImageDefinition.EmbeddedArtifactRegistry)...)

return failures
}

func validateContainerImages(ear *image.EmbeddedArtifactRegistry) []FailedValidation {
var failures []FailedValidation

seenContainerImages := make(map[string]bool)
for _, cImage := range ear.ContainerImages {
if cImage.Name == "" {
failures = append(failures, FailedValidation{
userMessage: "The 'name' field is required for each entry in 'images'.",
component: registryComponent,
})
}

if seenContainerImages[cImage.Name] {
msg := fmt.Sprintf("Duplicate image name '%s' found in the 'images' section.", cImage.Name)
failures = append(failures, FailedValidation{
userMessage: msg,
component: registryComponent,
})
}
seenContainerImages[cImage.Name] = true
}

return failures
}

func validateHelmCharts(ear *image.EmbeddedArtifactRegistry) []FailedValidation {
var failures []FailedValidation

charts := ear.HelmCharts
seenCharts := make(map[string]bool)
for _, chart := range charts {
if chart.Name == "" {
failures = append(failures, FailedValidation{
userMessage: "The 'name' field is required for each entry in 'charts'.",
component: registryComponent,
})
}

if chart.RepoURL == "" {
failures = append(failures, FailedValidation{
userMessage: "The 'repoURL' field is required for each entry in 'charts'.",
component: registryComponent,
})
} else if !strings.HasPrefix(chart.RepoURL, "http") {
failures = append(failures, FailedValidation{
userMessage: "The 'repoURL' field must begin with either 'http://' or 'https://'.",
component: registryComponent,
})
}

if chart.Version == "" {
failures = append(failures, FailedValidation{
userMessage: "The 'version' field is required for each entry in 'charts'.",
component: registryComponent,
})
}

if seenCharts[chart.Name] {
msg := fmt.Sprintf("Duplicate chart name '%s' found in the 'charts' section.", chart.Name)
failures = append(failures, FailedValidation{
userMessage: msg,
component: registryComponent,
})
}
seenCharts[chart.Name] = true
}

return failures
}
Loading

0 comments on commit 980a961

Please sign in to comment.