Skip to content

Commit

Permalink
config validation with rego
Browse files Browse the repository at this point in the history
  • Loading branch information
malt3 committed Oct 6, 2023
1 parent 5fc8370 commit 01543b0
Show file tree
Hide file tree
Showing 7 changed files with 825 additions and 63 deletions.
10 changes: 5 additions & 5 deletions azure/uploader.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ func (u *Uploader) ensureManagedImageDeleted(ctx context.Context) error {
// ensureSIG creates a SIG if it does not exist yet.
func (u *Uploader) ensureSIG(ctx context.Context) error {
rg := u.config.Azure.ResourceGroup
sigName := u.config.Azure.SharedImageGalleryName
sigName := u.config.Azure.SharedImageGallery
pubNamePrefix := u.config.Azure.SharingNamePrefix
sharingProf := sharingProfilePermissionFromString(u.config.Azure.SharingProfile)

Expand Down Expand Up @@ -406,7 +406,7 @@ func sharingProfilePermissionFromString(s string) *armcomputev5.GallerySharingPe
// ensureImageDefinition creates an image definition (component of a SIG) if it does not exist yet.
func (u *Uploader) ensureImageDefinition(ctx context.Context) error {
rg := u.config.Azure.ResourceGroup
sigName := u.config.Azure.SharedImageGalleryName
sigName := u.config.Azure.SharedImageGallery
attestVariant := u.config.Azure.AttestationVariant
defName := u.config.Azure.ImageDefinitionName

Expand Down Expand Up @@ -459,7 +459,7 @@ func (u *Uploader) ensureImageDefinition(ctx context.Context) error {

func (u *Uploader) createImageVersion(ctx context.Context, imageID string) (string, error) {
rg := u.config.Azure.ResourceGroup
sigName := u.config.Azure.SharedImageGalleryName
sigName := u.config.Azure.SharedImageGallery
verName := u.config.ImageVersion
defName := u.config.Azure.ImageDefinitionName

Expand Down Expand Up @@ -500,7 +500,7 @@ func (u *Uploader) createImageVersion(ctx context.Context, imageID string) (stri

func (u *Uploader) ensureImageVersionDeleted(ctx context.Context) error {
rg := u.config.Azure.ResourceGroup
sigName := u.config.Azure.SharedImageGalleryName
sigName := u.config.Azure.SharedImageGallery
verName := u.config.ImageVersion
defName := u.config.Azure.ImageDefinitionName

Expand Down Expand Up @@ -529,7 +529,7 @@ func (u *Uploader) ensureImageVersionDeleted(ctx context.Context) error {
func (u *Uploader) getImageReference(ctx context.Context, unsharedID string) (string, error) {
rg := u.config.Azure.ResourceGroup
location := u.config.Azure.Location
sigName := u.config.Azure.SharedImageGalleryName
sigName := u.config.Azure.SharedImageGallery
verName := u.config.ImageVersion
defName := u.config.Azure.ImageDefinitionName

Expand Down
82 changes: 56 additions & 26 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ SPDX-License-Identifier: Apache-2.0
package config

import (
"context"
"errors"
"fmt"
"html/template"
Expand All @@ -16,7 +17,6 @@ import (
uplositemplate "github.com/edgelesssys/uplosi/template"

"dario.cat/mergo"
"golang.org/x/mod/semver"
)

var defaultConfig = Config{
Expand Down Expand Up @@ -63,19 +63,6 @@ func (c *Config) SetDefaults() error {
return mergo.Merge(c, defaultConfig, mergo.WithTransformers(&OptionTransformer{}))
}

func (c *Config) Validate() error {
if len(c.Provider) == 0 {
return errors.New("provider must be set")
}
if !semver.IsValid("v" + c.ImageVersion) {
return errors.New("imageVersion must be of the form MAJOR.MINOR.PATCH")
}
if len(c.Name) == 0 {
return errors.New("name must be set")
}
return nil
}

// Render renders the config by evaluating the version file and all template strings.
func (c *Config) Render(fileLookup func(name string) ([]byte, error)) error {
if err := c.renderVersion(fileLookup); err != nil {
Expand All @@ -95,6 +82,12 @@ func (c *Config) Render(fileLookup func(name string) ([]byte, error)) error {
return err
}

v := Validator{}

if err := v.Validate(context.TODO(), *c); err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -180,18 +173,18 @@ type AWSConfig struct {
}

type AzureConfig struct {
SubscriptionID string `toml:"subscriptionID,omitempty"`
Location string `toml:"location,omitempty"`
ResourceGroup string `toml:"resourceGroup,omitempty" template:"true"`
AttestationVariant string `toml:"attestationVariant,omitempty" template:"true"`
SharedImageGalleryName string `toml:"sharedImageGallery,omitempty" template:"true"`
SharingProfile string `toml:"sharingProfile,omitempty" template:"true"`
SharingNamePrefix string `toml:"sharingNamePrefix,omitempty" template:"true"`
ImageDefinitionName string `toml:"imageDefinitionName,omitempty" template:"true"`
Offer string `toml:"offer,omitempty" template:"true"`
SKU string `toml:"sku,omitempty" template:"true"`
Publisher string `toml:"publisher,omitempty" template:"true"`
DiskName string `toml:"diskName,omitempty" template:"true"`
SubscriptionID string `toml:"subscriptionID,omitempty"`
Location string `toml:"location,omitempty"`
ResourceGroup string `toml:"resourceGroup,omitempty" template:"true"`
AttestationVariant string `toml:"attestationVariant,omitempty" template:"true"`
SharedImageGallery string `toml:"sharedImageGallery,omitempty" template:"true"`
SharingProfile string `toml:"sharingProfile,omitempty" template:"true"`
SharingNamePrefix string `toml:"sharingNamePrefix,omitempty" template:"true"`
ImageDefinitionName string `toml:"imageDefinitionName,omitempty" template:"true"`
Offer string `toml:"offer,omitempty" template:"true"`
SKU string `toml:"sku,omitempty" template:"true"`
Publisher string `toml:"publisher,omitempty" template:"true"`
DiskName string `toml:"diskName,omitempty" template:"true"`
}

type GCPConfig struct {
Expand Down Expand Up @@ -254,7 +247,44 @@ func (c *ConfigFile) RenderedVariant(fileLookup fileLookupFn, name string) (Conf
return out, nil
}

func (c *ConfigFile) validateAll(fileLookup fileLookupFn, filters ...variantFilter) error {
var errs error
if len(c.Variants) == 0 {
_, err := c.RenderedVariant(fileLookup, "")
if err != nil {
return fmt.Errorf("validating config: %w", err)
}
}

variantNames := make([]string, 0, len(c.Variants))
for name := range c.Variants {
var filtered bool
for _, filter := range filters {
if !filter(name) {
filtered = true
break
}
}
if filtered {
continue
}
variantNames = append(variantNames, name)
}
slices.Sort(variantNames)
for _, name := range variantNames {
_, err := c.RenderedVariant(fileLookup, name)
if err != nil {
errs = errors.Join(errs, fmt.Errorf("config for variant %s: %w", name, err))
}
}
return errs
}

func (c *ConfigFile) ForEach(fn func(name string, cfg Config) error, fileLookup fileLookupFn, filters ...variantFilter) error {
if err := c.validateAll(fileLookup, filters...); err != nil {
return err
}

if len(c.Variants) == 0 {
cfg, err := c.RenderedVariant(fileLookup, "")
if err != nil {
Expand Down
35 changes: 19 additions & 16 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,27 @@ func TestConfigRenderVersionFromFile(t *testing.T) {
lookup := stubFileLookup{
"image-version.txt": []byte("0.0.2"),
}
config := Config{
config := fullConfig()
assert.NoError(config.Merge(Config{
Name: "test",
ImageVersion: "0.0.1", // this will be overwritten by the file
ImageVersionFile: "image-version.txt",
}
}))
assert.NoError(config.Render(lookup.Lookup))
assert.Equal("0.0.2", config.ImageVersion)
}

func TestConfigRenderTemplate(t *testing.T) {
assert := assert.New(t)
lookup := stubFileLookup{}
config := Config{
config := fullConfig()
assert.NoError(config.Merge(Config{
Name: "name",
ImageVersion: "0.0.1",
GCP: GCPConfig{
ImageName: "prefix-{{.Name}}-{{replaceAll .Version \".\" \"-\"}}-suffix",
},
}
}))
assert.NoError(config.Render(lookup.Lookup))
assert.Equal("prefix-name-0-0-1-suffix", config.GCP.ImageName)
}
Expand Down Expand Up @@ -144,6 +146,7 @@ func (s stubFileLookup) Lookup(name string) ([]byte, error) {

func fullConfig() Config {
return Config{
Provider: "aws",
ImageVersion: "0.0.1",
Name: "test",
AWS: AWSConfig{
Expand All @@ -157,18 +160,18 @@ func fullConfig() Config {
Publish: Some[bool](true),
},
Azure: AzureConfig{
SubscriptionID: "subscription-id",
Location: "location",
ResourceGroup: "resource-group",
AttestationVariant: "attestation-variant",
SharedImageGalleryName: "shared-image-gallery",
SharingProfile: "sharing-profile",
SharingNamePrefix: "sharing-name-prefix",
ImageDefinitionName: "image-definition-name-template",
Offer: "offer",
SKU: "sku",
Publisher: "publisher",
DiskName: "disk-name",
SubscriptionID: "subscription-id",
Location: "location",
ResourceGroup: "resource-group",
AttestationVariant: "attestation-variant",
SharedImageGallery: "shared-image-gallery",
SharingProfile: "sharing-profile",
SharingNamePrefix: "sharing-name-prefix",
ImageDefinitionName: "image-definition-name-template",
Offer: "offer",
SKU: "sku",
Publisher: "publisher",
DiskName: "disk-name",
},
GCP: GCPConfig{
Project: "project",
Expand Down
1 change: 0 additions & 1 deletion config/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ func (v *Validator) Validate(ctx context.Context, config Config) error {
if err != nil {
return fmt.Errorf("evaluating policy: %w", err)
}
fmt.Println(res)

var resErr error
for _, result := range res {
Expand Down
Loading

0 comments on commit 01543b0

Please sign in to comment.