Skip to content
This repository was archived by the owner on Apr 25, 2023. It is now read-only.

Commit 7050eb0

Browse files
authored
Merge pull request #1086 from marun/federate-remove-metadata
Remove all metadata fields but labels from targets of kf federate
2 parents eef16b5 + e8fb05b commit 7050eb0

File tree

4 files changed

+48
-15
lines changed

4 files changed

+48
-15
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
# Unreleased
2+
- [#1086](https://github.com/kubernetes-sigs/kubefed/pull/1086)
3+
`kubefedctl federate` now removes all metadata fields except labels
4+
from the template of federated resources created from a
5+
non-federated resource. Previously `metadata.annotations` and
6+
`metadata.finalizers` were not removed which could result in
7+
propagation errors.
28
- [#1079](https://github.com/kubernetes-sigs/kubefed/issues/1079) The
39
spec field is now required in generated federated types. For types
410
generated previously, a check has been added so that a missing spec

pkg/kubefedctl/federate/federate.go

+18-3
Original file line numberDiff line numberDiff line change
@@ -361,8 +361,10 @@ func FederatedResourceFromTargetResource(typeConfig typeconfig.Interface, resour
361361
fedAPIResource := typeConfig.GetFederatedType()
362362
targetResource := resource.DeepCopy()
363363

364+
targetKind := typeConfig.GetTargetType().Kind
365+
364366
// Special handling is needed for some controller set fields.
365-
switch typeConfig.GetTargetType().Kind {
367+
switch targetKind {
366368
case ctlutil.NamespaceKind:
367369
{
368370
unstructured.RemoveNestedField(targetResource.Object, "spec", "finalizers")
@@ -397,9 +399,22 @@ func FederatedResourceFromTargetResource(typeConfig typeconfig.Interface, resour
397399
resourceNamespace := getNamespace(typeConfig, qualifiedName)
398400
fedResource := &unstructured.Unstructured{}
399401
SetBasicMetaFields(fedResource, fedAPIResource, qualifiedName.Name, resourceNamespace, "")
400-
RemoveUnwantedFields(targetResource)
401402

402-
err := unstructured.SetNestedField(fedResource.Object, targetResource.Object, ctlutil.SpecField, ctlutil.TemplateField)
403+
// Warn if annotations are present in case the intention is to
404+
// define annotations in the template of the federated resource.
405+
annotations, _, err := unstructured.NestedMap(targetResource.Object, "metadata", "annotations")
406+
if err != nil {
407+
return nil, errors.Wrap(err, "Failed to retrieve metadata.annotations")
408+
}
409+
if len(annotations) > 0 {
410+
klog.Warningf("Annotations defined for %s %q will not appear in the template of the federated resource: %v", targetKind, qualifiedName, annotations)
411+
}
412+
413+
if err := RemoveUnwantedFields(targetResource); err != nil {
414+
return nil, err
415+
}
416+
417+
err = unstructured.SetNestedField(fedResource.Object, targetResource.Object, ctlutil.SpecField, ctlutil.TemplateField)
403418
if err != nil {
404419
return nil, err
405420
}

pkg/kubefedctl/federate/util.go

+18-10
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,27 @@ import (
3838
"sigs.k8s.io/kubefed/pkg/kubefedctl/util"
3939
)
4040

41-
var systemMetadataFields = []string{"selfLink", "uid", "resourceVersion", "generation", "creationTimestamp", "deletionTimestamp", "deletionGracePeriodSeconds"}
42-
43-
func RemoveUnwantedFields(resource *unstructured.Unstructured) {
44-
for _, field := range systemMetadataFields {
45-
unstructured.RemoveNestedField(resource.Object, "metadata", field)
46-
// For resources with pod template subresource (jobs, deployments, replicasets)
47-
unstructured.RemoveNestedField(resource.Object, "spec", "template", "metadata", field)
48-
}
49-
unstructured.RemoveNestedField(resource.Object, "metadata", "name")
50-
unstructured.RemoveNestedField(resource.Object, "metadata", "namespace")
41+
func RemoveUnwantedFields(resource *unstructured.Unstructured) error {
5142
unstructured.RemoveNestedField(resource.Object, "apiVersion")
5243
unstructured.RemoveNestedField(resource.Object, "kind")
5344
unstructured.RemoveNestedField(resource.Object, "status")
45+
46+
// All metadata fields save labels should be cleared. Other
47+
// metadata fields will be set by the system on creation or
48+
// subsequently by controllers.
49+
labels, _, err := unstructured.NestedMap(resource.Object, "metadata", "labels")
50+
if err != nil {
51+
return errors.Wrap(err, "Failed to retrieve metadata.labels")
52+
}
53+
unstructured.RemoveNestedField(resource.Object, "metadata")
54+
if len(labels) > 0 {
55+
err := unstructured.SetNestedMap(resource.Object, labels, "metadata", "labels")
56+
if err != nil {
57+
return errors.Wrap(err, "Failed to set metadata.labels")
58+
}
59+
}
60+
61+
return nil
5462
}
5563

5664
func SetBasicMetaFields(resource *unstructured.Unstructured, apiResource metav1.APIResource, name, namespace, generateName string) {

test/e2e/federate.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,12 @@ func validateTemplateEquality(tl common.TestLogger, fedResource, targetResource
264264

265265
expectedResource := &unstructured.Unstructured{}
266266
expectedResource.Object = templateMap.(map[string]interface{})
267-
federate.RemoveUnwantedFields(expectedResource)
268-
federate.RemoveUnwantedFields(targetResource)
267+
if err := federate.RemoveUnwantedFields(expectedResource); err != nil {
268+
tl.Fatalf("Failed to remove unwanted fields from expected resource: %v", err)
269+
}
270+
if err := federate.RemoveUnwantedFields(targetResource); err != nil {
271+
tl.Fatalf("Failed to remove unwanted fields from target resource: %v", err)
272+
}
269273
if kind == util.NamespaceKind {
270274
unstructured.RemoveNestedField(targetResource.Object, "spec", "finalizers")
271275
}

0 commit comments

Comments
 (0)