Skip to content

Commit 073e616

Browse files
authored
feat(k8s): Set default labels and annotations from spec.json
1 parent e8b3805 commit 073e616

File tree

4 files changed

+128
-4
lines changed

4 files changed

+128
-4
lines changed

go.sum

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
3535
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
3636
github.com/google/go-cmp v0.5.2-0.20200818193711-d2fcc899bdc2 h1:CZtx9gNen+kr3PuC/JQff3n1pJbgpy7Wr3hzjnupqdw=
3737
github.com/google/go-cmp v0.5.2-0.20200818193711-d2fcc899bdc2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
38+
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
3839
github.com/google/go-jsonnet v0.15.1-0.20200331184325-4f4aa80dd785 h1:+dlQ7fPoeAqO0U9V+94golo/rW1/V2Pn+v8aPp3ljRM=
3940
github.com/google/go-jsonnet v0.15.1-0.20200331184325-4f4aa80dd785/go.mod h1:sOcuej3UW1vpPTZOr8L7RQimqai1a57bt5j22LzGZCw=
4041
github.com/google/go-jsonnet v0.16.1-0.20200908152747-b70cbd441a39 h1:noLRnY1ESguFGDPxXvIcESe2rG63f+ZSbSGYfVa6iHo=

pkg/process/process.go

+24
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ func Process(raw interface{}, cfg v1alpha1.Config, exprs Matchers) (manifest.Lis
4141
// tanka.dev/** labels
4242
out = Label(out, cfg)
4343

44+
// arbitrary labels and annotations from spec
45+
out = ResourceDefaults(out, cfg)
46+
4447
// Perhaps filter for kind/name expressions
4548
if len(exprs) > 0 {
4649
out = Filter(out, exprs)
@@ -65,6 +68,27 @@ func Label(list manifest.List, cfg v1alpha1.Config) manifest.List {
6568
return list
6669
}
6770

71+
func ResourceDefaults(list manifest.List, cfg v1alpha1.Config) manifest.List {
72+
for i, m := range list {
73+
for k, v := range cfg.Spec.ResourceDefaults.Annotations {
74+
annotations := m.Metadata().Annotations()
75+
if _, ok := annotations[k]; !ok {
76+
annotations[k] = v
77+
}
78+
}
79+
80+
for k, v := range cfg.Spec.ResourceDefaults.Labels {
81+
labels := m.Metadata().Labels()
82+
if _, ok := labels[k]; !ok {
83+
labels[k] = v
84+
}
85+
}
86+
87+
list[i] = m
88+
}
89+
return list
90+
}
91+
6892
// Unwrap returns all Kubernetes objects in the manifest. If m is not a List
6993
// type, a one item List is returned
7094
func Unwrap(manifests map[string]manifest.Manifest) error {

pkg/process/resourceDefaults_test.go

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package process
2+
3+
import (
4+
"testing"
5+
6+
"github.com/google/go-cmp/cmp"
7+
8+
"github.com/grafana/tanka/pkg/kubernetes/manifest"
9+
"github.com/grafana/tanka/pkg/spec/v1alpha1"
10+
)
11+
12+
func TestResourceDefaults(t *testing.T) {
13+
cases := []struct {
14+
name string
15+
beforeAnnotations map[string]string
16+
beforeLabels map[string]string
17+
specAnnotations map[string]string
18+
specLabels map[string]string
19+
expectedAnnotations map[string]string
20+
expectedLabels map[string]string
21+
}{
22+
// resource without a namespace: set it
23+
{
24+
name: "No change",
25+
},
26+
{
27+
name: "Add annotation",
28+
specAnnotations: map[string]string{"a": "b"},
29+
expectedAnnotations: map[string]string{"a": "b"},
30+
},
31+
{
32+
name: "Add Label",
33+
specLabels: map[string]string{"a": "b"},
34+
expectedLabels: map[string]string{"a": "b"},
35+
},
36+
{
37+
name: "Add leaves existing",
38+
beforeAnnotations: map[string]string{"1": "2"},
39+
beforeLabels: map[string]string{"1": "2"},
40+
specAnnotations: map[string]string{"a": "b"},
41+
specLabels: map[string]string{"a": "b"},
42+
expectedAnnotations: map[string]string{"a": "b", "1": "2"},
43+
expectedLabels: map[string]string{"a": "b", "1": "2"},
44+
},
45+
{
46+
name: "Existing overrides spec",
47+
beforeAnnotations: map[string]string{"a": "c", "1": "2"},
48+
beforeLabels: map[string]string{"a": "c", "1": "2"},
49+
specAnnotations: map[string]string{"a": "b"},
50+
specLabels: map[string]string{"a": "b"},
51+
expectedAnnotations: map[string]string{"a": "c", "1": "2"},
52+
expectedLabels: map[string]string{"a": "c", "1": "2"},
53+
},
54+
}
55+
56+
for _, c := range cases {
57+
t.Run(c.name, func(t *testing.T) {
58+
cfg := v1alpha1.Config{
59+
Spec: v1alpha1.Spec{
60+
ResourceDefaults: v1alpha1.ResourceDefaults{
61+
Annotations: c.specAnnotations,
62+
Labels: c.specLabels,
63+
},
64+
},
65+
}
66+
67+
before := manifest.Manifest{
68+
"kind": "Deployment",
69+
}
70+
for k, v := range c.beforeAnnotations {
71+
before.Metadata().Annotations()[k] = v
72+
}
73+
for k, v := range c.beforeLabels {
74+
before.Metadata().Labels()[k] = v
75+
}
76+
77+
expected := manifest.Metadata{}
78+
for k, v := range c.expectedAnnotations {
79+
expected.Annotations()[k] = v
80+
}
81+
for k, v := range c.expectedLabels {
82+
expected.Labels()[k] = v
83+
}
84+
85+
result := ResourceDefaults(manifest.List{before}, cfg)
86+
actual := result[0]
87+
if diff := cmp.Diff(expected, actual.Metadata()); diff != "" {
88+
t.Error(diff)
89+
}
90+
})
91+
}
92+
}

pkg/spec/v1alpha1/config.go

+11-4
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,15 @@ func (m Metadata) NameLabel() string {
5050

5151
// Spec defines Kubernetes properties
5252
type Spec struct {
53-
APIServer string `json:"apiServer"`
54-
Namespace string `json:"namespace"`
55-
DiffStrategy string `json:"diffStrategy,omitempty"`
56-
InjectLabels bool `json:"injectLabels,omitempty"`
53+
APIServer string `json:"apiServer"`
54+
Namespace string `json:"namespace"`
55+
DiffStrategy string `json:"diffStrategy,omitempty"`
56+
InjectLabels bool `json:"injectLabels,omitempty"`
57+
ResourceDefaults ResourceDefaults `json:"resourceDefaults,omitempty"`
58+
}
59+
60+
// ResourceDefaults will be inserted in any manifests that tanka processes.
61+
type ResourceDefaults struct {
62+
Annotations map[string]string `json:"annotations,omitempty"`
63+
Labels map[string]string `json:"labels,omitempty"`
5764
}

0 commit comments

Comments
 (0)