feat: add extends option

This commit is contained in:
Kevin Franklin Kim 2024-10-22 16:14:31 +02:00
parent 3548f9afc6
commit 10e19dcae3
No known key found for this signature in database
38 changed files with 89 additions and 46 deletions

View File

@ -17,7 +17,7 @@ Configure your squadron
```yaml ```yaml
# https://raw.githubusercontent.com/foomo/squadron/refs/heads/main/squadron.schema.json # https://raw.githubusercontent.com/foomo/squadron/refs/heads/main/squadron.schema.json
version: '2.1' version: '2.2'
# squadron template vars # squadron template vars
vars: {} vars: {}

View File

@ -1,4 +1,4 @@
version: '2.1' version: '2.2'
squadron: squadron:
storefinder: storefinder:

View File

@ -1,4 +1,4 @@
version: '2.1' version: '2.2'
squadron: squadron:
storefinder: storefinder:

View File

@ -1,5 +1,5 @@
# Schema version # Schema version
version: '2.1' version: '2.2'
squadron: squadron:
checkout: checkout:

View File

@ -1,5 +1,5 @@
# Schema version # Schema version
version: '2.1' version: '2.2'
squadron: squadron:
checkout: checkout:

View File

@ -1,4 +1,4 @@
version: '2.1' version: '2.2'
global: global:
docker: docker:

View File

@ -1,5 +1,5 @@
# Schema version # Schema version
version: '2.1' version: '2.2'
squadron: squadron:
storefinder: storefinder:

View File

@ -1,5 +1,5 @@
# Schema version # Schema version
version: '2.1' version: '2.2'
squadron: squadron:
storefinder: storefinder:

2
go.mod
View File

@ -5,6 +5,7 @@ go 1.23.2
replace github.com/miracl/conflate v1.2.1 => github.com/runz0rd/conflate v1.2.2-0.20210920145208-fa48576ef06d replace github.com/miracl/conflate v1.2.1 => github.com/runz0rd/conflate v1.2.2-0.20210920145208-fa48576ef06d
require ( require (
dario.cat/mergo v1.0.1
github.com/1Password/connect-sdk-go v1.5.3 github.com/1Password/connect-sdk-go v1.5.3
github.com/BurntSushi/toml v1.4.0 github.com/BurntSushi/toml v1.4.0
github.com/Masterminds/sprig/v3 v3.3.0 github.com/Masterminds/sprig/v3 v3.3.0
@ -29,7 +30,6 @@ require (
atomicgo.dev/cursor v0.2.0 // indirect atomicgo.dev/cursor v0.2.0 // indirect
atomicgo.dev/keyboard v0.2.9 // indirect atomicgo.dev/keyboard v0.2.9 // indirect
atomicgo.dev/schedule v0.1.0 // indirect atomicgo.dev/schedule v0.1.0 // indirect
dario.cat/mergo v1.0.1 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.3.0 // indirect github.com/Masterminds/semver/v3 v3.3.0 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect

View File

@ -35,21 +35,26 @@ func (d *Chart) UnmarshalYAML(value *yaml.Node) error {
if err := value.Decode(&vString); err != nil { if err := value.Decode(&vString); err != nil {
return err return err
} }
vBytes, err := template.ExecuteFileTemplate(context.Background(), vString, nil, true) vBytes, err := template.ExecuteFileTemplate(context.Background(), vString, nil, true)
if err != nil { if err != nil {
return errors.Wrap(err, "failed to render chart string") return errors.Wrap(err, "failed to render chart string")
} }
localChart, err := loadChart(path.Join(string(vBytes), "Chart.yaml")) localChart, err := loadChart(path.Join(string(vBytes), "Chart.yaml"))
if err != nil { if err != nil {
return errors.New("failed to load local chart: " + vString) return errors.New("failed to load local chart: " + vString)
} }
d.Name = localChart.Name d.Name = localChart.Name
d.Repository = fmt.Sprintf("file://%v", vString) d.Repository = fmt.Sprintf("file://%v", vString)
d.Version = localChart.Version d.Version = localChart.Version
wd, err := os.Getwd() wd, err := os.Getwd()
if err != nil { if err != nil {
return errors.Wrap(err, "failed to get working directory") return errors.Wrap(err, "failed to get working directory")
} }
schemaPath := string(vBytes) schemaPath := string(vBytes)
if value, err := filepath.Rel(wd, string(vBytes)); err == nil { if value, err := filepath.Rel(wd, string(vBytes)); err == nil {
schemaPath = value schemaPath = value

View File

@ -4,13 +4,17 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "fmt"
"os"
"path" "path"
"sort" "sort"
"strings" "strings"
"dario.cat/mergo"
"github.com/foomo/squadron/internal/template"
"github.com/foomo/squadron/internal/util" "github.com/foomo/squadron/internal/util"
"github.com/pkg/errors" "github.com/pkg/errors"
yamlv2 "gopkg.in/yaml.v2" yamlv2 "gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
) )
type Unit struct { type Unit struct {
@ -24,12 +28,46 @@ type Unit struct {
Builds map[string]Build `json:"builds,omitempty" yaml:"builds,omitempty"` Builds map[string]Build `json:"builds,omitempty" yaml:"builds,omitempty"`
// Chart values // Chart values
Values map[string]any `json:"values,omitempty" yaml:"values,omitempty"` Values map[string]any `json:"values,omitempty" yaml:"values,omitempty"`
// Extend chart values
Extends string `json:"extends,omitempty" yaml:"extends,omitempty"`
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// ~ Public methods // ~ Public methods
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
func (u *Unit) UnmarshalYAML(value *yaml.Node) error {
type wrapper Unit
if err := value.Decode((*wrapper)(u)); err != nil {
return err
}
if u.Extends != "" {
// render filename
filename, err := template.ExecuteFileTemplate(context.Background(), u.Extends, nil, true)
if err != nil {
return errors.Wrap(err, "failed to render defaults filename")
}
// read defaults
defaults, err := os.ReadFile(string(filename))
if err != nil {
return errors.Wrap(err, "failed to read defaults")
}
var m map[string]any
if err := yaml.Unmarshal(defaults, &m); err != nil {
return errors.Wrap(err, "failed to unmarshal defaults")
}
if err := mergo.Merge(&m, u.Values); err != nil {
return err
}
u.Extends = ""
u.Values = m
}
return nil
}
// JSONSchemaProperty type workaround // JSONSchemaProperty type workaround
func (Unit) JSONSchemaProperty(prop string) any { func (Unit) JSONSchemaProperty(prop string) any {
var x any var x any
@ -39,7 +77,7 @@ func (Unit) JSONSchemaProperty(prop string) any {
return nil return nil
} }
func (u *Unit) ValuesYAML(global, vars map[string]any) ([]byte, error) { func (u *Unit) ValuesYAML(global map[string]any) ([]byte, error) {
values := u.Values values := u.Values
if values == nil { if values == nil {
values = map[string]any{} values = map[string]any{}
@ -49,11 +87,6 @@ func (u *Unit) ValuesYAML(global, vars map[string]any) ([]byte, error) {
values["global"] = global values["global"] = global
} }
} }
if vars != nil {
if _, ok := values["vars"]; !ok {
values["vars"] = vars
}
}
return yamlv2.Marshal(values) return yamlv2.Marshal(values)
} }
@ -66,9 +99,9 @@ func (u *Unit) BuildNames() []string {
return ret return ret
} }
func (u *Unit) Template(ctx context.Context, name, squadron, unit, namespace string, global, vars map[string]any, helmArgs []string) ([]byte, error) { func (u *Unit) Template(ctx context.Context, name, squadron, unit, namespace string, global map[string]any, helmArgs []string) ([]byte, error) {
var ret bytes.Buffer var ret bytes.Buffer
valueBytes, err := u.ValuesYAML(global, vars) valueBytes, err := u.ValuesYAML(global)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,3 +1,3 @@
package config package config
const Version = "2.1" const Version = "2.2"

View File

@ -398,7 +398,7 @@ func (sq *Squadron) Diff(ctx context.Context, helmArgs []string, parallel int) e
if err != nil { if err != nil {
return err return err
} }
valueBytes, err := v.ValuesYAML(sq.c.Global, sq.c.Vars) valueBytes, err := v.ValuesYAML(sq.c.Global)
if err != nil { if err != nil {
return err return err
} }
@ -676,7 +676,7 @@ func (sq *Squadron) Up(ctx context.Context, helmArgs []string, username, version
if err != nil { if err != nil {
return err return err
} }
valueBytes, err := v.ValuesYAML(sq.c.Global, sq.c.Vars) valueBytes, err := v.ValuesYAML(sq.c.Global)
if err != nil { if err != nil {
return err return err
} }
@ -687,7 +687,8 @@ func (sq *Squadron) Up(ctx context.Context, helmArgs []string, username, version
Stdin(bytes.NewReader(valueBytes)). Stdin(bytes.NewReader(valueBytes)).
Stdout(os.Stdout). Stdout(os.Stdout).
Args("upgrade", name, "--install"). Args("upgrade", name, "--install").
Args("--set", fmt.Sprintf("squadron=%s,unit=%s", key, k)). Args("--set", fmt.Sprintf("squadron=%s", key)).
Args("--set", fmt.Sprintf("unit=%s", k)).
Args("--description", string(description)). Args("--description", string(description)).
Args("--namespace", namespace). Args("--namespace", namespace).
Args("--dependency-update"). Args("--dependency-update").
@ -748,7 +749,7 @@ func (sq *Squadron) Template(ctx context.Context, helmArgs []string, parallel in
} }
pterm.Debug.Printfln("running helm template for chart: %s", name) pterm.Debug.Printfln("running helm template for chart: %s", name)
out, err := v.Template(ctx, name, key, k, namespace, sq.c.Global, sq.c.Vars, helmArgs) out, err := v.Template(ctx, name, key, k, namespace, sq.c.Global, helmArgs)
if err != nil { if err != nil {
return err return err
} }

View File

@ -250,6 +250,10 @@
"values": { "values": {
"type": "object", "type": "object",
"description": "Chart values" "description": "Chart values"
},
"extends": {
"type": "string",
"description": "Extend chart values"
} }
}, },
"additionalProperties": false, "additionalProperties": false,

View File

@ -1 +1 @@
version: "2.1" version: "2.2"

View File

@ -1 +1 @@
version: "2.1" version: "2.2"

View File

@ -1 +1 @@
version: "2.1" version: "2.2"

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
global: global:
bar: bar:
- one - one

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
global: global:
bar: bar:
- one - one

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
global: global:
foo: "two" foo: "two"

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
global: global:
foo: "one" foo: "one"

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
squadron: squadron:
storefinder: storefinder:
frontend: frontend:

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
squadron: squadron:
storefinder: storefinder:
frontend: frontend:

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
squadron: squadron:
storefinder: storefinder:

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
squadron: squadron:
storefinder: storefinder:

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
squadron: squadron:
storefinder: storefinder:
frontend: frontend:

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
squadron: squadron:
storefinder: storefinder:
frontend: frontend:

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
squadron: squadron:
storefinder: storefinder:

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
squadron: squadron:
checkout: checkout:
backend: backend:

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
squadron: squadron:
checkout: checkout:
backend: backend:

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
squadron: squadron:
storefinder: storefinder:

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
global: global:
enabled: true enabled: true
host: mycompany.com host: mycompany.com

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
global: global:
enabled: true enabled: true
host: mycompany.com host: mycompany.com

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
global: global:
host: mycompany.com host: mycompany.com

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
vars: vars:
bar: bar:
- one - one

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
vars: vars:
bar: bar:
- one - one

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
vars: vars:
foo: "two" foo: "two"

View File

@ -1,4 +1,4 @@
version: "2.1" version: "2.2"
vars: vars:
foo: "one" foo: "one"