Skip to content

Commit

Permalink
use regex for selecting files and improve config structure
Browse files Browse the repository at this point in the history
  • Loading branch information
choffmeister committed Nov 12, 2021
1 parent ea9f9b9 commit 3ebf7a6
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 209 deletions.
5 changes: 2 additions & 3 deletions example/.git-ops-update.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
files:
includes:
- '*.yaml'
- '\.yaml$'
excludes:
- '.git-ops-update.yaml'
- '.git-ops-update.cache.yaml'
- '.git-ops-update(\.cache)?\.yaml$'
registries:
docker:
interval: 1h
Expand Down
126 changes: 103 additions & 23 deletions internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,81 @@ import (
"io/ioutil"
"regexp"

"github.com/google/go-cmp/cmp"
utilyaml "k8s.io/apimachinery/pkg/util/yaml"
)

type GitOpsUpdaterConfigFiles struct {
type GitOpsUpdaterConfigRawHttpCredentials struct {
Username string `json:"username"`
Password string `json:"password"`
}

type GitOpsUpdaterConfigRawFiles struct {
Includes []string `json:"includes"`
Excludes []string `json:"excludes"`
}

type GitOpsUpdaterConfigRawRegistryDocker struct {
Url string `json:"url"`
Credentials GitOpsUpdaterConfigRawHttpCredentials `json:"credentials"`
}

type GitOpsUpdaterConfigRawRegistryHelm struct {
Url string `json:"url"`
Credentials GitOpsUpdaterConfigRawHttpCredentials `json:"credentials"`
}

type GitOpsUpdaterConfigRawRegistry struct {
Interval Duration `json:"interval"`
Docker *GitOpsUpdaterConfigRawRegistryDocker `json:"docker"`
Helm *GitOpsUpdaterConfigRawRegistryHelm `json:"helm"`
}

type GitOpsUpdaterConfigRawPolicyExtractLexicographicStrategy struct {
Pin bool `json:"pin"`
}

type GitOpsUpdaterConfigRawPolicyExtractNumericStrategyConfig struct {
Pin bool `json:"pin"`
}

type GitOpsUpdaterConfigRawPolicyExtractSemverStrategy struct {
PinMajor bool `json:"pinMajor"`
PinMinor bool `json:"pinMinor"`
PinPatch bool `json:"pinPatch"`
AllowPrereleases bool `json:"allowPrereleases"`
}

type GitOpsUpdaterConfigRawPolicyExtract struct {
Value string `json:"value"`
Lexicographic *GitOpsUpdaterConfigRawPolicyExtractLexicographicStrategy `json:"lexicographic"`
Numeric *GitOpsUpdaterConfigRawPolicyExtractNumericStrategyConfig `json:"numeric"`
Semver *GitOpsUpdaterConfigRawPolicyExtractSemverStrategy `json:"semver"`
}

type GitOpsUpdaterConfigRawPolicy struct {
Pattern string `json:"pattern"`
Extracts []GitOpsUpdaterConfigRawPolicyExtract `json:"extracts"`
}

type GitOpsUpdaterConfigRaw struct {
Files GitOpsUpdaterConfigRawFiles `json:"files"`
Registries map[string]GitOpsUpdaterConfigRawRegistry `json:"registries"`
Policies map[string]GitOpsUpdaterConfigRawPolicy `json:"policies"`
}

type GitOpsUpdaterConfigFiles struct {
Includes []regexp.Regexp
Excludes []regexp.Regexp
}

type GitOpsUpdaterConfig struct {
Files GitOpsUpdaterConfigFiles `json:"files"`
RegistryConfigs map[string]RegistryConfig `json:"registries"`
PolicyConfigs map[string]PolicyConfig `json:"policies"`
Registries map[string]Registry
Policies map[string]Policy
Files GitOpsUpdaterConfigFiles
Registries map[string]Registry
Policies map[string]Policy
}

func LoadGitOpsUpdaterConfig(yaml []byte) (*GitOpsUpdaterConfig, error) {
config := &GitOpsUpdaterConfig{}
config := &GitOpsUpdaterConfigRaw{}

json, err := utilyaml.ToJSON(yaml)
if err != nil {
Expand All @@ -35,25 +91,51 @@ func LoadGitOpsUpdaterConfig(yaml []byte) (*GitOpsUpdaterConfig, error) {
return nil, err
}

fileIncludes := []regexp.Regexp{}
for _, i := range config.Files.Includes {
regex, err := regexp.Compile(i)
if err != nil {
return nil, err
}
fileIncludes = append(fileIncludes, *regex)
}

fileExcludes := []regexp.Regexp{}
for _, e := range config.Files.Excludes {
regex, err := regexp.Compile(e)
if err != nil {
return nil, err
}
fileExcludes = append(fileExcludes, *regex)
}

registries := map[string]Registry{}
for rn, r := range config.RegistryConfigs {
for rn, r := range config.Registries {
if r.Docker != nil {
registries[rn] = DockerRegistry{
Interval: r.Interval,
Config: r.Docker,
Url: r.Docker.Url,
Credentials: HttpBasicCredentials{
Username: r.Docker.Credentials.Username,
Password: r.Docker.Credentials.Password,
},
}
} else if r.Helm != nil {
registries[rn] = HelmRegistry{
Interval: r.Interval,
Config: r.Helm,
Url: r.Helm.Url,
Credentials: HttpBasicCredentials{
Username: r.Helm.Credentials.Username,
Password: r.Helm.Credentials.Password,
},
}
} else {
return nil, fmt.Errorf("registry %s is invalid", rn)
}
}

policies := map[string]Policy{}
for pn, p := range config.PolicyConfigs {
for pn, p := range config.Policies {
extracts := []Extract{}
for ei, e := range p.Extracts {
if e.Lexicographic != nil {
Expand Down Expand Up @@ -82,11 +164,16 @@ func LoadGitOpsUpdaterConfig(yaml []byte) (*GitOpsUpdaterConfig, error) {
}
}

config.Registries = registries
config.Policies = policies

return config, nil
return &GitOpsUpdaterConfig{
Files: GitOpsUpdaterConfigFiles{
Includes: fileIncludes,
Excludes: fileExcludes,
},
Registries: registries,
Policies: policies,
}, nil
}

func LoadGitOpsUpdaterConfigFromFile(file string) (*GitOpsUpdaterConfig, error) {
configRaw, err := ioutil.ReadFile(file)
if err != nil {
Expand All @@ -98,10 +185,3 @@ func LoadGitOpsUpdaterConfigFromFile(file string) (*GitOpsUpdaterConfig, error)
}
return config, nil
}

func (c1 GitOpsUpdaterConfig) Equal(c2 GitOpsUpdaterConfig) bool {
return true &&
cmp.Equal(c1.Files, c2.Files) &&
cmp.Equal(c1.RegistryConfigs, c2.RegistryConfigs) &&
cmp.Equal(c1.PolicyConfigs, c2.PolicyConfigs)
}
97 changes: 34 additions & 63 deletions internal/config_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package internal

import (
"regexp"
"testing"

"github.com/stretchr/testify/assert"
)

func TestLoadGitOpsUpdaterConfig(t *testing.T) {
Expand All @@ -11,9 +14,9 @@ func TestLoadGitOpsUpdaterConfig(t *testing.T) {
password: pass
files:
includes:
- '**/*.yaml'
- '\.yaml$'
excludes:
- '**/*.generated.yaml'
- '\.generated\.yaml$'
registries:
docker:
interval: 1m
Expand Down Expand Up @@ -50,90 +53,58 @@ policies:
}
c2 := GitOpsUpdaterConfig{
Files: GitOpsUpdaterConfigFiles{
Includes: []string{"**/*.yaml"},
Excludes: []string{"**/*.generated.yaml"},
Includes: []regexp.Regexp{*regexp.MustCompile(`\.yaml$`)},
Excludes: []regexp.Regexp{*regexp.MustCompile(`\.generated\.yaml$`)},
},
RegistryConfigs: map[string]RegistryConfig{
"docker": {
Registries: map[string]Registry{
"docker": DockerRegistry{
Interval: Duration(60000000000),
Docker: &RegistryConfigDocker{
Url: "https://registry-1.docker.io",
Credentials: HttpBasicCredentials{
Username: "user",
Password: "pass",
},
Url: "https://registry-1.docker.io",
Credentials: HttpBasicCredentials{
Username: "user",
Password: "pass",
},
},
"helm": {
"helm": HelmRegistry{
Interval: Duration(3600000000000),
Helm: &RegistryConfigHelm{
Url: "https://charts.helm.sh/stable",
Credentials: HttpBasicCredentials{
Username: "user",
Password: "pass",
},
Url: "https://charts.helm.sh/stable",
Credentials: HttpBasicCredentials{
Username: "user",
Password: "pass",
},
},
},
PolicyConfigs: map[string]PolicyConfig{
Policies: map[string]Policy{
"lexicographic": {
Pattern: "^(?P<all>.*)$",
Extracts: []ExtractConfig{
Pattern: regexp.MustCompile(`^(?P<all>.*)$`),
Extracts: []Extract{
{
Value: "<all>",
Lexicographic: &LexicographicExtractStrategyConfig{},
Value: "<all>",
Strategy: LexicographicExtractStrategy{},
},
},
},
"numeric": {
Pattern: "^(?P<all>.*)$",
Extracts: []ExtractConfig{
Pattern: regexp.MustCompile(`^(?P<all>.*)$`),
Extracts: []Extract{
{
Value: "<all>",
Numeric: &NumericExtractStrategyConfig{},
Value: "<all>",
Strategy: NumericExtractStrategy{},
},
},
},
"semver": {
Pattern: "^(?P<all>.*)$",
Extracts: []ExtractConfig{
Pattern: regexp.MustCompile(`^(?P<all>.*)$`),
Extracts: []Extract{
{
Value: "<all>",
Semver: &SemverExtractStrategyConfig{},
Value: "<all>",
Strategy: SemverExtractStrategy{},
},
},
},
},
}
if !c1.Equal(c2) {
t.Errorf("expected %v, got %v", c2, c1)
return
}

ok := false
_, ok = c1.Registries["docker"].(DockerRegistry)
if !ok {
t.Errorf("expected DockerRegistry, got %v", c1.Registries["docker"])
return
}
_, ok = c1.Registries["helm"].(HelmRegistry)
if !ok {
t.Errorf("expected HelmRegistry, got %v", c1.Registries["helm"])
return
}
_, ok = c1.Policies["lexicographic"].Extracts[0].Strategy.(LexicographicExtractStrategy)
if !ok {
t.Errorf("expected LexicographicExtractStrategy, got %v", c1.Policies["lexicographic"].Extracts[0].Strategy)
return
}
_, ok = c1.Policies["numeric"].Extracts[0].Strategy.(NumericExtractStrategy)
if !ok {
t.Errorf("expected NumericExtractStrategy, got %v", c1.Policies["numeric"].Extracts[0].Strategy)
return
}
_, ok = c1.Policies["semver"].Extracts[0].Strategy.(SemverExtractStrategy)
if !ok {
t.Errorf("expected SemverExtractStrategy, got %v", c1.Policies["semver"].Extracts[0].Strategy)
return
}
assert.Equal(t, c1.Files, c2.Files)
assert.Equal(t, c1.Registries, c2.Registries)
assert.Equal(t, c1.Policies, c2.Policies)
}
36 changes: 7 additions & 29 deletions internal/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,6 @@ import (
"github.com/blang/semver/v4"
)

type LexicographicExtractStrategyConfig struct{}

type NumericExtractStrategyConfig struct{}

type SemverExtractStrategyConfig struct {
PinMajor bool `json:"pinMajor"`
PinMinor bool `json:"pinMinor"`
PinPatch bool `json:"pinPatch"`
AllowPrereleases bool `json:"allowPrereleases"`
}

type ExtractConfig struct {
Value string `json:"value"`
Lexicographic *LexicographicExtractStrategyConfig `json:"lexicographic"`
Numeric *NumericExtractStrategyConfig `json:"numeric"`
Semver *SemverExtractStrategyConfig `json:"semver"`
}

type PolicyConfig struct {
Pattern string `json:"pattern"`
Extracts []ExtractConfig `json:"extracts"`
}

type Policy struct {
Pattern *regexp.Regexp
Extracts []Extract
Expand All @@ -49,15 +26,16 @@ type ExtractStrategy interface {
}

type LexicographicExtractStrategy struct {
Config LexicographicExtractStrategyConfig
}

type NumericExtractStrategy struct {
Config NumericExtractStrategyConfig
}

type SemverExtractStrategy struct {
Config SemverExtractStrategyConfig
PinMajor bool
PinMinor bool
PinPatch bool
AllowPrereleases bool
}

var extractPattern = regexp.MustCompile(`<([a-zA-Z0-9\-]+)>`)
Expand Down Expand Up @@ -222,13 +200,13 @@ func (str SemverExtractStrategy) Compare(v1 string, v2 string) int {
func (str SemverExtractStrategy) IsCompatible(v1 string, v2 string) bool {
v1sv, _ := semver.Make(v1)
v2sv, _ := semver.Make(v2)
if str.Config.PinMajor && v1sv.Major != v2sv.Major {
if str.PinMajor && v1sv.Major != v2sv.Major {
return false
}
if str.Config.PinMinor && (v1sv.Major != v2sv.Major || v1sv.Minor != v2sv.Minor) {
if str.PinMinor && (v1sv.Major != v2sv.Major || v1sv.Minor != v2sv.Minor) {
return false
}
if str.Config.PinPatch && (v1sv.Major != v2sv.Major || v1sv.Minor != v2sv.Minor || v1sv.Patch != v2sv.Patch) {
if str.PinPatch && (v1sv.Major != v2sv.Major || v1sv.Minor != v2sv.Minor || v1sv.Patch != v2sv.Patch) {
return false
}
return true
Expand Down
Loading

0 comments on commit 3ebf7a6

Please sign in to comment.