Skip to content

Commit 13e2600

Browse files
authored
Merge pull request #4357 from natasha41575/TransformerAnnotations
define methods, types, and unit tests for transformer annotations
2 parents a1a0a49 + 4f21d60 commit 13e2600

File tree

10 files changed

+428
-15
lines changed

10 files changed

+428
-15
lines changed

api/internal/target/kusttarget.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ func (kt *KustTarget) accumulateFile(
502502
if err != nil {
503503
return errors.Wrapf(err, "cannot add path annotation for '%s'", path)
504504
}
505-
err = resources.AnnotateAll(utils.OriginAnnotation, originAnno)
505+
err = resources.AnnotateAll(utils.OriginAnnotationKey, originAnno)
506506
if err != nil || originAnno == "" {
507507
return errors.Wrapf(err, "cannot add path annotation for '%s'", path)
508508
}

api/internal/utils/annotations.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package utils
33
import "sigs.k8s.io/kustomize/api/konfig"
44

55
const (
6+
// build annotations
67
BuildAnnotationPreviousKinds = konfig.ConfigAnnoDomain + "/previousKinds"
78
BuildAnnotationPreviousNames = konfig.ConfigAnnoDomain + "/previousNames"
89
BuildAnnotationPrefixes = konfig.ConfigAnnoDomain + "/prefixes"
@@ -17,7 +18,9 @@ const (
1718
BuildAnnotationAllowNameChange = konfig.ConfigAnnoDomain + "/allowNameChange"
1819
BuildAnnotationAllowKindChange = konfig.ConfigAnnoDomain + "/allowKindChange"
1920

20-
OriginAnnotation = "config.kubernetes.io/origin"
21+
// for keeping track of origin and transformer data
22+
OriginAnnotationKey = "config.kubernetes.io/origin"
23+
TransformerAnnotationKey = "config.kubernetes.io/transformations"
2124

2225
Enabled = "enabled"
2326
)

api/krusty/buildmetadata_test.go renamed to api/krusty/originannotation_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"github.com/stretchr/testify/assert"
1212
"sigs.k8s.io/kustomize/api/internal/utils"
1313
"sigs.k8s.io/kustomize/api/krusty"
14-
_ "sigs.k8s.io/kustomize/api/krusty"
1514
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
1615
"sigs.k8s.io/kustomize/kyaml/filesys"
1716
)

api/resmap/resmap.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ type Transformer interface {
2121
Transform(m ResMap) error
2222
}
2323

24+
// A TransformerWithProperties contains a Transformer and stores
25+
// some of its properties
26+
type TransformerWithProperties struct {
27+
Transformer
28+
Origin *resource.Origin
29+
}
30+
2431
// A Generator creates an instance of ResMap.
2532
type Generator interface {
2633
Generate() (ResMap, error)
@@ -144,10 +151,24 @@ type ResMap interface {
144151
AbsorbAll(ResMap) error
145152

146153
// AddOriginAnnotation will add the provided origin as
147-
// an annotation to all resources in the Resmap, if
154+
// an origin annotation to all resources in the ResMap, if
148155
// the origin is not nil.
149156
AddOriginAnnotation(origin *resource.Origin) error
150157

158+
// RemoveOriginAnnotation will remove the origin annotation
159+
// from all resources in the ResMap
160+
RemoveOriginAnnotations() error
161+
162+
// AddTransformerAnnotation will add the provided origin as
163+
// an origin annotation if the resource doesn't have one; a
164+
// transformer annotation otherwise; to all resources in
165+
// ResMap
166+
AddTransformerAnnotation(origin *resource.Origin) error
167+
168+
// RemoveTransformerAnnotation will remove the transformer annotation
169+
// from all resources in the ResMap
170+
RemoveTransformerAnnotations() error
171+
151172
// AnnotateAll annotates all resources in the ResMap with
152173
// the provided key value pair.
153174
AnnotateAll(key string, value string) error

api/resmap/reswrangler.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,50 @@ func (m *resWrangler) AddOriginAnnotation(origin *resource.Origin) error {
510510
return nil
511511
}
512512

513+
// RemoveOriginAnnotation implements ResMap
514+
func (m *resWrangler) RemoveOriginAnnotations() error {
515+
for _, res := range m.rList {
516+
if err := res.SetOrigin(nil); err != nil {
517+
return err
518+
}
519+
}
520+
return nil
521+
}
522+
523+
// AddTransformerAnnotation implements ResMap
524+
func (m *resWrangler) AddTransformerAnnotation(origin *resource.Origin) error {
525+
for _, res := range m.rList {
526+
or, err := res.GetOrigin()
527+
if err != nil {
528+
return err
529+
}
530+
if or == nil {
531+
// the resource does not have an origin annotation, so
532+
// we assume that the transformer generated the resource
533+
// rather than modifying it
534+
err = res.SetOrigin(origin)
535+
} else {
536+
// the resource already has an origin annotation, so we
537+
// record the provided origin as a transformation
538+
err = res.AddTransformation(origin)
539+
}
540+
if err != nil {
541+
return err
542+
}
543+
}
544+
return nil
545+
}
546+
547+
// RemoveTransformerAnnotations implements ResMap
548+
func (m *resWrangler) RemoveTransformerAnnotations() error {
549+
for _, res := range m.rList {
550+
if err := res.ClearTransformations(); err != nil {
551+
return err
552+
}
553+
}
554+
return nil
555+
}
556+
513557
func (m *resWrangler) appendReplaceOrMerge(res *resource.Resource) error {
514558
id := res.CurId()
515559
matches := m.GetMatchingResourcesByAnyId(id.Equals)

api/resmap/reswrangler_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,34 @@ import (
2626
var depProvider = provider.NewDefaultDepProvider()
2727
var rf = depProvider.GetResourceFactory()
2828
var rmF = NewFactory(rf)
29+
var origin1 = &resource.Origin{
30+
Repo: "github.com/myrepo",
31+
Ref: "master",
32+
ConfiguredIn: "config.yaml",
33+
ConfiguredBy: yaml.ResourceIdentifier{
34+
TypeMeta: yaml.TypeMeta{
35+
APIVersion: "builtin",
36+
Kind: "Generator",
37+
},
38+
NameMeta: yaml.NameMeta{
39+
Name: "my-name",
40+
Namespace: "my-namespace",
41+
},
42+
},
43+
}
44+
var origin2 = &resource.Origin{
45+
ConfiguredIn: "../base/config.yaml",
46+
ConfiguredBy: yaml.ResourceIdentifier{
47+
TypeMeta: yaml.TypeMeta{
48+
APIVersion: "builtin",
49+
Kind: "Generator",
50+
},
51+
NameMeta: yaml.NameMeta{
52+
Name: "my-name",
53+
Namespace: "my-namespace",
54+
},
55+
},
56+
}
2957

3058
func doAppend(t *testing.T, w ResMap, r *resource.Resource) {
3159
err := w.Append(r)
@@ -1530,6 +1558,67 @@ $patch: delete
15301558
}
15311559
}
15321560

1561+
func TestOriginAnnotations(t *testing.T) {
1562+
w := New()
1563+
for i := 0; i < 3; i++ {
1564+
assert.NoError(t, w.Append(makeCm(i)))
1565+
}
1566+
// this should add an origin annotation to every resource
1567+
assert.NoError(t, w.AddOriginAnnotation(origin1))
1568+
resources := w.Resources()
1569+
for _, res := range resources {
1570+
or, err := res.GetOrigin()
1571+
assert.NoError(t, err)
1572+
assert.Equal(t, origin1, or)
1573+
}
1574+
// this should not overwrite the existing origin annotations
1575+
assert.NoError(t, w.AddOriginAnnotation(origin2))
1576+
for _, res := range resources {
1577+
or, err := res.GetOrigin()
1578+
assert.NoError(t, err)
1579+
assert.Equal(t, origin1, or)
1580+
}
1581+
// this should remove origin annotations from all resources
1582+
assert.NoError(t, w.RemoveOriginAnnotations())
1583+
for _, res := range resources {
1584+
or, err := res.GetOrigin()
1585+
assert.NoError(t, err)
1586+
assert.Nil(t, or)
1587+
}
1588+
}
1589+
1590+
func TestTransformerAnnotations(t *testing.T) {
1591+
w := New()
1592+
for i := 0; i < 3; i++ {
1593+
assert.NoError(t, w.Append(makeCm(i)))
1594+
}
1595+
// this should add an origin annotation to every resource
1596+
assert.NoError(t, w.AddTransformerAnnotation(origin1))
1597+
resources := w.Resources()
1598+
for _, res := range resources {
1599+
or, err := res.GetOrigin()
1600+
assert.NoError(t, err)
1601+
assert.Equal(t, origin1, or)
1602+
}
1603+
// this should add a transformer annotation to every resource
1604+
assert.NoError(t, w.AddTransformerAnnotation(origin2))
1605+
for _, res := range resources {
1606+
or, err := res.GetOrigin()
1607+
assert.NoError(t, err)
1608+
assert.Equal(t, origin1, or)
1609+
tr, err := res.GetTransformations()
1610+
assert.NoError(t, err)
1611+
assert.Equal(t, resource.Transformations{origin2}, tr)
1612+
}
1613+
// remove transformer annotations from all resources
1614+
assert.NoError(t, w.RemoveTransformerAnnotations())
1615+
for _, res := range resources {
1616+
tr, err := res.GetTransformations()
1617+
assert.NoError(t, err)
1618+
assert.Nil(t, tr)
1619+
}
1620+
}
1621+
15331622
// baseResource produces a base object which used to test
15341623
// patch transformation
15351624
// Also the structure is matching the Deployment syntax

api/resource/origin.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,31 @@ import (
1111
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
1212
)
1313

14-
// Origin retains information about where resources in the output
15-
// of `kustomize build` originated from
14+
// Origin retains information about the origin of resources and transformer configs
15+
// that contributed to the output of `kustomize build`
1616
type Origin struct {
1717
// Path is the path to the resource. If a local resource, this path is
1818
// rooted from the directory upon which `kustomize build` was invoked. If a
1919
// remote resource, this path is rooted from the root of the remote repo.
2020
Path string `json:"path,omitempty" yaml:"path,omitempty"`
2121

22-
// Repo is the remote repository that the resource originated from if it is
22+
// Repo is the remote repository that the resource or transformer originated from if it is
2323
// not from a local file
2424
Repo string `json:"repo,omitempty" yaml:"repo,omitempty"`
2525

26-
// Ref is the ref of the remote repository that the resource originated from
26+
// Ref is the ref of the remote repository that the resource or transformer originated from
2727
// if it is not from a local file
2828
Ref string `json:"ref,omitempty" yaml:"ref,omitempty"`
2929

3030
// The following fields only apply to resources that have been
31-
// generated by fields other than the `resources` field.
31+
// generated by fields other than the `resources` field, or to transformer
32+
// configs.
3233

33-
// ConfiguredIn is the file path to the generator config that created the
34+
// ConfiguredIn is the file path to the generator or transformer config that created the
3435
// resource
3536
ConfiguredIn string `json:"configuredIn,omitempty" yaml:"configuredIn,omitempty"`
3637

37-
// ConfiguredBy is the ObjectReference of the generator config
38+
// ConfiguredBy is the ObjectReference of the generator or transformer config
3839
ConfiguredBy kyaml.ResourceIdentifier `json:"configuredBy,omitempty" yaml:"configuredBy,omitempty"`
3940
}
4041

@@ -67,6 +68,17 @@ func (origin *Origin) String() (string, error) {
6768
return string(anno), err
6869
}
6970

71+
// Transformations is a list of Origin
72+
type Transformations []*Origin
73+
74+
// String returns a string version of Transformations
75+
func (transformations *Transformations) String() (string, error) {
76+
anno, err := kyaml.Marshal(transformations)
77+
return string(anno), err
78+
}
79+
80+
// OriginFromCustomPlugin takes a custom plugin defined as a resource
81+
// and returns an origin object to describe it
7082
func OriginFromCustomPlugin(res *Resource) (*Origin, error) {
7183
origin, err := res.GetOrigin()
7284
if err != nil {

api/resource/origin_test.go

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/stretchr/testify/assert"
1010
. "sigs.k8s.io/kustomize/api/resource"
11+
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
1112
)
1213

1314
func TestOriginAppend(t *testing.T) {
@@ -78,6 +79,82 @@ repo: github.com/kubernetes-sigs/kustomize/examples/multibases/dev/
7879
for _, test := range tests {
7980
actual, err := test.in.String()
8081
assert.NoError(t, err)
81-
assert.Equal(t, actual, test.expected)
82+
assert.Equal(t, test.expected, actual)
83+
}
84+
}
85+
86+
func TestTransformationsString(t *testing.T) {
87+
origin1 := &Origin{
88+
Repo: "github.com/myrepo",
89+
Ref: "master",
90+
ConfiguredIn: "config.yaml",
91+
ConfiguredBy: kyaml.ResourceIdentifier{
92+
TypeMeta: kyaml.TypeMeta{
93+
APIVersion: "builtin",
94+
Kind: "Generator",
95+
},
96+
NameMeta: kyaml.NameMeta{
97+
Name: "my-name",
98+
Namespace: "my-namespace",
99+
},
100+
},
101+
}
102+
origin2 := &Origin{
103+
ConfiguredIn: "../base/config.yaml",
104+
ConfiguredBy: kyaml.ResourceIdentifier{
105+
TypeMeta: kyaml.TypeMeta{
106+
APIVersion: "builtin",
107+
Kind: "Generator",
108+
},
109+
NameMeta: kyaml.NameMeta{
110+
Name: "my-name",
111+
Namespace: "my-namespace",
112+
},
113+
},
114+
}
115+
tests := []struct {
116+
in Transformations
117+
expected string
118+
}{
119+
{
120+
in: Transformations{origin1},
121+
expected: `- repo: github.com/myrepo
122+
ref: master
123+
configuredIn: config.yaml
124+
configuredBy:
125+
apiVersion: builtin
126+
kind: Generator
127+
name: my-name
128+
namespace: my-namespace
129+
`,
130+
},
131+
{
132+
in: Transformations{origin1, origin2},
133+
expected: `- repo: github.com/myrepo
134+
ref: master
135+
configuredIn: config.yaml
136+
configuredBy:
137+
apiVersion: builtin
138+
kind: Generator
139+
name: my-name
140+
namespace: my-namespace
141+
- configuredIn: ../base/config.yaml
142+
configuredBy:
143+
apiVersion: builtin
144+
kind: Generator
145+
name: my-name
146+
namespace: my-namespace
147+
`,
148+
},
149+
{
150+
in: Transformations{},
151+
expected: `[]
152+
`,
153+
},
154+
}
155+
for _, test := range tests {
156+
actual, err := test.in.String()
157+
assert.NoError(t, err)
158+
assert.Equal(t, test.expected, actual)
82159
}
83160
}

0 commit comments

Comments
 (0)