Skip to content

Commit

Permalink
feat: Tanka version constraint (#396)
Browse files Browse the repository at this point in the history
Adds `spec.versions.tanka` to validate the current Tanka version against
a SemVer constraint (e.g. `>=0.12`).

This is a struct and not a top level field to allow for extending in the
future, as there are other versions we could validate as well (Helm,
Kubectl, etc)
  • Loading branch information
sh0rez committed Oct 5, 2020
1 parent 596417c commit 5b1c57d
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ test:
dev:
go build -ldflags "-X main.Version=dev-${VERSION}" ./cmd/tk

LDFLAGS := '-s -w -extldflags "-static" -X main.Version=${VERSION}'
LDFLAGS := '-s -w -extldflags "-static" -X github.com/grafana/tanka/pkg/tanka.CURRENT_VERSION=${VERSION}'
static:
CGO_ENABLED=0 go build -ldflags=${LDFLAGS} ./cmd/tk

Expand Down
7 changes: 2 additions & 5 deletions cmd/tk/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,9 @@ import (
"github.com/grafana/tanka/pkg/jsonnet/jpath"
"github.com/grafana/tanka/pkg/spec"
"github.com/grafana/tanka/pkg/spec/v1alpha1"
"github.com/grafana/tanka/pkg/tanka"
)

// Version is the current version of the tk command.
// To be overwritten at build time
var Version = "dev"

// describing variables
var (
verbose = false
Expand All @@ -31,7 +28,7 @@ func main() {
rootCmd := &cli.Command{
Use: "tk",
Short: "tanka <3 jsonnet",
Version: Version,
Version: tanka.CURRENT_VERSION,
}

// workflow commands
Expand Down
9 changes: 8 additions & 1 deletion pkg/spec/v1alpha1/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,14 @@ type Spec struct {
Namespace string `json:"namespace"`
DiffStrategy string `json:"diffStrategy,omitempty"`
InjectLabels bool `json:"injectLabels,omitempty"`
ResourceDefaults ResourceDefaults `json:"resourceDefaults,omitempty"`
ResourceDefaults ResourceDefaults `json:"resourceDefaults"`
ExpectVersions ExpectVersions `json:"expectVersions"`
}

// ExpectVersions holds semantic version constraints
// TODO: extend this to handle more than Tanka
type ExpectVersions struct {
Tanka string `json:"tanka,omitempty"`
}

// ResourceDefaults will be inserted in any manifests that tanka processes.
Expand Down
37 changes: 37 additions & 0 deletions pkg/tanka/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"log"
"path/filepath"

"github.com/Masterminds/semver"
"github.com/pkg/errors"

"github.com/grafana/tanka/pkg/jsonnet"
Expand All @@ -17,6 +18,13 @@ import (
"github.com/grafana/tanka/pkg/spec/v1alpha1"
)

// DEFAULT_DEV_VERSION is the placeholder version used when no actual semver is
// provided using ldflags
const DEFAULT_DEV_VERSION = "dev"

// CURRENT_VERSION is the current version of the running Tanka code
var CURRENT_VERSION = DEFAULT_DEV_VERSION

// loaded is the final result of all processing stages:
// 1. jpath.Resolve: Consruct import paths
// 2. parseSpec: load spec.json
Expand Down Expand Up @@ -61,6 +69,10 @@ func load(dir string, opts Opts) (*loaded, error) {
return nil, err
}

if err := checkVersion(env.Spec.ExpectVersions.Tanka); err != nil {
return nil, err
}

rec, err := process.Process(raw, *env, opts.Filters)
if err != nil {
return nil, err
Expand Down Expand Up @@ -149,3 +161,28 @@ func evalJsonnet(baseDir string, env *v1alpha1.Config, opts jsonnet.Opts) (inter
}
return data, nil
}

func checkVersion(constraint string) error {
if constraint == "" {
return nil
}
if CURRENT_VERSION == DEFAULT_DEV_VERSION {
return nil
}

c, err := semver.NewConstraint(constraint)
if err != nil {
return fmt.Errorf("Parsing version constraint: '%w'. Please check 'spec.expectVersions.tanka'", err)
}

v, err := semver.NewVersion(CURRENT_VERSION)
if err != nil {
return fmt.Errorf("'%s' is not a valid semantic version: '%w'.\nThis likely means your build of Tanka is broken, as this is a compile-time value. When in doubt, please raise an issue", CURRENT_VERSION, err)
}

if !c.Check(v) {
return fmt.Errorf("Current version '%s' does not satisfy the version required by the environment: '%s'. You likely need to use another version of Tanka", CURRENT_VERSION, constraint)
}

return nil
}

0 comments on commit 5b1c57d

Please sign in to comment.