Skip to content

Commit ac417d3

Browse files
committed
refactor: extract Environment as k8s-like object
1 parent b18a386 commit ac417d3

File tree

2 files changed

+66
-31
lines changed

2 files changed

+66
-31
lines changed

pkg/tanka/parse.go

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -171,31 +171,38 @@ func eval(path string, opts jsonnet.Opts) (interface{}, *v1alpha1.Config, error)
171171
return data, nil, nil
172172
}
173173

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

186-
// env is not a v1alpha1.Config, fallback to original behavior
187-
if env.Kind != "Environment" {
188-
if hasSpec {
189-
specEnv.Data = data
190-
// return env from spec.json
191-
return data, specEnv, nil
192-
} else {
193-
// No spec.json found, behave as jsonnet interpreter
194-
return data, nil, nil
184+
var env *v1alpha1.Config
185+
186+
if len(extract) > 1 {
187+
return nil, nil, fmt.Errorf("more than 1 environments found")
188+
} else if len(extract) == 1 {
189+
data, err := json.Marshal(extract[0])
190+
if err != nil {
191+
return nil, nil, err
195192
}
193+
env, err = spec.Parse(data)
194+
if err != nil {
195+
return nil, nil, err
196+
}
197+
} else if hasSpec {
198+
// if no environments found, fallback to original behavior
199+
specEnv.Data = data
200+
return data, specEnv, nil
201+
} else {
202+
// if no environments or spec found, behave as jsonnet interpreter
203+
return data, nil, fmt.Errorf("no environments found")
196204
}
197-
// return env AS IS
198-
return *env, env, nil
205+
return data, env, nil
199206
}
200207

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

223230
return nil
224231
}
232+
233+
func extractEnvironments(data interface{}) (manifest.List, error) {
234+
// Scan for everything that looks like a Kubernetes object
235+
extracted, err := process.Extract(data)
236+
if err != nil {
237+
return nil, err
238+
}
239+
240+
// Unwrap *List types
241+
if err := process.Unwrap(extracted); err != nil {
242+
return nil, err
243+
}
244+
245+
// Perhaps filter for kind/name expressions
246+
out := make(manifest.List, 0, len(extracted))
247+
for _, m := range extracted {
248+
out = append(out, m)
249+
}
250+
251+
// Extract only object of Kind: Environment
252+
return process.Filter(out, process.MustStrExps("Environment/.*")), nil
253+
}

pkg/tanka/parse_test.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"testing"
55

66
"github.com/grafana/tanka/pkg/jsonnet"
7+
"github.com/grafana/tanka/pkg/process"
78
"github.com/grafana/tanka/pkg/spec/v1alpha1"
89
"github.com/stretchr/testify/assert"
910
)
@@ -79,25 +80,26 @@ func TestEvalJsonnet(t *testing.T) {
7980
},
8081
{
8182
baseDir: "./testdata/cases/withenv/main.jsonnet",
82-
expected: v1alpha1.Config{
83-
APIVersion: v1alpha1.New().APIVersion,
84-
Kind: v1alpha1.New().Kind,
85-
Metadata: v1alpha1.Metadata{
86-
Name: "withenv",
83+
expected: map[string]interface{}{
84+
"apiVersion": v1alpha1.New().APIVersion,
85+
"kind": v1alpha1.New().Kind,
86+
"metadata": map[string]interface{}{
87+
"name": "withenv",
8788
},
88-
Spec: v1alpha1.Spec{
89-
APIServer: "https://localhost",
90-
Namespace: "withenv",
89+
"spec": map[string]interface{}{
90+
"apiServer": "https://localhost",
91+
"namespace": "withenv",
9192
},
92-
Data: map[string]interface{}{
93+
"data": map[string]interface{}{
9394
"testCase": "object",
9495
},
9596
},
9697
env: &v1alpha1.Config{
9798
APIVersion: v1alpha1.New().APIVersion,
9899
Kind: v1alpha1.New().Kind,
99100
Metadata: v1alpha1.Metadata{
100-
Name: "withenv",
101+
Name: "withenv",
102+
Labels: v1alpha1.New().Metadata.Labels,
101103
},
102104
Spec: v1alpha1.Spec{
103105
APIServer: "https://localhost",
@@ -112,7 +114,11 @@ func TestEvalJsonnet(t *testing.T) {
112114

113115
for _, test := range cases {
114116
data, env, e := eval(test.baseDir, jsonnet.Opts{})
115-
assert.NoError(t, e)
117+
if data == nil {
118+
assert.NoError(t, e)
119+
} else if e != nil {
120+
assert.IsType(t, process.ErrorPrimitiveReached{}, e)
121+
}
116122
assert.Equal(t, test.expected, data)
117123
assert.Equal(t, test.env, env)
118124
}

0 commit comments

Comments
 (0)