Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add extends #76

Merged
merged 2 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Configure your squadron

```yaml
# https://raw.githubusercontent.com/foomo/squadron/refs/heads/main/squadron.schema.json
version: '2.1'
version: '2.2'

# squadron template vars
vars: {}
Expand Down
2 changes: 1 addition & 1 deletion _examples/helloworld/squadron.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '2.1'
version: '2.2'

squadron:
storefinder:
Expand Down
2 changes: 1 addition & 1 deletion _examples/kustomize/squadron.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '2.1'
version: '2.2'

squadron:
storefinder:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Schema version
version: '2.1'
version: '2.2'

squadron:
checkout:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Schema version
version: '2.1'
version: '2.2'

squadron:
checkout:
Expand Down
2 changes: 1 addition & 1 deletion _examples/monorepo/squadrons/squadron.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: '2.1'
version: '2.2'

global:
docker:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Schema version
version: '2.1'
version: '2.2'

squadron:
storefinder:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Schema version
version: '2.1'
version: '2.2'

squadron:
storefinder:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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

require (
dario.cat/mergo v1.0.1
github.com/1Password/connect-sdk-go v1.5.3
github.com/BurntSushi/toml v1.4.0
github.com/Masterminds/sprig/v3 v3.3.0
Expand All @@ -29,7 +30,6 @@ require (
atomicgo.dev/cursor v0.2.0 // indirect
atomicgo.dev/keyboard v0.2.9 // 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/semver/v3 v3.3.0 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
Expand Down
5 changes: 5 additions & 0 deletions internal/config/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,26 @@ func (d *Chart) UnmarshalYAML(value *yaml.Node) error {
if err := value.Decode(&vString); err != nil {
return err
}

vBytes, err := template.ExecuteFileTemplate(context.Background(), vString, nil, true)
if err != nil {
return errors.Wrap(err, "failed to render chart string")
}

localChart, err := loadChart(path.Join(string(vBytes), "Chart.yaml"))
if err != nil {
return errors.New("failed to load local chart: " + vString)
}

d.Name = localChart.Name
d.Repository = fmt.Sprintf("file://%v", vString)
d.Version = localChart.Version

wd, err := os.Getwd()
if err != nil {
return errors.Wrap(err, "failed to get working directory")
}

schemaPath := string(vBytes)
if value, err := filepath.Rel(wd, string(vBytes)); err == nil {
schemaPath = value
Expand Down
48 changes: 40 additions & 8 deletions internal/config/unit.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ import (
"bytes"
"context"
"fmt"
"os"
"path"
"sort"
"strings"

"dario.cat/mergo"
"github.com/foomo/squadron/internal/template"
"github.com/foomo/squadron/internal/util"
"github.com/pkg/errors"
yamlv2 "gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
)

type Unit struct {
Expand All @@ -24,12 +28,45 @@ type Unit struct {
Builds map[string]Build `json:"builds,omitempty" yaml:"builds,omitempty"`
// Chart values
Values map[string]any `json:"values,omitempty" yaml:"values,omitempty"`
// Extend chart values
Extends string `json:"extends,omitempty" yaml:"extends,omitempty"`
}

// ------------------------------------------------------------------------------------------------
// ~ 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(&u.Values, m); err != nil {
return err
}

u.Extends = ""
}
return nil
}

// JSONSchemaProperty type workaround
func (Unit) JSONSchemaProperty(prop string) any {
var x any
Expand All @@ -39,7 +76,7 @@ func (Unit) JSONSchemaProperty(prop string) any {
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
if values == nil {
values = map[string]any{}
Expand All @@ -49,11 +86,6 @@ func (u *Unit) ValuesYAML(global, vars map[string]any) ([]byte, error) {
values["global"] = global
}
}
if vars != nil {
if _, ok := values["vars"]; !ok {
values["vars"] = vars
}
}
return yamlv2.Marshal(values)
}

Expand All @@ -66,9 +98,9 @@ func (u *Unit) BuildNames() []string {
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
valueBytes, err := u.ValuesYAML(global, vars)
valueBytes, err := u.ValuesYAML(global)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/config/version.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package config

const Version = "2.1"
const Version = "2.2"
9 changes: 5 additions & 4 deletions squadron.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ func (sq *Squadron) Diff(ctx context.Context, helmArgs []string, parallel int) e
if err != nil {
return err
}
valueBytes, err := v.ValuesYAML(sq.c.Global, sq.c.Vars)
valueBytes, err := v.ValuesYAML(sq.c.Global)
if err != nil {
return err
}
Expand Down Expand Up @@ -676,7 +676,7 @@ func (sq *Squadron) Up(ctx context.Context, helmArgs []string, username, version
if err != nil {
return err
}
valueBytes, err := v.ValuesYAML(sq.c.Global, sq.c.Vars)
valueBytes, err := v.ValuesYAML(sq.c.Global)
if err != nil {
return err
}
Expand All @@ -687,7 +687,8 @@ func (sq *Squadron) Up(ctx context.Context, helmArgs []string, username, version
Stdin(bytes.NewReader(valueBytes)).
Stdout(os.Stdout).
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("--namespace", namespace).
Args("--dependency-update").
Expand Down Expand Up @@ -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)
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 {
return err
}
Expand Down
4 changes: 4 additions & 0 deletions squadron.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@
"values": {
"type": "object",
"description": "Chart values"
},
"extends": {
"type": "string",
"description": "Extend chart values"
}
},
"additionalProperties": false,
Expand Down
4 changes: 4 additions & 0 deletions squadron_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ func TestConfigSimpleSnapshot(t *testing.T) {
name: "simple",
files: []string{"squadron.yaml"},
},
{
name: "extends",
files: []string{"squadron.yaml"},
},
{
name: "override",
files: []string{"squadron.yaml", "squadron.override.yaml"},
Expand Down
2 changes: 1 addition & 1 deletion testdata/blank/snapshop-config-norender.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version: "2.1"
version: "2.2"
2 changes: 1 addition & 1 deletion testdata/blank/snapshop-config.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version: "2.1"
version: "2.2"
2 changes: 1 addition & 1 deletion testdata/blank/squadron.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version: "2.1"
version: "2.2"
19 changes: 19 additions & 0 deletions testdata/extends/snapshop-config-norender.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: "2.2"
squadron:
storefinder:
frontend:
chart:
name: frontend
repository: file://<% env "PROJECT_ROOT" %>/_examples/common/charts/frontend
version: 0.0.1
values:
env:
ONE: foo
THREE: baz
TWO: bar
image:
repository: nginx
tag: latest
tags:
- ONE
- TWO
19 changes: 19 additions & 0 deletions testdata/extends/snapshop-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: "2.2"
squadron:
storefinder:
frontend:
chart:
name: frontend
repository: file://./_examples/common/charts/frontend
version: 0.0.1
values:
env:
ONE: foo
THREE: baz
TWO: bar
image:
repository: nginx
tag: latest
tags:
- ONE
- TWO
78 changes: 78 additions & 0 deletions testdata/extends/snapshop-template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
# Source: frontend/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: storefinder-frontend
labels:
app.kubernetes.io/name: storefinder-frontend
app.kubernetes.io/component: frontend
app.kubernetes.io/managed-by: Helm
helm.sh/chart: 'frontend-0.0.1'
namespace: default
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: storefinder-frontend
app.kubernetes.io/component: frontend
ports:
- name: http
port: 80
---
# Source: frontend/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: storefinder-frontend
labels:
app.kubernetes.io/name: storefinder-frontend
app.kubernetes.io/component: frontend
app.kubernetes.io/managed-by: Helm
helm.sh/chart: 'frontend-0.0.1'
namespace: default
spec:
selector:
matchLabels:
app.kubernetes.io/name: storefinder-frontend
app.kubernetes.io/component: frontend
template:
metadata:
labels:
app.kubernetes.io/name: storefinder-frontend
app.kubernetes.io/component: frontend
spec:
containers:
- name: storefinder-frontend
image: 'nginx:latest'
ports:
- name: http
protocol: TCP
containerPort: 80
---
# Source: frontend/templates/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: storefinder-frontend
labels:
app.kubernetes.io/name: storefinder-frontend
app.kubernetes.io/component: frontend
app.kubernetes.io/managed-by: Helm
helm.sh/chart: 'frontend-0.0.1'
namespace: default
spec:
tls:
- hosts: ['foo.com']
secretName: foo-com-cert
rules:
- host: foo.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: storefinder-frontend
port:
name: http
number: 80
8 changes: 8 additions & 0 deletions testdata/extends/squadron.base.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
image:
tag: unknown
repository: nginx
env:
ONE: unknown
THREE: baz
tags:
- unknown
Loading