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

Ignore ClusterIPs, and IPFamilyPolicy in services, and timestamp in license during reconciliation #4929

Merged
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
22 changes: 22 additions & 0 deletions pkg/controller/common/service_control.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ func applyServerSideValues(expected, reconciled *corev1.Service) {
expected.Spec.ClusterIP = reconciled.Spec.ClusterIP
}

// ClusterIPs also might not exist in the expected service,
// but might have been set after creation by k8s on the actual resource.
// In such case, we want to use these values for comparison.
// But only if we are not changing the type of service and the api server has assigned IPs
if expected.Spec.Type == reconciled.Spec.Type && len(expected.Spec.ClusterIPs) == 0 && validClusterIPs(reconciled.Spec.ClusterIPs) {
expected.Spec.ClusterIPs = reconciled.Spec.ClusterIPs
}

// SessionAffinity may be defaulted by the api server
if expected.Spec.SessionAffinity == "" {
expected.Spec.SessionAffinity = reconciled.Spec.SessionAffinity
Expand Down Expand Up @@ -126,6 +134,20 @@ func applyServerSideValues(expected, reconciled *corev1.Service) {
if expected.Spec.IPFamilies == nil {
expected.Spec.IPFamilies = reconciled.Spec.IPFamilies
}

// IPFamilyPolicy is immutable and cannot be modified so we should retain the existing value from the server if there's no explicit override.
if expected.Spec.IPFamilyPolicy == nil {
expected.Spec.IPFamilyPolicy = reconciled.Spec.IPFamilyPolicy
}
}

func validClusterIPs(clusterIPs []string) bool {
for _, ip := range clusterIPs {
if net.ParseIP(ip) == nil {
return false
}
}
return true
}

// hasNodePort returns for a given service type, if the service ports have a NodePort or not.
Expand Down
28 changes: 19 additions & 9 deletions pkg/controller/common/service_control_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func mkService(owner *kbv1.Kibana) *corev1.Service {
}

func Test_needsUpdate(t *testing.T) {
ipFamilySingleStack := corev1.IPFamilyPolicySingleStack
type args struct {
expected corev1.Service
reconciled corev1.Service
Expand Down Expand Up @@ -133,9 +134,11 @@ func Test_needsUpdate(t *testing.T) {
Annotations: map[string]string{"annotation1": "annotation1val", "annotation2": "annotation2val"},
},
Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeClusterIP,
ClusterIP: "1.2.3.4",
IPFamilies: []corev1.IPFamily{corev1.IPv4Protocol},
Type: corev1.ServiceTypeClusterIP,
ClusterIP: "1.2.3.4",
ClusterIPs: []string{"1.2.3.4"},
IPFamilies: []corev1.IPFamily{corev1.IPv4Protocol},
IPFamilyPolicy: &ipFamilySingleStack,
}},
},
want: false,
Expand Down Expand Up @@ -263,28 +266,31 @@ func Test_applyServerSideValues(t *testing.T) {
want corev1.Service
}{
{
name: "Reconciled ClusterIP/Type/SessionAffinity is used if expected ClusterIP/Type/SessionAffinity is empty",
name: "Reconciled ClusterIP/ClusterIPs/Type/SessionAffinity is used if expected ClusterIP/Type/SessionAffinity is empty",
args: args{
expected: corev1.Service{Spec: corev1.ServiceSpec{}},
reconciled: corev1.Service{Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeClusterIP,
ClusterIP: "1.2.3.4",
ClusterIPs: []string{"1.2.3.4"},
SessionAffinity: corev1.ServiceAffinityClientIP,
}},
},
want: corev1.Service{Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeClusterIP,
ClusterIP: "1.2.3.4",
ClusterIPs: []string{"1.2.3.4"},
SessionAffinity: corev1.ServiceAffinityClientIP,
}},
},
{
name: "Reconciled ClusterIP is not used if the reconciled ClusterIP is not an IP",
name: "Reconciled ClusterIP[s] is not used if the reconciled ClusterIP[s] are not valid IPs",
args: args{
expected: corev1.Service{Spec: corev1.ServiceSpec{}},
reconciled: corev1.Service{Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeClusterIP,
ClusterIP: "None",
ClusterIPs: []string{"None"},
SessionAffinity: corev1.ServiceAffinityClientIP,
}},
},
Expand All @@ -294,37 +300,41 @@ func Test_applyServerSideValues(t *testing.T) {
}},
},
{
name: "Reconciled ClusterIP is not used if expected type changes",
name: "Reconciled ClusterIP[s] is not used if expected type changes",
args: args{
expected: corev1.Service{Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeLoadBalancer,
}},
reconciled: corev1.Service{Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeClusterIP,
ClusterIP: "1.2.3.4",
Type: corev1.ServiceTypeClusterIP,
ClusterIP: "1.2.3.4",
ClusterIPs: []string{"1.2.3.4"},
}},
},
want: corev1.Service{Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeLoadBalancer,
}},
},
{
name: "Reconciled ClusterIP/Type/SessionAffinity is not used if expected ClusterIP/Type/SessionAffinity is set",
name: "Reconciled ClusterIP[s]/Type/SessionAffinity is not used if expected ClusterIP[s]/Type/SessionAffinity is set",
args: args{
expected: corev1.Service{Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeLoadBalancer,
ClusterIP: "4.3.2.1",
ClusterIPs: []string{"4.3.2.1"},
SessionAffinity: corev1.ServiceAffinityNone,
}},
reconciled: corev1.Service{Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeClusterIP,
ClusterIP: "1.2.3.4",
ClusterIPs: []string{"1.2.3.4"},
SessionAffinity: corev1.ServiceAffinityClientIP,
}},
},
want: corev1.Service{Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeLoadBalancer,
ClusterIP: "4.3.2.1",
ClusterIPs: []string{"4.3.2.1"},
SessionAffinity: corev1.ServiceAffinityNone,
}},
},
Expand Down
12 changes: 11 additions & 1 deletion pkg/license/license.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,17 @@ func (r LicensingResolver) Save(info LicensingInfo) error {
Expected: &expected,
Reconciled: reconciled,
NeedsUpdate: func() bool {
return !reflect.DeepEqual(expected.Data, reconciled.Data)
// do not compare timestamp, as it will always change
expectedData, reconciledData := map[string]string{}, map[string]string{}
for k, v := range expected.Data {
expectedData[k] = v
}
for k, v := range reconciled.Data {
reconciledData[k] = v
}
delete(expectedData, "timestamp")
delete(reconciledData, "timestamp")
return !reflect.DeepEqual(expectedData, reconciledData)
},
UpdateReconciled: func() {
expected.DeepCopyInto(reconciled)
Expand Down