From 2c2c491f1c225706d7cefa9a1632e065332dbd04 Mon Sep 17 00:00:00 2001 From: magicsong Date: Thu, 12 Sep 2024 15:32:09 +0800 Subject: [PATCH] fix: support more fieldpath Signed-off-by: magicsong --- pkg/control/sidecarcontrol/util.go | 56 ++++++------ pkg/control/sidecarcontrol/util_test.go | 91 +++++++++++++++---- .../sidecarset_create_update_handler.go | 1 + 3 files changed, 99 insertions(+), 49 deletions(-) diff --git a/pkg/control/sidecarcontrol/util.go b/pkg/control/sidecarcontrol/util.go index b590f45848..a202d41d5e 100644 --- a/pkg/control/sidecarcontrol/util.go +++ b/pkg/control/sidecarcontrol/util.go @@ -33,11 +33,9 @@ import ( "github.com/openkruise/kruise/pkg/util/expectations" utilfeature "github.com/openkruise/kruise/pkg/util/feature" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/util/validation" "k8s.io/klog/v2" kubecontroller "k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/fieldpath" @@ -398,29 +396,7 @@ func GetSidecarTransferEnvs(sidecarContainer *appsv1alpha1.SidecarContainer, pod } func ExtractContainerNameFromFieldPath(fs *corev1.ObjectFieldSelector, pod *corev1.Pod) (string, error) { - fieldPath := fs.FieldPath - accessor, err := meta.Accessor(pod) - if err != nil { - return "", err - } - path, subscript, ok := fieldpath.SplitMaybeSubscriptedPath(fieldPath) - if ok { - switch path { - case "metadata.annotations": - if errs := validation.IsQualifiedName(strings.ToLower(subscript)); len(errs) != 0 { - return "", fmt.Errorf("invalid key subscript in %s: %s", fieldPath, strings.Join(errs, ";")) - } - return accessor.GetAnnotations()[subscript], nil - case "metadata.labels": - if errs := validation.IsQualifiedName(subscript); len(errs) != 0 { - return "", fmt.Errorf("invalid key subscript in %s: %s", fieldPath, strings.Join(errs, ";")) - } - return accessor.GetLabels()[subscript], nil - default: - return "", fmt.Errorf("fieldPath %q does not support subscript", fieldPath) - } - } - return "", fmt.Errorf("unsupported fieldPath: %v", fieldPath) + return fieldpath.ExtractFieldPathAsString(pod, fs.FieldPath) } // code lifted from https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/core/pods/helpers.go @@ -432,16 +408,38 @@ func ConvertDownwardAPIFieldLabel(version, label, value string) (string, string, if version != "v1" { return "", "", fmt.Errorf("unsupported pod version: %s", version) } - path, _, ok := fieldpath.SplitMaybeSubscriptedPath(label) - if ok { + + if path, _, ok := fieldpath.SplitMaybeSubscriptedPath(label); ok { switch path { case "metadata.annotations", "metadata.labels": return label, value, nil default: - return "", "", fmt.Errorf("field path not supported: %s", path) + return "", "", fmt.Errorf("field label does not support subscript: %s", label) } } - return "", "", fmt.Errorf("field label not supported: %s", label) + + switch label { + case "metadata.annotations", + "metadata.labels", + "metadata.name", + "metadata.namespace", + "metadata.uid", + "spec.nodeName", + "spec.restartPolicy", + "spec.serviceAccountName", + "spec.schedulerName", + "status.phase", + "status.hostIP", + "status.hostIPs", + "status.podIP", + "status.podIPs": + return label, value, nil + // This is for backwards compatibility with old v1 clients which send spec.host + case "spec.host": + return "spec.nodeName", value, nil + default: + return "", "", fmt.Errorf("field label not supported: %s", label) + } } // PatchPodMetadata patch pod annotations and labels diff --git a/pkg/control/sidecarcontrol/util_test.go b/pkg/control/sidecarcontrol/util_test.go index cff328d7f1..c34d07caef 100644 --- a/pkg/control/sidecarcontrol/util_test.go +++ b/pkg/control/sidecarcontrol/util_test.go @@ -470,36 +470,60 @@ func TestConvertDownwardAPIFieldLabel(t *testing.T) { expectedErr: true, }, { - version: "v1", - label: "metadata.name", - value: "test-pod", - expectedErr: true, + version: "v1", + label: "metadata.name", + value: "test-pod", + expectedLabel: "metadata.name", + expectedValue: "test-pod", }, { - version: "v1", - label: "metadata.annotations", - value: "myAnnoValue", - expectedErr: true, + version: "v1", + label: "metadata.annotations", + value: "myValue", + expectedLabel: "metadata.annotations", + expectedValue: "myValue", }, { - version: "v1", - label: "metadata.labels", - value: "myLabelValue", - expectedErr: true, + version: "v1", + label: "metadata.annotations['myKey']", + value: "myValue", + expectedLabel: "metadata.annotations['myKey']", + expectedValue: "myValue", }, { version: "v1", - label: "metadata.annotations['myAnnoKey']", - value: "myAnnoValue", - expectedLabel: "metadata.annotations['myAnnoKey']", - expectedValue: "myAnnoValue", + label: "spec.host", + value: "127.0.0.1", + expectedLabel: "spec.nodeName", + expectedValue: "127.0.0.1", }, { version: "v1", - label: "metadata.labels['myLabelKey']", - value: "myLabelValue", - expectedLabel: "metadata.labels['myLabelKey']", - expectedValue: "myLabelValue", + label: "status.podIPs", + value: "10.244.0.6,fd00::6", + expectedLabel: "status.podIPs", + expectedValue: "10.244.0.6,fd00::6", + }, + { + version: "v1", + label: "status.podIPs", + value: "10.244.0.6", + expectedLabel: "status.podIPs", + expectedValue: "10.244.0.6", + }, + { + version: "v1", + label: "status.hostIPs", + value: "10.244.0.6,fd00::6", + expectedLabel: "status.hostIPs", + expectedValue: "10.244.0.6,fd00::6", + }, + { + version: "v1", + label: "status.hostIPs", + value: "10.244.0.6", + expectedLabel: "status.hostIPs", + expectedValue: "10.244.0.6", }, } for _, tc := range testCases { @@ -561,6 +585,33 @@ func TestExtractContainerNameFromFieldPath(t *testing.T) { }}, expectedName: "test-pod-anno", }, + { + fieldSelector: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.name", + }, + pod: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod-anno", + Annotations: map[string]string{ + "test-anno": "test-pod-anno", + }, + }}, + expectedName: "test-pod-anno", + }, + { + fieldSelector: &corev1.ObjectFieldSelector{ + APIVersion: "v1", + FieldPath: "metadata.namespace", + }, + pod: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod-anno", + Namespace: "test-namespace", + Annotations: map[string]string{ + "test-anno": "test-pod-anno", + }, + }}, + expectedName: "test-namespace", + }, } for _, tc := range testCases { containerName, err := ExtractContainerNameFromFieldPath(tc.fieldSelector, tc.pod) diff --git a/pkg/webhook/sidecarset/validating/sidecarset_create_update_handler.go b/pkg/webhook/sidecarset/validating/sidecarset_create_update_handler.go index 4c1584c0f1..f9fd907aef 100644 --- a/pkg/webhook/sidecarset/validating/sidecarset_create_update_handler.go +++ b/pkg/webhook/sidecarset/validating/sidecarset_create_update_handler.go @@ -52,6 +52,7 @@ const ( var validDownwardAPIFieldPathExpressions = sets.NewString( "metadata.name", + "metadata.namespace", "metadata.labels", "metadata.annotations")