From 6f9d4fc0b907a6ce56e787b1cdbdcfc18fba2218 Mon Sep 17 00:00:00 2001 From: tamal Date: Mon, 6 Nov 2017 15:08:36 -0800 Subject: [PATCH] Support ExternalIPs Fixes #686 --- apis/voyager/ingress.go | 14 +++++++++++--- apis/voyager/v1beta1/ingress.go | 14 +++++++++++--- apis/voyager/v1beta1/openapi_generated.go | 14 ++++++++++++++ apis/voyager/v1beta1/zz_generated.conversion.go | 2 ++ apis/voyager/v1beta1/zz_generated.deepcopy.go | 5 +++++ apis/voyager/zz_generated.deepcopy.go | 5 +++++ pkg/ingress/hostport.go | 7 ++++--- pkg/ingress/internal.go | 7 ++++--- pkg/ingress/loadbalancer.go | 1 + pkg/ingress/nodeport.go | 7 ++++--- pkg/ingress/update.go | 4 ++++ 11 files changed, 65 insertions(+), 15 deletions(-) diff --git a/apis/voyager/ingress.go b/apis/voyager/ingress.go index 83acee25f..29642e0d9 100644 --- a/apis/voyager/ingress.go +++ b/apis/voyager/ingress.go @@ -82,16 +82,16 @@ type IngressSpec struct { // If specified, the pod's scheduling constraints // +optional - Affinity *core.Affinity `json:"affinity,omitempty" protobuf:"bytes,18,opt,name=affinity"` + Affinity *core.Affinity `json:"affinity,omitempty"` // If specified, the pod will be dispatched by specified scheduler. // If not specified, the pod will be dispatched by default scheduler. // +optional - SchedulerName string `json:"schedulerName,omitempty" protobuf:"bytes,19,opt,name=schedulerName"` + SchedulerName string `json:"schedulerName,omitempty"` // If specified, the pod's tolerations. // +optional - Tolerations []core.Toleration `json:"tolerations,omitempty" protobuf:"bytes,22,opt,name=tolerations"` + Tolerations []core.Toleration `json:"tolerations,omitempty"` // ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. // If specified, these secrets will be passed to individual puller implementations for them to use. For example, @@ -99,6 +99,14 @@ type IngressSpec struct { // More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod // +optional ImagePullSecrets []core.LocalObjectReference `json:"imagePullSecrets,omitempty"` + + // externalIPs is a list of IP addresses for which nodes in the cluster + // will also accept traffic for this service. These IPs are not managed by + // Kubernetes. The user is responsible for ensuring that traffic arrives + // at a node with this IP. A common example is external load-balancers + // that are not part of the Kubernetes system. + // +optional + ExternalIPs []string `json:"externalIPs,omitempty"` } // IngressTLS describes the transport layer security associated with an Ingress. diff --git a/apis/voyager/v1beta1/ingress.go b/apis/voyager/v1beta1/ingress.go index 2a5ebdcc9..582fc854f 100644 --- a/apis/voyager/v1beta1/ingress.go +++ b/apis/voyager/v1beta1/ingress.go @@ -83,16 +83,16 @@ type IngressSpec struct { // If specified, the pod's scheduling constraints // +optional - Affinity *core.Affinity `json:"affinity,omitempty" protobuf:"bytes,18,opt,name=affinity"` + Affinity *core.Affinity `json:"affinity,omitempty"` // If specified, the pod will be dispatched by specified scheduler. // If not specified, the pod will be dispatched by default scheduler. // +optional - SchedulerName string `json:"schedulerName,omitempty" protobuf:"bytes,19,opt,name=schedulerName"` + SchedulerName string `json:"schedulerName,omitempty"` // If specified, the pod's tolerations. // +optional - Tolerations []core.Toleration `json:"tolerations,omitempty" protobuf:"bytes,22,opt,name=tolerations"` + Tolerations []core.Toleration `json:"tolerations,omitempty"` // ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. // If specified, these secrets will be passed to individual puller implementations for them to use. For example, @@ -100,6 +100,14 @@ type IngressSpec struct { // More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod // +optional ImagePullSecrets []core.LocalObjectReference `json:"imagePullSecrets,omitempty"` + + // externalIPs is a list of IP addresses for which nodes in the cluster + // will also accept traffic for this service. These IPs are not managed by + // Kubernetes. The user is responsible for ensuring that traffic arrives + // at a node with this IP. A common example is external load-balancers + // that are not part of the Kubernetes system. + // +optional + ExternalIPs []string `json:"externalIPs,omitempty"` } // IngressTLS describes the transport layer security associated with an Ingress. diff --git a/apis/voyager/v1beta1/openapi_generated.go b/apis/voyager/v1beta1/openapi_generated.go index cb327c147..760030d8f 100644 --- a/apis/voyager/v1beta1/openapi_generated.go +++ b/apis/voyager/v1beta1/openapi_generated.go @@ -1054,6 +1054,20 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA }, }, }, + "externalIPs": { + SchemaProps: spec.SchemaProps{ + Description: "externalIPs is a list of IP addresses for which nodes in the cluster will also accept traffic for this service. These IPs are not managed by Kubernetes. The user is responsible for ensuring that traffic arrives at a node with this IP. A common example is external load-balancers that are not part of the Kubernetes system.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, }, }, diff --git a/apis/voyager/v1beta1/zz_generated.conversion.go b/apis/voyager/v1beta1/zz_generated.conversion.go index d0e19d322..55a131816 100644 --- a/apis/voyager/v1beta1/zz_generated.conversion.go +++ b/apis/voyager/v1beta1/zz_generated.conversion.go @@ -718,6 +718,7 @@ func autoConvert_v1beta1_IngressSpec_To_voyager_IngressSpec(in *IngressSpec, out out.SchedulerName = in.SchedulerName out.Tolerations = *(*[]core_v1.Toleration)(unsafe.Pointer(&in.Tolerations)) out.ImagePullSecrets = *(*[]core_v1.LocalObjectReference)(unsafe.Pointer(&in.ImagePullSecrets)) + out.ExternalIPs = *(*[]string)(unsafe.Pointer(&in.ExternalIPs)) return nil } @@ -737,6 +738,7 @@ func autoConvert_voyager_IngressSpec_To_v1beta1_IngressSpec(in *voyager.IngressS out.SchedulerName = in.SchedulerName out.Tolerations = *(*[]core_v1.Toleration)(unsafe.Pointer(&in.Tolerations)) out.ImagePullSecrets = *(*[]core_v1.LocalObjectReference)(unsafe.Pointer(&in.ImagePullSecrets)) + out.ExternalIPs = *(*[]string)(unsafe.Pointer(&in.ExternalIPs)) return nil } diff --git a/apis/voyager/v1beta1/zz_generated.deepcopy.go b/apis/voyager/v1beta1/zz_generated.deepcopy.go index 5341f0f06..a3b25de09 100644 --- a/apis/voyager/v1beta1/zz_generated.deepcopy.go +++ b/apis/voyager/v1beta1/zz_generated.deepcopy.go @@ -869,6 +869,11 @@ func (in *IngressSpec) DeepCopyInto(out *IngressSpec) { *out = make([]core_v1.LocalObjectReference, len(*in)) copy(*out, *in) } + if in.ExternalIPs != nil { + in, out := &in.ExternalIPs, &out.ExternalIPs + *out = make([]string, len(*in)) + copy(*out, *in) + } return } diff --git a/apis/voyager/zz_generated.deepcopy.go b/apis/voyager/zz_generated.deepcopy.go index 410341403..d9d582a8d 100644 --- a/apis/voyager/zz_generated.deepcopy.go +++ b/apis/voyager/zz_generated.deepcopy.go @@ -822,6 +822,11 @@ func (in *IngressSpec) DeepCopyInto(out *IngressSpec) { *out = make([]core_v1.LocalObjectReference, len(*in)) copy(*out, *in) } + if in.ExternalIPs != nil { + in, out := &in.ExternalIPs, &out.ExternalIPs + *out = make([]string, len(*in)) + copy(*out, *in) + } return } diff --git a/pkg/ingress/hostport.go b/pkg/ingress/hostport.go index 838039f7e..2b8a2ae2f 100644 --- a/pkg/ingress/hostport.go +++ b/pkg/ingress/hostport.go @@ -486,9 +486,10 @@ func (c *hostPortController) newService() *core.Service { }, Spec: core.ServiceSpec{ - Type: core.ServiceTypeClusterIP, - ClusterIP: "None", - Ports: []core.ServicePort{}, + Type: core.ServiceTypeClusterIP, + ClusterIP: "None", + Ports: []core.ServicePort{}, + ExternalIPs: c.Ingress.Spec.ExternalIPs, }, } svc.ObjectMeta = c.ensureOwnerReference(svc.ObjectMeta) diff --git a/pkg/ingress/internal.go b/pkg/ingress/internal.go index 3851feaad..3d4ba9601 100644 --- a/pkg/ingress/internal.go +++ b/pkg/ingress/internal.go @@ -391,9 +391,10 @@ func (c *internalController) newService() *core.Service { }, }, Spec: core.ServiceSpec{ - Type: core.ServiceTypeClusterIP, - Ports: []core.ServicePort{}, - Selector: c.Ingress.OffshootLabels(), + Type: core.ServiceTypeClusterIP, + Ports: []core.ServicePort{}, + Selector: c.Ingress.OffshootLabels(), + ExternalIPs: c.Ingress.Spec.ExternalIPs, }, } svc.ObjectMeta = c.ensureOwnerReference(svc.ObjectMeta) diff --git a/pkg/ingress/loadbalancer.go b/pkg/ingress/loadbalancer.go index 6de98ecd4..e21968928 100644 --- a/pkg/ingress/loadbalancer.go +++ b/pkg/ingress/loadbalancer.go @@ -405,6 +405,7 @@ func (c *loadBalancerController) newService() *core.Service { Ports: []core.ServicePort{}, Selector: c.Ingress.OffshootLabels(), LoadBalancerSourceRanges: c.Ingress.Spec.LoadBalancerSourceRanges, + ExternalIPs: c.Ingress.Spec.ExternalIPs, }, } svc.ObjectMeta = c.ensureOwnerReference(svc.ObjectMeta) diff --git a/pkg/ingress/nodeport.go b/pkg/ingress/nodeport.go index b5f52a5a5..dcc3462ef 100644 --- a/pkg/ingress/nodeport.go +++ b/pkg/ingress/nodeport.go @@ -517,9 +517,10 @@ func (c *nodePortController) newService() *core.Service { }, }, Spec: core.ServiceSpec{ - Type: core.ServiceTypeNodePort, - Ports: []core.ServicePort{}, - Selector: c.Ingress.OffshootLabels(), + Type: core.ServiceTypeNodePort, + Ports: []core.ServicePort{}, + Selector: c.Ingress.OffshootLabels(), + ExternalIPs: c.Ingress.Spec.ExternalIPs, // https://github.com/kubernetes/kubernetes/issues/33586 // LoadBalancerSourceRanges: lbc.Config.Spec.LoadBalancerSourceRanges, }, diff --git a/pkg/ingress/update.go b/pkg/ingress/update.go index a759aaa32..f4730dd55 100644 --- a/pkg/ingress/update.go +++ b/pkg/ingress/update.go @@ -129,6 +129,10 @@ func (c *controller) serviceRequiresUpdate(current, desired *core.Service, old * current.Spec.ExternalTrafficPolicy = desired.Spec.ExternalTrafficPolicy } + if !sets.NewString(current.Spec.ExternalIPs...).Equal(sets.NewString(desired.Spec.ExternalIPs...)) { + needsUpdate = true + current.Spec.ExternalIPs = desired.Spec.ExternalIPs + } return current, needsUpdate }