-
Notifications
You must be signed in to change notification settings - Fork 172
/
Copy pathprocess.go
121 lines (97 loc) · 2.56 KB
/
process.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package process
import (
"errors"
"fmt"
"github.com/grafana/tanka/pkg/kubernetes/manifest"
"github.com/grafana/tanka/pkg/spec/v1alpha1"
)
const (
MetadataPrefix = "tanka.dev"
LabelEnvironment = MetadataPrefix + "/environment"
)
// Process converts the raw Jsonnet evaluation result (JSON tree) into a flat
// list of Kubernetes objects, also applying some transformations:
// - tanka.dev/** labels
// - filtering
// - best-effort sorting
func Process(raw interface{}, cfg v1alpha1.Environment, exprs Matchers) (manifest.List, error) {
// Scan for everything that looks like a Kubernetes object
extracted, err := Extract(raw)
if err != nil {
return nil, err
}
// Unwrap *List types
if err := Unwrap(extracted); err != nil {
return nil, err
}
out := make(manifest.List, 0, len(extracted))
for _, m := range extracted {
out = append(out, m)
}
// set default namespace
out = Namespace(out, cfg.Spec.Namespace)
// tanka.dev/** labels
out = Label(out, cfg)
// arbitrary labels and annotations from spec
out = ResourceDefaults(out, cfg)
// Perhaps filter for kind/name expressions
if len(exprs) > 0 {
out = Filter(out, exprs)
}
// Best-effort dependency sort
Sort(out)
return out, nil
}
// Label conditionally adds tanka.dev/** labels to each manifest in the List
func Label(list manifest.List, cfg v1alpha1.Environment) manifest.List {
for i, m := range list {
// inject tanka.dev/environment label
if cfg.Spec.InjectLabels {
m.Metadata().Labels()[LabelEnvironment] = cfg.Metadata.NameLabel()
}
list[i] = m
}
return list
}
func ResourceDefaults(list manifest.List, cfg v1alpha1.Environment) manifest.List {
for i, m := range list {
for k, v := range cfg.Spec.ResourceDefaults.Annotations {
annotations := m.Metadata().Annotations()
if _, ok := annotations[k]; !ok {
annotations[k] = v
}
}
for k, v := range cfg.Spec.ResourceDefaults.Labels {
labels := m.Metadata().Labels()
if _, ok := labels[k]; !ok {
labels[k] = v
}
}
list[i] = m
}
return list
}
// Unwrap returns all Kubernetes objects in the manifest. If m is not a List
// type, a one item List is returned
func Unwrap(manifests map[string]manifest.Manifest) error {
for path, m := range manifests {
if !m.IsList() {
continue
}
items, err := m.Items()
if err != nil {
return err
}
for index, i := range items {
name := fmt.Sprintf("%s.items[%v]", path, index)
var e *manifest.SchemaError
if errors.As(i.Verify(), &e) {
e.Name = name
return e
}
manifests[name] = i
}
delete(manifests, path)
}
return nil
}