Add proper mirror support (#74)

* Add rewrite support and fix existing tests

* Add unit tests for policy matching

* Compile regexes up front and store policies in map

* Add test for verify flow with mirror

* Rename ImageName -> ResolvedName

And only set it when necessary

* Rename Rewrite -> Replacement

but keep it as rewrite in the yaml
This commit is contained in:
Jonny Stoten
2024-07-12 17:09:41 +01:00
committed by GitHub
parent 247448a765
commit a4c3bd07fe
32 changed files with 619 additions and 225 deletions

View File

@@ -4,6 +4,7 @@ import (
"fmt"
"os"
"path/filepath"
"regexp"
"github.com/docker/attest/pkg/tuf"
goyaml "gopkg.in/yaml.v3"
@@ -17,7 +18,7 @@ func LoadLocalMappings(configDir string) (*PolicyMappings, error) {
if configDir == "" {
return nil, nil
}
mappings := &PolicyMappings{}
mappings := &policyMappingsFile{}
path := filepath.Join(configDir, MappingFilename)
mappingFile, err := os.ReadFile(path)
if err != nil {
@@ -27,7 +28,7 @@ func LoadLocalMappings(configDir string) (*PolicyMappings, error) {
if err != nil {
return nil, fmt.Errorf("failed to unmarshal policy mapping file %s: %w", path, err)
}
return mappings, nil
return expandMappingFile(mappings)
}
func LoadTufMappings(tufClient tuf.TUFClient, localTargetsDir string) (*PolicyMappings, error) {
@@ -39,11 +40,38 @@ func LoadTufMappings(tufClient tuf.TUFClient, localTargetsDir string) (*PolicyMa
if err != nil {
return nil, fmt.Errorf("failed to download policy mapping file %s: %w", filename, err)
}
mappings := &PolicyMappings{}
mappings := &policyMappingsFile{}
err = goyaml.Unmarshal(fileContents, mappings)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal policy mapping file %s: %w", filename, err)
}
return mappings, nil
return expandMappingFile(mappings)
}
func expandMappingFile(mappingFile *policyMappingsFile) (*PolicyMappings, error) {
policies := make(map[string]*PolicyMapping)
for _, policy := range mappingFile.Policies {
policies[policy.Id] = policy
}
var rules []*PolicyRule
for _, rule := range mappingFile.Rules {
r, err := regexp.Compile(rule.Pattern)
if err != nil {
return nil, err
}
rules = append(rules, &PolicyRule{
Pattern: r,
PolicyId: rule.PolicyId,
Replacement: rule.Replacement,
})
}
return &PolicyMappings{
Version: mappingFile.Version,
Kind: mappingFile.Kind,
Policies: policies,
Rules: rules,
}, nil
}

View File

@@ -1,10 +1,25 @@
package config
import "regexp"
type policyMappingsFile struct {
Version string `yaml:"version"`
Kind string `yaml:"kind"`
Policies []*PolicyMapping `yaml:"policies"`
Rules []*policyRuleFile `yaml:"rules"`
}
type policyRuleFile struct {
Pattern string `yaml:"pattern"`
PolicyId string `yaml:"policy-id"`
Replacement string `yaml:"rewrite"`
}
type PolicyMappings struct {
Version string `json:"version"`
Kind string `json:"kind"`
Policies []*PolicyMapping `json:"policies"`
Mirrors []*PolicyMirror `json:"mirrors"`
Version string
Kind string
Policies map[string]*PolicyMapping
Rules []*PolicyRule
}
type AttestationStyle string
@@ -15,34 +30,23 @@ const (
)
type PolicyMapping struct {
Id string `json:"id"`
Description string `json:"description"`
Origin *PolicyOrigin `json:"origin"`
Files []PolicyMappingFile `json:"files"`
Attestations *ReferrersConfig `json:"attestations"`
Id string `yaml:"id"`
Description string `yaml:"description"`
Files []PolicyMappingFile `yaml:"files"`
Attestations *AttestationConfig `yaml:"attestations"`
}
type ReferrersConfig struct {
Style AttestationStyle `json:"style"`
Repo string `json:"repo"`
type AttestationConfig struct {
Style AttestationStyle `yaml:"style"`
Repo string `yaml:"repo"`
}
type PolicyMappingFile struct {
Path string `json:"path"`
Path string `yaml:"path"`
}
type PolicyMirror struct {
PolicyId string `yaml:"policy-id"`
Mirror MirrorSpec `json:"mirror"`
}
type MirrorSpec struct {
Domains []string `json:"domains"`
Prefix string `json:"prefix"`
}
type PolicyOrigin struct {
Name string `json:"name"`
Prefix string `json:"prefix"`
Domain string `json:"domain"`
type PolicyRule struct {
Pattern *regexp.Regexp
PolicyId string
Replacement string
}