Move defaulting logic for ExternalTrafficPolicy into defaults.go

This commit is contained in:
Zihong Zheng
2017-05-17 12:47:01 -07:00
parent ac62748480
commit a28a22df11
9 changed files with 56 additions and 273 deletions

View File

@@ -118,20 +118,6 @@ func GetServiceHealthCheckNodePort(service *api.Service) int32 {
return service.Spec.HealthCheckNodePort
}
// SetDefaultExternalTrafficPolicyIfNeeded defaults the ExternalTrafficPolicy field
// for NodePort / LoadBalancer service to Global for consistency.
// TODO: Move this default logic to default.go once beta annotation is deprecated.
func SetDefaultExternalTrafficPolicyIfNeeded(service *api.Service) {
if _, ok := service.Annotations[api.BetaAnnotationExternalTraffic]; ok {
// Don't default this field if beta annotation exists.
return
} else if (service.Spec.Type == api.ServiceTypeNodePort ||
service.Spec.Type == api.ServiceTypeLoadBalancer) &&
service.Spec.ExternalTrafficPolicy == "" {
service.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeGlobal
}
}
// ClearExternalTrafficPolicy resets the ExternalTrafficPolicy field.
func ClearExternalTrafficPolicy(service *api.Service) {
// First check the beta annotation and then the first class field. This is so that

View File

@@ -20,7 +20,6 @@ import (
"testing"
"fmt"
"reflect"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -298,106 +297,6 @@ func TestGetServiceHealthCheckNodePort(t *testing.T) {
})
}
func TestSetDefaultExternalTrafficPolicyIfNeeded(t *testing.T) {
testCases := []struct {
inputService *api.Service
expectedService *api.Service
}{
// First class fields cases.
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
},
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
},
},
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeNodePort,
},
},
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeNodePort,
ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeGlobal,
},
},
},
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
},
},
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeClusterIP,
},
},
},
// Beta annotations cases.
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
api.BetaAnnotationExternalTraffic: api.AnnotationValueExternalTrafficLocal,
},
},
},
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
api.BetaAnnotationExternalTraffic: api.AnnotationValueExternalTrafficLocal,
},
},
},
},
{
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
api.BetaAnnotationExternalTraffic: api.AnnotationValueExternalTrafficGlobal,
},
},
},
&api.Service{
Spec: api.ServiceSpec{
Type: api.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
api.BetaAnnotationExternalTraffic: api.AnnotationValueExternalTrafficGlobal,
},
},
},
},
}
for i, tc := range testCases {
SetDefaultExternalTrafficPolicyIfNeeded(tc.inputService)
if !reflect.DeepEqual(tc.inputService, tc.expectedService) {
t.Errorf("%v: got unexpected service", i)
spew.Dump(tc)
}
}
}
func TestClearExternalTrafficPolicy(t *testing.T) {
testCases := []struct {
inputService *api.Service

View File

@@ -319,6 +319,10 @@ func coreFuncs(t apitesting.TestingCommon) []interface{} {
types := []api.ServiceType{api.ServiceTypeClusterIP, api.ServiceTypeNodePort, api.ServiceTypeLoadBalancer}
*p = types[c.Rand.Intn(len(types))]
},
func(p *api.ServiceExternalTrafficPolicyType, c fuzz.Continue) {
types := []api.ServiceExternalTrafficPolicyType{api.ServiceExternalTrafficPolicyTypeGlobal, api.ServiceExternalTrafficPolicyTypeLocal}
*p = types[c.Rand.Intn(len(types))]
},
func(ct *api.Container, c fuzz.Continue) {
c.FuzzNoCustom(ct) // fuzz self without calling this function again
ct.TerminationMessagePath = "/" + ct.TerminationMessagePath // Must be non-empty

View File

@@ -96,15 +96,15 @@ func SetDefaults_Container(obj *Container) {
obj.TerminationMessagePolicy = TerminationMessageReadFile
}
}
func SetDefaults_ServiceSpec(obj *ServiceSpec) {
if obj.SessionAffinity == "" {
obj.SessionAffinity = ServiceAffinityNone
func SetDefaults_Service(obj *Service) {
if obj.Spec.SessionAffinity == "" {
obj.Spec.SessionAffinity = ServiceAffinityNone
}
if obj.Type == "" {
obj.Type = ServiceTypeClusterIP
if obj.Spec.Type == "" {
obj.Spec.Type = ServiceTypeClusterIP
}
for i := range obj.Ports {
sp := &obj.Ports[i]
for i := range obj.Spec.Ports {
sp := &obj.Spec.Ports[i]
if sp.Protocol == "" {
sp.Protocol = ProtocolTCP
}
@@ -112,6 +112,16 @@ func SetDefaults_ServiceSpec(obj *ServiceSpec) {
sp.TargetPort = intstr.FromInt(int(sp.Port))
}
}
// Defaults ExternalTrafficPolicy field for NodePort / LoadBalancer service
// to Global for consistency.
if _, ok := obj.Annotations[BetaAnnotationExternalTraffic]; ok {
// Don't default this field if beta annotation exists.
return
} else if (obj.Spec.Type == ServiceTypeNodePort ||
obj.Spec.Type == ServiceTypeLoadBalancer) &&
obj.Spec.ExternalTrafficPolicy == "" {
obj.Spec.ExternalTrafficPolicy = ServiceExternalTrafficPolicyTypeGlobal
}
}
func SetDefaults_Pod(obj *Pod) {
// If limits are specified, but requests are not, default requests to limits

View File

@@ -874,6 +874,41 @@ func TestSetDefaultServicePort(t *testing.T) {
}
}
func TestSetDefaulServiceExternalTraffic(t *testing.T) {
in := &v1.Service{}
obj := roundTrip(t, runtime.Object(in))
out := obj.(*v1.Service)
if out.Spec.ExternalTrafficPolicy != "" {
t.Errorf("Expected ExternalTrafficPolicy to be empty, got %v", out.Spec.ExternalTrafficPolicy)
}
in = &v1.Service{Spec: v1.ServiceSpec{Type: v1.ServiceTypeNodePort}}
obj = roundTrip(t, runtime.Object(in))
out = obj.(*v1.Service)
if out.Spec.ExternalTrafficPolicy != v1.ServiceExternalTrafficPolicyTypeGlobal {
t.Errorf("Expected ExternalTrafficPolicy to be %v, got %v", v1.ServiceExternalTrafficPolicyTypeGlobal, out.Spec.ExternalTrafficPolicy)
}
in = &v1.Service{Spec: v1.ServiceSpec{Type: v1.ServiceTypeLoadBalancer}}
obj = roundTrip(t, runtime.Object(in))
out = obj.(*v1.Service)
if out.Spec.ExternalTrafficPolicy != v1.ServiceExternalTrafficPolicyTypeGlobal {
t.Errorf("Expected ExternalTrafficPolicy to be %v, got %v", v1.ServiceExternalTrafficPolicyTypeGlobal, out.Spec.ExternalTrafficPolicy)
}
in = &v1.Service{
Spec: v1.ServiceSpec{Type: v1.ServiceTypeLoadBalancer},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{v1.BetaAnnotationExternalTraffic: v1.AnnotationValueExternalTrafficLocal},
},
}
obj = roundTrip(t, runtime.Object(in))
out = obj.(*v1.Service)
if out.Spec.ExternalTrafficPolicy != "" {
t.Errorf("Expected ExternalTrafficPolicy to be empty, got %v", out.Spec.ExternalTrafficPolicy)
}
}
func TestSetDefaultNamespace(t *testing.T) {
s := &v1.Namespace{}
obj2 := roundTrip(t, runtime.Object(s))

View File

@@ -118,20 +118,6 @@ func GetServiceHealthCheckNodePort(service *v1.Service) int32 {
return service.Spec.HealthCheckNodePort
}
// SetDefaultExternalTrafficPolicyIfNeeded defaults the ExternalTrafficPolicy field
// for NodePort / LoadBalancer service to Global for consistency.
// TODO: Move this default logic to default.go once beta annotation is deprecated.
func SetDefaultExternalTrafficPolicyIfNeeded(service *v1.Service) {
if _, ok := service.Annotations[v1.BetaAnnotationExternalTraffic]; ok {
// Don't default this field if beta annotation exists.
return
} else if (service.Spec.Type == v1.ServiceTypeNodePort ||
service.Spec.Type == v1.ServiceTypeLoadBalancer) &&
service.Spec.ExternalTrafficPolicy == "" {
service.Spec.ExternalTrafficPolicy = v1.ServiceExternalTrafficPolicyTypeGlobal
}
}
// ClearExternalTrafficPolicy resets the ExternalTrafficPolicy field.
func ClearExternalTrafficPolicy(service *v1.Service) {
// First check the beta annotation and then the first class field. This is so existing

View File

@@ -20,7 +20,6 @@ import (
"testing"
"fmt"
"reflect"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -298,106 +297,6 @@ func TestGetServiceHealthCheckNodePort(t *testing.T) {
})
}
func TestSetDefaultExternalTrafficPolicyIfNeeded(t *testing.T) {
testCases := []struct {
inputService *v1.Service
expectedService *v1.Service
}{
// First class fields cases.
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
},
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
},
},
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeNodePort,
},
},
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeNodePort,
ExternalTrafficPolicy: v1.ServiceExternalTrafficPolicyTypeGlobal,
},
},
},
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
},
},
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeClusterIP,
},
},
},
// Beta annotations cases.
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
v1.BetaAnnotationExternalTraffic: v1.AnnotationValueExternalTrafficLocal,
},
},
},
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
v1.BetaAnnotationExternalTraffic: v1.AnnotationValueExternalTrafficLocal,
},
},
},
},
{
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
v1.BetaAnnotationExternalTraffic: v1.AnnotationValueExternalTrafficGlobal,
},
},
},
&v1.Service{
Spec: v1.ServiceSpec{
Type: v1.ServiceTypeLoadBalancer,
},
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{
v1.BetaAnnotationExternalTraffic: v1.AnnotationValueExternalTrafficGlobal,
},
},
},
},
}
for i, tc := range testCases {
SetDefaultExternalTrafficPolicyIfNeeded(tc.inputService)
if !reflect.DeepEqual(tc.inputService, tc.expectedService) {
t.Errorf("%v: got unexpected service", i)
spew.Dump(tc)
}
}
}
func TestClearExternalTrafficPolicy(t *testing.T) {
testCases := []struct {
inputService *v1.Service