Skip to content

Commit

Permalink
refactor: extract Environment as k8s-like object
Browse files Browse the repository at this point in the history
  • Loading branch information
Duologic committed Nov 4, 2020
1 parent b18a386 commit ac417d3
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 31 deletions.
69 changes: 49 additions & 20 deletions pkg/tanka/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,31 +171,38 @@ func eval(path string, opts jsonnet.Opts) (interface{}, *v1alpha1.Config, error)
return data, nil, nil
}

var env *v1alpha1.Config
switch data.(type) {
case []interface{}:
env = &v1alpha1.Config{}
// data is array, do not try to unmarshal,
// multiple envs currently unsupported
default:
if err := json.Unmarshal([]byte(raw), &env); err != nil {
return nil, nil, errors.Wrap(err, "unmarshalling into v1alpha1.Config")
extract, err := extractEnvironments(data)
if _, ok := err.(process.ErrorPrimitiveReached); ok {
if !hasSpec {
// if no environments or spec found, behave as jsonnet interpreter
return data, nil, err
}
} else if err != nil {
return nil, nil, err
}

// env is not a v1alpha1.Config, fallback to original behavior
if env.Kind != "Environment" {
if hasSpec {
specEnv.Data = data
// return env from spec.json
return data, specEnv, nil
} else {
// No spec.json found, behave as jsonnet interpreter
return data, nil, nil
var env *v1alpha1.Config

if len(extract) > 1 {
return nil, nil, fmt.Errorf("more than 1 environments found")
} else if len(extract) == 1 {
data, err := json.Marshal(extract[0])
if err != nil {
return nil, nil, err
}
env, err = spec.Parse(data)
if err != nil {
return nil, nil, err
}
} else if hasSpec {
// if no environments found, fallback to original behavior
specEnv.Data = data
return data, specEnv, nil
} else {
// if no environments or spec found, behave as jsonnet interpreter
return data, nil, fmt.Errorf("no environments found")
}
// return env AS IS
return *env, env, nil
return data, env, nil
}

func checkVersion(constraint string) error {
Expand All @@ -222,3 +229,25 @@ func checkVersion(constraint string) error {

return nil
}

func extractEnvironments(data interface{}) (manifest.List, error) {
// Scan for everything that looks like a Kubernetes object
extracted, err := process.Extract(data)
if err != nil {
return nil, err
}

// Unwrap *List types
if err := process.Unwrap(extracted); err != nil {
return nil, err
}

// Perhaps filter for kind/name expressions
out := make(manifest.List, 0, len(extracted))
for _, m := range extracted {
out = append(out, m)
}

// Extract only object of Kind: Environment
return process.Filter(out, process.MustStrExps("Environment/.*")), nil
}
28 changes: 17 additions & 11 deletions pkg/tanka/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/grafana/tanka/pkg/jsonnet"
"github.com/grafana/tanka/pkg/process"
"github.com/grafana/tanka/pkg/spec/v1alpha1"
"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -79,25 +80,26 @@ func TestEvalJsonnet(t *testing.T) {
},
{
baseDir: "./testdata/cases/withenv/main.jsonnet",
expected: v1alpha1.Config{
APIVersion: v1alpha1.New().APIVersion,
Kind: v1alpha1.New().Kind,
Metadata: v1alpha1.Metadata{
Name: "withenv",
expected: map[string]interface{}{
"apiVersion": v1alpha1.New().APIVersion,
"kind": v1alpha1.New().Kind,
"metadata": map[string]interface{}{
"name": "withenv",
},
Spec: v1alpha1.Spec{
APIServer: "https://localhost",
Namespace: "withenv",
"spec": map[string]interface{}{
"apiServer": "https://localhost",
"namespace": "withenv",
},
Data: map[string]interface{}{
"data": map[string]interface{}{
"testCase": "object",
},
},
env: &v1alpha1.Config{
APIVersion: v1alpha1.New().APIVersion,
Kind: v1alpha1.New().Kind,
Metadata: v1alpha1.Metadata{
Name: "withenv",
Name: "withenv",
Labels: v1alpha1.New().Metadata.Labels,
},
Spec: v1alpha1.Spec{
APIServer: "https://localhost",
Expand All @@ -112,7 +114,11 @@ func TestEvalJsonnet(t *testing.T) {

for _, test := range cases {
data, env, e := eval(test.baseDir, jsonnet.Opts{})
assert.NoError(t, e)
if data == nil {
assert.NoError(t, e)
} else if e != nil {
assert.IsType(t, process.ErrorPrimitiveReached{}, e)
}
assert.Equal(t, test.expected, data)
assert.Equal(t, test.env, env)
}
Expand Down

0 comments on commit ac417d3

Please sign in to comment.