Skip to content

Commit

Permalink
Propagate ResourceGroup labels and annotations
Browse files Browse the repository at this point in the history
When I declare a ResourceGroup on disk, I expect the labels and
annotations defined on it to be propagated to the in-cluster inventory.
That was previously not the case.

kioutil annotations are removed (path, index, etc) since they are
redundant for inventories that are typically defined in one place, and
don't need to be reconstructed by a function pipeline.

Signed-off-by: Fredrik Sommar <[email protected]>
  • Loading branch information
fsommar committed Jun 27, 2024
1 parent 9566954 commit 7264842
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 2 deletions.
24 changes: 24 additions & 0 deletions internal/pkg/pkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"os"
"path/filepath"
"sort"
"strings"

"github.com/GoogleContainerTools/kpt/internal/errors"
"github.com/GoogleContainerTools/kpt/internal/types"
Expand Down Expand Up @@ -736,9 +737,14 @@ func (p *Pkg) LocalInventory() (kptfilev1.Inventory, error) {
if !hasKptfile {
// Return the ResourceGroup object as inventory.
if len(resources) == 1 {
labels := resources[0].GetLabels()
delete(labels, rgfilev1alpha1.RGInventoryIDLabel)

return kptfilev1.Inventory{
Name: resources[0].GetName(),
Namespace: resources[0].GetNamespace(),
Annotations: resources[0].GetAnnotations(),
Labels: labels,
InventoryID: resources[0].GetLabels()[rgfilev1alpha1.RGInventoryIDLabel],
}, nil
}
Expand All @@ -764,9 +770,14 @@ func (p *Pkg) LocalInventory() (kptfilev1.Inventory, error) {

// ResourceGroup stores the inventory and Kptfile does not contain inventory.
if len(resources) == 1 {
labels := resources[0].GetLabels()
delete(labels, rgfilev1alpha1.RGInventoryIDLabel)

return kptfilev1.Inventory{
Name: resources[0].GetName(),
Namespace: resources[0].GetNamespace(),
Annotations: resources[0].GetAnnotations(),
Labels: labels,
InventoryID: resources[0].GetLabels()[rgfilev1alpha1.RGInventoryIDLabel],
}, nil
}
Expand All @@ -788,8 +799,21 @@ func filterResourceGroups(input []*yaml.RNode) (output []*yaml.RNode, err error)
continue
}

ClearInternalAnnotations(meta.Annotations)
if err := r.SetAnnotations(meta.Annotations); err != nil {
return nil, fmt.Errorf("failed to set annotations for resource %w", err)
}

output = append(output, r)
}

return output, nil
}

func ClearInternalAnnotations(annotations map[string]string) {
for k := range annotations {
if strings.HasPrefix(k, "internal.config.kubernetes.io/") || strings.HasPrefix(k, "config.kubernetes.io/") {
delete(annotations, k)
}
}
}
10 changes: 9 additions & 1 deletion internal/testutil/pkgbuilder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ func (sp *SubPkg) WithSubPackages(ps ...*SubPkg) *SubPkg {
// RGFile represents a minimal resourcegroup.
type RGFile struct {
Name, Namespace, ID string
Annotations, Labels map[string]string
}

func NewRGFile() *RGFile {
Expand Down Expand Up @@ -547,8 +548,15 @@ func buildRGFile(pkg *pkg) string {
tmp := rgfilev1alpha1.ResourceGroup{ResourceMeta: rgfilev1alpha1.DefaultMeta}
tmp.ObjectMeta.Name = pkg.RGFile.Name
tmp.ObjectMeta.Namespace = pkg.RGFile.Namespace
tmp.ObjectMeta.Annotations = pkg.RGFile.Annotations
tmp.ObjectMeta.Labels = pkg.RGFile.Labels

if tmp.ObjectMeta.Labels == nil {
tmp.ObjectMeta.Labels = make(map[string]string)
}

if pkg.RGFile.ID != "" {
tmp.ObjectMeta.Labels = map[string]string{rgfilev1alpha1.RGInventoryIDLabel: pkg.RGFile.ID}
tmp.ObjectMeta.Labels[rgfilev1alpha1.RGInventoryIDLabel] = pkg.RGFile.ID
}

b, err := yaml.MarshalWithOptions(tmp, &yaml.EncoderOptions{SeqIndent: yaml.WideSequenceStyle})
Expand Down
10 changes: 9 additions & 1 deletion pkg/live/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,18 @@ func readInvInfoFromStream(in io.Reader) (kptfilev1.Inventory, error) {
}
// Inventory found with ResourceGroup object.
if len(rgFilter.Inventories) == 1 {
invID := rgFilter.Inventories[0].Labels[rgfilev1alpha1.RGInventoryIDLabel]
labels := rgFilter.Inventories[0].Labels
invID := labels[rgfilev1alpha1.RGInventoryIDLabel]
delete(labels, rgfilev1alpha1.RGInventoryIDLabel)

annotations := rgFilter.Inventories[0].Annotations
pkg.ClearInternalAnnotations(annotations)

return kptfilev1.Inventory{
Name: rgFilter.Inventories[0].Name,
Namespace: rgFilter.Inventories[0].Namespace,
Annotations: annotations,
Labels: labels,
InventoryID: invID,
}, nil
}
Expand Down
78 changes: 78 additions & 0 deletions pkg/live/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,36 @@ func TestLoad_LocalDisk(t *testing.T) {
},
rgFile: "resourcegroup.yaml",
},
"Inventory information taken from resourcegroup in file": {
pkg: pkgbuilder.NewRootPkg().
WithKptfile(
pkgbuilder.NewKptfile(),
).WithRGFile(&pkgbuilder.RGFile{
Name: "foo",
Namespace: "bar",
Annotations: map[string]string{
"additional-annotation": "true",
},
Labels: map[string]string{
"cli-utils.sigs.k8s.io/inventory-id": "foo-bar",
"additional-label": "true",
},
}),
namespace: "foo",
expectedObjs: []object.ObjMetadata{},
expectedInv: kptfile.Inventory{
Name: "foo",
Namespace: "bar",
InventoryID: "foo-bar",
Annotations: map[string]string{
"additional-annotation": "true",
},
Labels: map[string]string{
"additional-label": "true",
},
},
rgFile: "inventory.yaml",
},
}

for tn, tc := range testCases {
Expand Down Expand Up @@ -239,6 +269,14 @@ func TestLoad_LocalDisk(t *testing.T) {
})
assert.Equal(t, tc.expectedObjs, objMetas)

// Simplify testing against empty labels and annotations
if len(inv.Labels) == 0 {
inv.Labels = nil
}
if len(inv.Annotations) == 0 {
inv.Annotations = nil
}

assert.Equal(t, tc.expectedInv, inv)
})
}
Expand Down Expand Up @@ -380,6 +418,39 @@ func TestLoad_StdIn(t *testing.T) {
},
},
},
"Inventory using STDIN resourcegroup file with annotations": {
pkg: pkgbuilder.NewRootPkg().
WithKptfile(
pkgbuilder.NewKptfile(),
).
WithFile("cm.yaml", configMap).
WithRGFile(&pkgbuilder.RGFile{
Name: "foo",
Namespace: "bar",
ID: "foo-bar",
Annotations: map[string]string{
"extra-annotation": "hello-world",
},
}),
namespace: "foo",
expectedInv: kptfile.Inventory{
Name: "foo",
Namespace: "bar",
InventoryID: "foo-bar",
Annotations: map[string]string{
"extra-annotation": "hello-world",
},
},
expectedObjs: []object.ObjMetadata{
{
GroupKind: schema.GroupKind{
Kind: "ConfigMap",
},
Name: "cm",
Namespace: "foo",
},
},
},
"Multiple inventories using STDIN resourcegroup and Kptfile is error": {
pkg: pkgbuilder.NewRootPkg().
WithKptfile(
Expand Down Expand Up @@ -479,6 +550,13 @@ func TestLoad_StdIn(t *testing.T) {
})
assert.Equal(t, tc.expectedObjs, objMetas)

// Simplify testing against empty labels and annotations
if len(inv.Annotations) == 0 {
inv.Annotations = nil
}
if len(inv.Labels) == 0 {
inv.Labels = nil
}
assert.Equal(t, tc.expectedInv, inv)
})
}
Expand Down

0 comments on commit 7264842

Please sign in to comment.