Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Pod annotations for Service type change #1936

Merged
merged 6 commits into from
Apr 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions pkg/agent/nodeportlocal/k8s/npl_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,22 @@ func (c *NPLController) enqueueSvcUpdate(oldObj, newObj interface{}) {
return
}

if newSvcAnnotation == "true" && newSvc.Spec.Type == corev1.ServiceTypeNodePort {
klog.Warningf("Service %s is of type NodePort and cannot be used for NodePortLocal, the '%s' annotation will have no effect", newSvc.Name, NPLEnabledAnnotationKey)
}

podKeys := sets.String{}
if oldSvcAnnotation != newSvcAnnotation {
// Process Pods corresponding to Service with valid NPL annotation.
if oldSvcAnnotation == "true" {
oldNPLEnabled := oldSvcAnnotation == "true" && oldSvc.Spec.Type != corev1.ServiceTypeNodePort
newNPLEnabled := newSvcAnnotation == "true" && newSvc.Spec.Type != corev1.ServiceTypeNodePort

if oldNPLEnabled != newNPLEnabled {
// Process Pods corresponding to Service with valid NPL annotation and Service type.
if oldNPLEnabled {
podKeys = sets.NewString(c.getPodsFromService(oldSvc)...)
} else if newSvcAnnotation == "true" {
} else if newNPLEnabled {
podKeys = sets.NewString(c.getPodsFromService(newSvc)...)
}
} else if !reflect.DeepEqual(oldSvc.Spec.Selector, newSvc.Spec.Selector) {
} else if oldNPLEnabled && newNPLEnabled && !reflect.DeepEqual(oldSvc.Spec.Selector, newSvc.Spec.Selector) {
// Disjunctive union of Pods from both Service sets.
oldPodSet := sets.NewString(c.getPodsFromService(oldSvc)...)
newPodSet := sets.NewString(c.getPodsFromService(newSvc)...)
Expand Down
41 changes: 40 additions & 1 deletion pkg/agent/nodeportlocal/npl_agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,30 @@ func TestSvcNamespaceUpdate(t *testing.T) {
assert.False(t, testData.portTable.RuleExists(defaultPodIP, defaultPort))
}

// TestSvcTypeUpdate updates Service type from ClusterIP to NodePort
// and checks whether Pod annotations are removed.
func TestSvcTypeUpdate(t *testing.T) {
testData, testSvc, testPod := setUpWithTestServiceAndPod(t)
defer testData.tearDown()

// Update Service type to NodePort.
testSvc.Spec.Type = "NodePort"
testData.updateServiceOrFail(testSvc)

// Check that annotation and the rule are removed.
_, err := testData.pollForPodAnnotation(testPod.Name, false)
require.NoError(t, err, "Poll for annotation check failed")
assert.False(t, testData.portTable.RuleExists(defaultPodIP, defaultPort))

// Update Service type to ClusterIP.
testSvc.Spec.Type = "ClusterIP"
testData.updateServiceOrFail(testSvc)

_, err = testData.pollForPodAnnotation(testPod.Name, true)
require.NoError(t, err, "Poll for annotation check failed")
assert.True(t, testData.portTable.RuleExists(defaultPodIP, defaultPort))
}

// TestSvcUpdateAnnotation updates the Service spec to disabled NPL. It then verifies that the Pod's
// NPL annotation is removed and that the port table is updated.
func TestSvcUpdateAnnotation(t *testing.T) {
Expand All @@ -273,6 +297,14 @@ func TestSvcUpdateAnnotation(t *testing.T) {
_, err := testData.pollForPodAnnotation(testPod.Name, false)
require.NoError(t, err, "Poll for annotation check failed")
assert.False(t, testData.portTable.RuleExists(defaultPodIP, defaultPort))

// Enable NPL back.
testSvc.Annotations = map[string]string{nplk8s.NPLEnabledAnnotationKey: "true"}
testData.updateServiceOrFail(testSvc)

_, err = testData.pollForPodAnnotation(testPod.Name, true)
require.NoError(t, err, "Poll for annotation check failed")
assert.True(t, testData.portTable.RuleExists(defaultPodIP, defaultPort))
}

// TestSvcRemoveAnnotation is the same as TestSvcUpdateAnnotation, but it deletes the NPL enabled
Expand All @@ -295,12 +327,19 @@ func TestSvcUpdateSelector(t *testing.T) {
testData, testSvc, testPod := setUpWithTestServiceAndPod(t)
defer testData.tearDown()

testSvc.Spec.Selector = map[string]string{"foo": "invalid-selector"}
testSvc.Spec.Selector = map[string]string{defaultAppSelectorKey: "invalid-selector"}
testData.updateServiceOrFail(testSvc)

_, err := testData.pollForPodAnnotation(testPod.Name, false)
require.NoError(t, err, "Poll for annotation check failed")
assert.False(t, testData.portTable.RuleExists(defaultPodIP, defaultPort))

testSvc.Spec.Selector = map[string]string{defaultAppSelectorKey: defaultAppSelectorVal}
testData.updateServiceOrFail(testSvc)

_, err = testData.pollForPodAnnotation(testPod.Name, true)
require.NoError(t, err, "Poll for annotation check failed")
assert.True(t, testData.portTable.RuleExists(defaultPodIP, defaultPort))
}

// TestPodUpdateSelectorLabel updates the Pod's labels so that the Pod is no longer selected by the
Expand Down