Skip to content

Commit

Permalink
feat: support labels key in transformer configuration (#5556)
Browse files Browse the repository at this point in the history
* feat: support labels key in transformer configuration

Allow the usage of a separate transformer configuration for the labels key,
similar to what is currently available for commonLabels and commonAnnotations.
This aims to provide the same functionality that commonLabels currently provide
for labels, since commonLabels is deprecated and slated for removal in a future
release.

* chore(transformerconfig): add nolint hint

Add a nolint hint to the new method so the returns can stay consistent with
one another.

* fix: changes from code review

* Rename methods `AddCommonLabelFieldSpec` and `AddLabelFieldSpec` to
  `AddCommonLabelsFieldSpec` and `AddLabelsFieldSpec`.
* Add extra test to verify scenarios applying labels to Custom Resource Definitions.
  • Loading branch information
stormqueen1990 authored Apr 25, 2024
1 parent 2e6171a commit 671de16
Show file tree
Hide file tree
Showing 8 changed files with 478 additions and 120 deletions.
2 changes: 1 addition & 1 deletion api/internal/accumulator/loadconfigfromcrds.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func loadCrdIntoConfig(
}
_, label := property.Extensions.GetString(xLabelSelector)
if label {
err = theConfig.AddLabelFieldSpec(
err = theConfig.AddCommonLabelsFieldSpec(
makeFs(theGvk, append(path, propName)))
if err != nil {
return
Expand Down
27 changes: 0 additions & 27 deletions api/internal/plugins/builtinconfig/loaddefaultconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,30 +70,3 @@ namoPrefix:
t.Fatalf("expected error %s, but got %s", errMsg, err)
}
}

// please remove this failing test after implements the labels support
func TestLoadDefaultConfigsFromFilesWithMissingFieldsLabels(t *testing.T) {
fSys := filesys.MakeFsInMemory()
filePathContainsTypo := "config_contains_typo.yaml"
if err := fSys.WriteFile(filePathContainsTypo, []byte(`
labels:
- path: spec/podTemplate/metadata/labels
create: true
kind: FlinkDeployment
`)); err != nil {
t.Fatal(err)
}
ldr, err := loader.NewLoader(
loader.RestrictionRootOnly, filesys.Separator, fSys)
if err != nil {
t.Fatal(err)
}
errMsg := "error unmarshaling JSON: while decoding JSON: json: unknown field"
_, err = loadDefaultConfig(ldr, []string{filePathContainsTypo})
if err == nil {
t.Fatalf("expected to fail unmarshal yaml, but got nil %s", filePathContainsTypo)
}
if !strings.Contains(err.Error(), errMsg) {
t.Fatalf("expected error %s, but got %s", errMsg, err)
}
}
17 changes: 15 additions & 2 deletions api/internal/plugins/builtinconfig/transformerconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type TransformerConfig struct {
NameSuffix types.FsSlice `json:"nameSuffix,omitempty" yaml:"nameSuffix,omitempty"`
NameSpace types.FsSlice `json:"namespace,omitempty" yaml:"namespace,omitempty"`
CommonLabels types.FsSlice `json:"commonLabels,omitempty" yaml:"commonLabels,omitempty"`
Labels types.FsSlice `json:"labels,omitempty" yaml:"labels,omitempty"`
TemplateLabels types.FsSlice `json:"templateLabels,omitempty" yaml:"templateLabels,omitempty"`
CommonAnnotations types.FsSlice `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"`
NameReference nbrSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"`
Expand All @@ -41,6 +42,7 @@ func (t *TransformerConfig) DeepCopy() *TransformerConfig {
NameSuffix: t.NameSuffix.DeepCopy(),
NameSpace: t.NameSpace.DeepCopy(),
CommonLabels: t.CommonLabels.DeepCopy(),
Labels: t.Labels.DeepCopy(),
TemplateLabels: t.TemplateLabels.DeepCopy(),
CommonAnnotations: t.CommonAnnotations.DeepCopy(),
NameReference: t.NameReference.DeepCopy(),
Expand Down Expand Up @@ -94,6 +96,7 @@ func (t *TransformerConfig) sortFields() {
sort.Sort(t.NameSuffix)
sort.Sort(t.NameSpace)
sort.Sort(t.CommonLabels)
sort.Sort(t.Labels)
sort.Sort(t.TemplateLabels)
sort.Sort(t.CommonAnnotations)
sort.Sort(t.NameReference)
Expand All @@ -114,12 +117,18 @@ func (t *TransformerConfig) AddSuffixFieldSpec(fs types.FieldSpec) (err error) {
return err
}

// AddLabelFieldSpec adds a FieldSpec to CommonLabels
func (t *TransformerConfig) AddLabelFieldSpec(fs types.FieldSpec) (err error) {
// AddCommonLabelsFieldSpec adds a FieldSpec to CommonLabels
func (t *TransformerConfig) AddCommonLabelsFieldSpec(fs types.FieldSpec) (err error) {
t.CommonLabels, err = t.CommonLabels.MergeOne(fs)
return err
}

// AddLabelsFieldSpec adds a FieldSpec to Labels
func (t *TransformerConfig) AddLabelsFieldSpec(fs types.FieldSpec) (err error) {
t.Labels, err = t.Labels.MergeOne(fs)
return err //nolint:wrapcheck
}

// AddAnnotationFieldSpec adds a FieldSpec to CommonAnnotations
func (t *TransformerConfig) AddAnnotationFieldSpec(fs types.FieldSpec) (err error) {
t.CommonAnnotations, err = t.CommonAnnotations.MergeOne(fs)
Expand Down Expand Up @@ -162,6 +171,10 @@ func (t *TransformerConfig) Merge(input *TransformerConfig) (
if err != nil {
return nil, errors.WrapPrefixf(err, "failed to merge CommonLabels fieldSpec")
}
merged.Labels, err = t.Labels.MergeAll(input.Labels)
if err != nil {
return nil, errors.WrapPrefixf(err, "failed to merge Labels fieldSpec")
}
merged.TemplateLabels, err = t.TemplateLabels.MergeAll(input.TemplateLabels)
if err != nil {
return nil, errors.WrapPrefixf(err, "failed to merge TemplateLabels fieldSpec")
Expand Down
118 changes: 42 additions & 76 deletions api/internal/plugins/builtinconfig/transformerconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
package builtinconfig_test

import (
"reflect"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
. "sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/resid"
Expand Down Expand Up @@ -35,13 +36,8 @@ func TestAddNamereferenceFieldSpec(t *testing.T) {
},
}

err := cfg.AddNamereferenceFieldSpec(nbrs)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if len(cfg.NameReference) != 1 {
t.Fatal("failed to add namereference FieldSpec")
}
require.NoError(t, cfg.AddNamereferenceFieldSpec(nbrs))
require.Len(t, cfg.NameReference, 1, "failed to add namereference FieldSpec")
}

func TestAddFieldSpecs(t *testing.T) {
Expand All @@ -53,34 +49,14 @@ func TestAddFieldSpecs(t *testing.T) {
CreateIfNotPresent: true,
}

err := cfg.AddPrefixFieldSpec(fieldSpec)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if len(cfg.NamePrefix) != 1 {
t.Fatalf("failed to add nameprefix FieldSpec")
}
err = cfg.AddSuffixFieldSpec(fieldSpec)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if len(cfg.NameSuffix) != 1 {
t.Fatalf("failed to add namesuffix FieldSpec")
}
err = cfg.AddLabelFieldSpec(fieldSpec)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if len(cfg.CommonLabels) != 1 {
t.Fatalf("failed to add nameprefix FieldSpec")
}
err = cfg.AddAnnotationFieldSpec(fieldSpec)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if len(cfg.CommonAnnotations) != 1 {
t.Fatalf("failed to add nameprefix FieldSpec")
}
require.NoError(t, cfg.AddPrefixFieldSpec(fieldSpec))
require.Len(t, cfg.NamePrefix, 1, "failed to add nameprefix FieldSpec")
require.NoError(t, cfg.AddSuffixFieldSpec(fieldSpec))
require.Len(t, cfg.NameSuffix, 1, "failed to add namesuffix FieldSpec")
require.NoError(t, cfg.AddCommonLabelsFieldSpec(fieldSpec))
require.Len(t, cfg.CommonLabels, 1, "failed to add labels FieldSpec")
require.NoError(t, cfg.AddAnnotationFieldSpec(fieldSpec))
require.Len(t, cfg.CommonAnnotations, 1, "failed to add nameprefix FieldSpec")
}

func TestMerge(t *testing.T) {
Expand Down Expand Up @@ -127,51 +103,43 @@ func TestMerge(t *testing.T) {
},
}
cfga := &TransformerConfig{}
cfga.AddNamereferenceFieldSpec(nameReference[0])
cfga.AddPrefixFieldSpec(fieldSpecs[0])
cfga.AddSuffixFieldSpec(fieldSpecs[0])
require.NoError(t, cfga.AddNamereferenceFieldSpec(nameReference[0]))
require.NoError(t, cfga.AddPrefixFieldSpec(fieldSpecs[0]))
require.NoError(t, cfga.AddSuffixFieldSpec(fieldSpecs[0]))
require.NoError(t, cfga.AddCommonLabelsFieldSpec(fieldSpecs[0]))
require.NoError(t, cfga.AddLabelsFieldSpec(fieldSpecs[0]))

cfgb := &TransformerConfig{}
cfgb.AddNamereferenceFieldSpec(nameReference[1])
cfgb.AddPrefixFieldSpec(fieldSpecs[1])
cfga.AddSuffixFieldSpec(fieldSpecs[1])
require.NoError(t, cfgb.AddNamereferenceFieldSpec(nameReference[1]))
require.NoError(t, cfgb.AddPrefixFieldSpec(fieldSpecs[1]))
require.NoError(t, cfgb.AddSuffixFieldSpec(fieldSpecs[1]))
require.NoError(t, cfgb.AddCommonLabelsFieldSpec(fieldSpecs[1]))
require.NoError(t, cfgb.AddLabelsFieldSpec(fieldSpecs[1]))

actual, err := cfga.Merge(cfgb)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}

if len(actual.NamePrefix) != 2 {
t.Fatal("merge failed for namePrefix FieldSpec")
}

if len(actual.NameSuffix) != 2 {
t.Fatal("merge failed for nameSuffix FieldSpec")
}

if len(actual.NameReference) != 1 {
t.Fatal("merge failed for namereference FieldSpec")
}
require.NoError(t, err)
require.Len(t, actual.NamePrefix, 2, "merge failed for namePrefix FieldSpec")
require.Len(t, actual.NameSuffix, 2, "merge failed for nameSuffix FieldSpec")
require.Len(t, actual.NameReference, 1, "merge failed for nameReference FieldSpec")
require.Len(t, actual.Labels, 2, "merge failed for labels FieldSpec")
require.Len(t, actual.CommonLabels, 2, "merge failed for commonLabels FieldSpec")

expected := &TransformerConfig{}
expected.AddNamereferenceFieldSpec(nameReference[0])
expected.AddNamereferenceFieldSpec(nameReference[1])
expected.AddPrefixFieldSpec(fieldSpecs[0])
expected.AddPrefixFieldSpec(fieldSpecs[1])
expected.AddSuffixFieldSpec(fieldSpecs[0])
expected.AddSuffixFieldSpec(fieldSpecs[1])

if !reflect.DeepEqual(actual, expected) {
t.Fatalf("expected: %v\n but got: %v\n", expected, actual)
}
require.NoError(t, expected.AddNamereferenceFieldSpec(nameReference[0]))
require.NoError(t, expected.AddNamereferenceFieldSpec(nameReference[1]))
require.NoError(t, expected.AddPrefixFieldSpec(fieldSpecs[0]))
require.NoError(t, expected.AddPrefixFieldSpec(fieldSpecs[1]))
require.NoError(t, expected.AddSuffixFieldSpec(fieldSpecs[0]))
require.NoError(t, expected.AddSuffixFieldSpec(fieldSpecs[1]))
require.NoError(t, expected.AddCommonLabelsFieldSpec(fieldSpecs[0]))
require.NoError(t, expected.AddCommonLabelsFieldSpec(fieldSpecs[1]))
require.NoError(t, expected.AddLabelsFieldSpec(fieldSpecs[0]))
require.NoError(t, expected.AddLabelsFieldSpec(fieldSpecs[1]))
require.Equal(t, expected, actual)

actual, err = cfga.Merge(nil)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
if !reflect.DeepEqual(actual, cfga) {
t.Fatalf("expected: %v\n but got: %v\n", cfga, actual)
}
require.NoError(t, err)
require.Equal(t, cfga, actual)
}

func TestMakeDefaultConfig_mutation(t *testing.T) {
Expand All @@ -182,9 +150,7 @@ func TestMakeDefaultConfig_mutation(t *testing.T) {
a.NameReference = a.NameReference[:1]

clean := MakeDefaultConfig()
if clean.NameReference[0].Kind == "mutated" {
t.Errorf("MakeDefaultConfig() did not return a clean copy: %+v", clean.NameReference)
}
assert.NotEqualf(t, "mutated", clean.NameReference[0].Kind, "MakeDefaultConfig() did not return a clean copy: %+v", clean.NameReference)
}

func BenchmarkMakeDefaultConfig(b *testing.B) {
Expand Down
29 changes: 20 additions & 9 deletions api/internal/target/kusttarget_configplugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,13 +275,25 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func(
if len(kt.kustomization.Labels) == 0 && len(kt.kustomization.CommonLabels) == 0 {
return
}

type labelStruct struct {
Labels map[string]string
FieldSpecs []types.FieldSpec
}

for _, label := range kt.kustomization.Labels {
var c struct {
Labels map[string]string
FieldSpecs []types.FieldSpec
}
var c labelStruct

c.Labels = label.Pairs
fss := types.FsSlice(label.FieldSpecs)

// merge labels specified in the label section of transformer configs
// these apply to selectors and templates
fss, err := fss.MergeAll(tc.Labels)
if err != nil {
return nil, fmt.Errorf("failed to merge labels: %w", err)
}

// merge the custom fieldSpecs with the default
if label.IncludeSelectors {
fss, err = fss.MergeAll(tc.CommonLabels)
Expand All @@ -297,7 +309,7 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func(
fss, err = fss.MergeOne(types.FieldSpec{Path: "metadata/labels", CreateIfNotPresent: true})
}
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to merge labels: %w", err)
}
c.FieldSpecs = fss
p := f()
Expand All @@ -307,10 +319,9 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func(
}
result = append(result, p)
}
var c struct {
Labels map[string]string
FieldSpecs []types.FieldSpec
}

var c labelStruct

c.Labels = kt.kustomization.CommonLabels
c.FieldSpecs = tc.CommonLabels
p := f()
Expand Down
4 changes: 1 addition & 3 deletions api/internal/target/kusttarget_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,7 @@ metadata:

expected := resmap.New()
for _, r := range resources {
if err := expected.Append(r); err != nil {
t.Fatalf("failed to append resource: %v", err)
}
require.NoError(t, expected.Append(r), "failed to append resource: %v")
}
expected.RemoveBuildAnnotations()
expYaml, err := expected.AsYaml()
Expand Down
Loading

0 comments on commit 671de16

Please sign in to comment.