This is an automated email from the ASF dual-hosted git repository.

chenyulin0719 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/yunikorn-k8shim.git


The following commit(s) were added to refs/heads/master by this push:
     new 223e1f3b [YUNIKORN-2631] Support canonical labels for 
queue/applicationId in Admission Controller (#843)
223e1f3b is described below

commit 223e1f3b69262a379a2f19efd2294cd7597d8f77
Author: Yu-Lin Chen <[email protected]>
AuthorDate: Sat Jun 8 05:50:55 2024 +0000

    [YUNIKORN-2631] Support canonical labels for queue/applicationId in 
Admission Controller (#843)
    
    Add canonical representations when Admission Controller try to patch 
queue/applicationID to pod
    
    Closes: #843
    
    Signed-off-by: Yu-Lin Chen <[email protected]>
---
 pkg/admission/admission_controller.go      |  2 +-
 pkg/admission/admission_controller_test.go | 32 +++++++++++++++-------
 pkg/admission/util.go                      | 17 ++++++++++--
 pkg/admission/util_test.go                 | 44 +++++++++++++++++++++---------
 pkg/common/constants/constants.go          |  2 ++
 5 files changed, 71 insertions(+), 26 deletions(-)

diff --git a/pkg/admission/admission_controller.go 
b/pkg/admission/admission_controller.go
index 3b058da6..35c3fecb 100644
--- a/pkg/admission/admission_controller.go
+++ b/pkg/admission/admission_controller.go
@@ -322,7 +322,7 @@ func (c *AdmissionController) processPodUpdate(req 
*admissionv1.AdmissionRequest
 
 func (c *AdmissionController) shouldProcessAdmissionReview(namespace string, 
labels map[string]string) bool {
        if c.shouldProcessNamespace(namespace) &&
-               (labels[constants.LabelApplicationID] != "" || 
labels[constants.SparkLabelAppID] != "" || c.shouldLabelNamespace(namespace)) {
+               (labels[constants.CanonicalLabelApplicationID] != "" || 
labels[constants.LabelApplicationID] != "" || labels[constants.SparkLabelAppID] 
!= "" || c.shouldLabelNamespace(namespace)) {
                return true
        }
 
diff --git a/pkg/admission/admission_controller_test.go 
b/pkg/admission/admission_controller_test.go
index 88bf8d6a..e5c66189 100644
--- a/pkg/admission/admission_controller_test.go
+++ b/pkg/admission/admission_controller_test.go
@@ -81,9 +81,11 @@ func TestUpdateLabels(t *testing.T) {
        assert.Equal(t, patch[0].Op, "add")
        assert.Equal(t, patch[0].Path, "/metadata/labels")
        if updatedMap, ok := patch[0].Value.(map[string]string); ok {
-               assert.Equal(t, len(updatedMap), 3)
+               assert.Equal(t, len(updatedMap), 5)
                assert.Equal(t, updatedMap["random"], "random")
+               assert.Equal(t, updatedMap[constants.CanonicalLabelQueueName], 
"root.default")
                assert.Equal(t, updatedMap[constants.LabelQueueName], 
"root.default")
+               assert.Equal(t, 
strings.HasPrefix(updatedMap[constants.CanonicalLabelApplicationID], 
constants.AutoGenAppPrefix), true)
                assert.Equal(t, 
strings.HasPrefix(updatedMap[constants.LabelApplicationID], 
constants.AutoGenAppPrefix), true)
        } else {
                t.Fatal("patch info content is not as expected")
@@ -104,8 +106,8 @@ func TestUpdateLabels(t *testing.T) {
                        UID:             "7f5fd6c5d5",
                        ResourceVersion: "10654",
                        Labels: map[string]string{
-                               "random":                     "random",
-                               constants.LabelApplicationID: "app-0001",
+                               "random":                              "random",
+                               constants.CanonicalLabelApplicationID: 
"app-0001",
                        },
                },
                Spec:   v1.PodSpec{},
@@ -117,9 +119,11 @@ func TestUpdateLabels(t *testing.T) {
        assert.Equal(t, patch[0].Op, "add")
        assert.Equal(t, patch[0].Path, "/metadata/labels")
        if updatedMap, ok := patch[0].Value.(map[string]string); ok {
-               assert.Equal(t, len(updatedMap), 3)
+               assert.Equal(t, len(updatedMap), 5)
                assert.Equal(t, updatedMap["random"], "random")
+               assert.Equal(t, updatedMap[constants.CanonicalLabelQueueName], 
"root.default")
                assert.Equal(t, updatedMap[constants.LabelQueueName], 
"root.default")
+               assert.Equal(t, 
updatedMap[constants.CanonicalLabelApplicationID], "app-0001")
                assert.Equal(t, updatedMap[constants.LabelApplicationID], 
"app-0001")
        } else {
                t.Fatal("patch info content is not as expected")
@@ -140,8 +144,8 @@ func TestUpdateLabels(t *testing.T) {
                        UID:             "7f5fd6c5d5",
                        ResourceVersion: "10654",
                        Labels: map[string]string{
-                               "random":                 "random",
-                               constants.LabelQueueName: "root.abc",
+                               "random":                          "random",
+                               constants.CanonicalLabelQueueName: "root.abc",
                        },
                },
                Spec:   v1.PodSpec{},
@@ -154,9 +158,11 @@ func TestUpdateLabels(t *testing.T) {
        assert.Equal(t, patch[0].Op, "add")
        assert.Equal(t, patch[0].Path, "/metadata/labels")
        if updatedMap, ok := patch[0].Value.(map[string]string); ok {
-               assert.Equal(t, len(updatedMap), 3)
+               assert.Equal(t, len(updatedMap), 5)
                assert.Equal(t, updatedMap["random"], "random")
+               assert.Equal(t, updatedMap[constants.CanonicalLabelQueueName], 
"root.abc")
                assert.Equal(t, updatedMap[constants.LabelQueueName], 
"root.abc")
+               assert.Equal(t, 
strings.HasPrefix(updatedMap[constants.CanonicalLabelApplicationID], 
constants.AutoGenAppPrefix), true)
                assert.Equal(t, 
strings.HasPrefix(updatedMap[constants.LabelApplicationID], 
constants.AutoGenAppPrefix), true)
        } else {
                t.Fatal("patch info content is not as expected")
@@ -186,8 +192,10 @@ func TestUpdateLabels(t *testing.T) {
        assert.Equal(t, patch[0].Op, "add")
        assert.Equal(t, patch[0].Path, "/metadata/labels")
        if updatedMap, ok := patch[0].Value.(map[string]string); ok {
-               assert.Equal(t, len(updatedMap), 2)
+               assert.Equal(t, len(updatedMap), 4)
+               assert.Equal(t, updatedMap[constants.CanonicalLabelQueueName], 
"root.default")
                assert.Equal(t, updatedMap[constants.LabelQueueName], 
"root.default")
+               assert.Equal(t, 
strings.HasPrefix(updatedMap[constants.CanonicalLabelApplicationID], 
constants.AutoGenAppPrefix), true)
                assert.Equal(t, 
strings.HasPrefix(updatedMap[constants.LabelApplicationID], 
constants.AutoGenAppPrefix), true)
        } else {
                t.Fatal("patch info content is not as expected")
@@ -214,8 +222,10 @@ func TestUpdateLabels(t *testing.T) {
        assert.Equal(t, patch[0].Op, "add")
        assert.Equal(t, patch[0].Path, "/metadata/labels")
        if updatedMap, ok := patch[0].Value.(map[string]string); ok {
-               assert.Equal(t, len(updatedMap), 2)
+               assert.Equal(t, len(updatedMap), 4)
+               assert.Equal(t, updatedMap[constants.CanonicalLabelQueueName], 
"root.default")
                assert.Equal(t, updatedMap[constants.LabelQueueName], 
"root.default")
+               assert.Equal(t, 
strings.HasPrefix(updatedMap[constants.CanonicalLabelApplicationID], 
constants.AutoGenAppPrefix), true)
                assert.Equal(t, 
strings.HasPrefix(updatedMap[constants.LabelApplicationID], 
constants.AutoGenAppPrefix), true)
        } else {
                t.Fatal("patch info content is not as expected")
@@ -240,8 +250,10 @@ func TestUpdateLabels(t *testing.T) {
        assert.Equal(t, patch[0].Op, "add")
        assert.Equal(t, patch[0].Path, "/metadata/labels")
        if updatedMap, ok := patch[0].Value.(map[string]string); ok {
-               assert.Equal(t, len(updatedMap), 2)
+               assert.Equal(t, len(updatedMap), 4)
+               assert.Equal(t, updatedMap[constants.CanonicalLabelQueueName], 
"root.default")
                assert.Equal(t, updatedMap[constants.LabelQueueName], 
"root.default")
+               assert.Equal(t, 
strings.HasPrefix(updatedMap[constants.CanonicalLabelApplicationID], 
constants.AutoGenAppPrefix), true)
                assert.Equal(t, 
strings.HasPrefix(updatedMap[constants.LabelApplicationID], 
constants.AutoGenAppPrefix), true)
        } else {
                t.Fatal("patch info content is not as expected")
diff --git a/pkg/admission/util.go b/pkg/admission/util.go
index fe994da7..5276b5b6 100644
--- a/pkg/admission/util.go
+++ b/pkg/admission/util.go
@@ -35,10 +35,11 @@ func updatePodLabel(pod *v1.Pod, namespace string, 
generateUniqueAppIds bool, de
                result[k] = v
        }
 
+       canonicalAppID := utils.GetPodLabelValue(pod, 
constants.CanonicalLabelApplicationID)
        sparkAppID := utils.GetPodLabelValue(pod, constants.SparkLabelAppID)
        labelAppID := utils.GetPodLabelValue(pod, constants.LabelApplicationID)
        annotationAppID := utils.GetPodAnnotationValue(pod, 
constants.AnnotationApplicationID)
-       if sparkAppID == "" && labelAppID == "" && annotationAppID == "" {
+       if canonicalAppID == "" && sparkAppID == "" && labelAppID == "" && 
annotationAppID == "" {
                // if app id not exist, generate one
                // for each namespace, we group unnamed pods to one single app 
- if GenerateUniqueAppId is not set
                // if GenerateUniqueAppId:
@@ -46,19 +47,31 @@ func updatePodLabel(pod *v1.Pod, namespace string, 
generateUniqueAppIds bool, de
                // else
                //              application ID convention: 
${AUTO_GEN_PREFIX}-${NAMESPACE}-${AUTO_GEN_SUFFIX}
                generatedID := utils.GenerateApplicationID(namespace, 
generateUniqueAppIds, string(pod.UID))
+
+               result[constants.CanonicalLabelApplicationID] = generatedID
+               // Deprecated: After 1.7.0, admission controller will only add 
canonical label if application ID was not set
                result[constants.LabelApplicationID] = generatedID
+       } else if canonicalAppID != "" {
+               // Deprecated: Added in 1.6.0 for backward compatibility, in 
case the prior shim version can't handle canonical label
+               result[constants.LabelApplicationID] = canonicalAppID
        }
 
+       canonicalQueueName := utils.GetPodLabelValue(pod, 
constants.CanonicalLabelQueueName)
        labelQueueName := utils.GetPodLabelValue(pod, constants.LabelQueueName)
        annotationQueueName := utils.GetPodAnnotationValue(pod, 
constants.AnnotationQueueName)
-       if labelQueueName == "" && annotationQueueName == "" {
+       if canonicalQueueName == "" && labelQueueName == "" && 
annotationQueueName == "" {
                // if queueName not exist, generate one
                // if defaultQueueName is "", skip adding default queue name to 
the pod labels
                if defaultQueueName != "" {
                        // for undefined configuration, am_conf will add 
'root.default' to retain existing behavior
                        // if a custom name is configured for default queue, it 
will be used instead of root.default
+                       result[constants.CanonicalLabelQueueName] = 
defaultQueueName
+                       // Deprecated: After 1.7.0, admission controller will 
only add canonical label if queue was not set
                        result[constants.LabelQueueName] = defaultQueueName
                }
+       } else if canonicalQueueName != "" {
+               // Deprecated: Added in 1.6.0 for backward compatibility, in 
case the prior shim version can't handle canonical label
+               result[constants.LabelQueueName] = canonicalQueueName
        }
 
        return result
diff --git a/pkg/admission/util_test.go b/pkg/admission/util_test.go
index fa28c824..2181bd5a 100644
--- a/pkg/admission/util_test.go
+++ b/pkg/admission/util_test.go
@@ -70,8 +70,8 @@ func createTestingPodWithMeta() *v1.Pod {
 
 func createTestingPodWithLabels(appId string, queue string) *v1.Pod {
        pod := createTestingPodWithMeta()
-       pod.ObjectMeta.Labels[constants.LabelApplicationID] = appId
-       pod.ObjectMeta.Labels[constants.LabelQueueName] = queue
+       pod.ObjectMeta.Labels[constants.CanonicalLabelApplicationID] = appId
+       pod.ObjectMeta.Labels[constants.CanonicalLabelQueueName] = queue
 
        return pod
 }
@@ -111,21 +111,25 @@ func TestUpdatePodLabelForAdmissionController(t 
*testing.T) {
        // we generate new appId/queue labels
        pod := createTestingPodWithMeta()
        if result := updatePodLabel(pod, "default", false, defaultQueueName); 
result != nil {
-               assert.Equal(t, len(result), 3)
+               assert.Equal(t, len(result), 5)
                assert.Equal(t, result["random"], "random")
+               assert.Equal(t, 
strings.HasPrefix(result[constants.CanonicalLabelApplicationID], 
constants.AutoGenAppPrefix), true)
                assert.Equal(t, 
strings.HasPrefix(result[constants.LabelApplicationID], 
constants.AutoGenAppPrefix), true)
+               assert.Equal(t, result[constants.CanonicalLabelQueueName], 
defaultQueueName)
                assert.Equal(t, result[constants.LabelQueueName], 
defaultQueueName)
        } else {
                t.Fatal("UpdatePodLabelForAdmissionController is not as 
expected")
        }
 
-       // verify if applicationId and queue is given in the labels,
-       // we won't modify it
+       // verify if appId/queue is given in the canonical labels
+       // we won't modify the value and will add it to non-canonical label for 
backward compatibility
        pod = createTestingPodWithLabels(dummyAppId, dummyQueueName)
        if result := updatePodLabel(pod, "default", false, defaultQueueName); 
result != nil {
-               assert.Equal(t, len(result), 3)
+               assert.Equal(t, len(result), 5)
                assert.Equal(t, result["random"], "random")
+               assert.Equal(t, result[constants.CanonicalLabelApplicationID], 
dummyAppId)
                assert.Equal(t, result[constants.LabelApplicationID], 
dummyAppId)
+               assert.Equal(t, result[constants.CanonicalLabelQueueName], 
dummyQueueName)
                assert.Equal(t, result[constants.LabelQueueName], 
dummyQueueName)
        } else {
                t.Fatal("UpdatePodLabelForAdmissionController is not as 
expected")
@@ -147,8 +151,10 @@ func TestUpdatePodLabelForAdmissionController(t 
*testing.T) {
        pod = createTestingPodNoNamespaceAndLabels()
 
        if result := updatePodLabel(pod, "default", false, defaultQueueName); 
result != nil {
-               assert.Equal(t, len(result), 2)
+               assert.Equal(t, len(result), 4)
+               assert.Equal(t, result[constants.CanonicalLabelQueueName], 
defaultQueueName)
                assert.Equal(t, result[constants.LabelQueueName], 
defaultQueueName)
+               assert.Equal(t, 
strings.HasPrefix(result[constants.CanonicalLabelApplicationID], 
constants.AutoGenAppPrefix), true)
                assert.Equal(t, 
strings.HasPrefix(result[constants.LabelApplicationID], 
constants.AutoGenAppPrefix), true)
        } else {
                t.Fatal("UpdatePodLabelForAdmissionController is not as 
expected")
@@ -157,8 +163,10 @@ func TestUpdatePodLabelForAdmissionController(t 
*testing.T) {
        // pod name might be empty, it can comes from generatedName
        pod = createTestingPodWithGenerateName()
        if result := updatePodLabel(pod, "default", false, defaultQueueName); 
result != nil {
-               assert.Equal(t, len(result), 2)
+               assert.Equal(t, len(result), 4)
+               assert.Equal(t, result[constants.CanonicalLabelQueueName], 
defaultQueueName)
                assert.Equal(t, result[constants.LabelQueueName], 
defaultQueueName)
+               assert.Equal(t, 
strings.HasPrefix(result[constants.CanonicalLabelApplicationID], 
constants.AutoGenAppPrefix), true)
                assert.Equal(t, 
strings.HasPrefix(result[constants.LabelApplicationID], 
constants.AutoGenAppPrefix), true)
        } else {
                t.Fatal("UpdatePodLabelForAdmissionController is not as 
expected")
@@ -166,8 +174,10 @@ func TestUpdatePodLabelForAdmissionController(t 
*testing.T) {
 
        pod = createMinimalTestingPod()
        if result := updatePodLabel(pod, "default", false, defaultQueueName); 
result != nil {
-               assert.Equal(t, len(result), 2)
+               assert.Equal(t, len(result), 4)
+               assert.Equal(t, result[constants.CanonicalLabelQueueName], 
defaultQueueName)
                assert.Equal(t, result[constants.LabelQueueName], 
defaultQueueName)
+               assert.Equal(t, 
strings.HasPrefix(result[constants.CanonicalLabelApplicationID], 
constants.AutoGenAppPrefix), true)
                assert.Equal(t, 
strings.HasPrefix(result[constants.LabelApplicationID], 
constants.AutoGenAppPrefix), true)
        } else {
                t.Fatal("UpdatePodLabelForAdmissionController is not as 
expected")
@@ -178,9 +188,11 @@ func TestDefaultQueueName(t *testing.T) {
        defaultConf := createConfig()
        pod := createTestingPodWithMeta()
        if result := updatePodLabel(pod, defaultConf.GetNamespace(), 
defaultConf.GetGenerateUniqueAppIds(), defaultConf.GetDefaultQueueName()); 
result != nil {
-               assert.Equal(t, len(result), 3)
+               assert.Equal(t, len(result), 5)
                assert.Equal(t, result["random"], "random")
+               assert.Equal(t, result[constants.CanonicalLabelApplicationID], 
"yunikorn-default-autogen")
                assert.Equal(t, result[constants.LabelApplicationID], 
"yunikorn-default-autogen")
+               assert.Equal(t, result[constants.CanonicalLabelQueueName], 
"root.default")
                assert.Equal(t, result[constants.LabelQueueName], 
"root.default")
        } else {
                t.Fatal("UpdatePodLabelForAdmissionController is not as 
expected")
@@ -190,9 +202,11 @@ func TestDefaultQueueName(t *testing.T) {
                conf.AMFilteringDefaultQueueName: "",
        })
        if result := updatePodLabel(pod, queueNameEmptyConf.GetNamespace(), 
queueNameEmptyConf.GetGenerateUniqueAppIds(), 
queueNameEmptyConf.GetDefaultQueueName()); result != nil {
-               assert.Equal(t, len(result), 2)
+               assert.Equal(t, len(result), 3)
                assert.Equal(t, result["random"], "random")
+               assert.Equal(t, result[constants.CanonicalLabelApplicationID], 
"yunikorn-default-autogen")
                assert.Equal(t, result[constants.LabelApplicationID], 
"yunikorn-default-autogen")
+               assert.Equal(t, result[constants.CanonicalLabelQueueName], "")
                assert.Equal(t, result[constants.LabelQueueName], "")
        } else {
                t.Fatal("UpdatePodLabelForAdmissionController is not as 
expected")
@@ -202,9 +216,11 @@ func TestDefaultQueueName(t *testing.T) {
                conf.AMFilteringDefaultQueueName: "yunikorn",
        })
        if result := updatePodLabel(pod, customQueueNameConf.GetNamespace(), 
customQueueNameConf.GetGenerateUniqueAppIds(), 
customQueueNameConf.GetDefaultQueueName()); result != nil {
-               assert.Equal(t, len(result), 3)
+               assert.Equal(t, len(result), 5)
                assert.Equal(t, result["random"], "random")
+               assert.Equal(t, result[constants.CanonicalLabelApplicationID], 
"yunikorn-default-autogen")
                assert.Equal(t, result[constants.LabelApplicationID], 
"yunikorn-default-autogen")
+               assert.Assert(t, result[constants.CanonicalLabelQueueName] != 
"yunikorn")
                assert.Assert(t, result[constants.LabelQueueName] != "yunikorn")
        } else {
                t.Fatal("UpdatePodLabelForAdmissionController is not as 
expected")
@@ -215,9 +231,11 @@ func TestDefaultQueueName(t *testing.T) {
        })
        if result := updatePodLabel(pod, 
customValidQueueNameConf.GetNamespace(),
                customValidQueueNameConf.GetGenerateUniqueAppIds(), 
customValidQueueNameConf.GetDefaultQueueName()); result != nil {
-               assert.Equal(t, len(result), 3)
+               assert.Equal(t, len(result), 5)
                assert.Equal(t, result["random"], "random")
+               assert.Equal(t, result[constants.CanonicalLabelApplicationID], 
"yunikorn-default-autogen")
                assert.Equal(t, result[constants.LabelApplicationID], 
"yunikorn-default-autogen")
+               assert.Equal(t, result[constants.CanonicalLabelQueueName], 
"root.yunikorn")
                assert.Equal(t, result[constants.LabelQueueName], 
"root.yunikorn")
        } else {
                t.Fatal("UpdatePodLabelForAdmissionController is not as 
expected")
diff --git a/pkg/common/constants/constants.go 
b/pkg/common/constants/constants.go
index 7a4c415d..bdee70a8 100644
--- a/pkg/common/constants/constants.go
+++ b/pkg/common/constants/constants.go
@@ -38,9 +38,11 @@ const DomainYuniKornInternal = 
siCommon.DomainYuniKornInternal
 const LabelApp = "app"
 const LabelApplicationID = "applicationId"
 const AnnotationApplicationID = DomainYuniKorn + "app-id"
+const CanonicalLabelApplicationID = DomainYuniKorn + "app-id"
 const LabelQueueName = "queue"
 const RootQueue = "root"
 const AnnotationQueueName = DomainYuniKorn + "queue"
+const CanonicalLabelQueueName = DomainYuniKorn + "queue"
 const AnnotationParentQueue = DomainYuniKorn + "parentqueue"
 const ApplicationDefaultQueue = "root.default"
 const DefaultPartition = "default"


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to