From 569ce87f0eb5da565a2ae43eaa218d3fb3013d2d Mon Sep 17 00:00:00 2001 From: Mike Foley Date: Wed, 17 Dec 2014 07:52:11 -0500 Subject: [PATCH] =?UTF-8?q?Updated=20types=20API=20to=20include=20session?= =?UTF-8?q?=20affinity.=20=E2=80=A6=20=20-=20changed=20CLIENT-IP=20and=20N?= =?UTF-8?q?ONE=20to=20be=20ClientIP=20and=20None=20respectively=20=20-=20u?= =?UTF-8?q?pdated=20conversions=20to=20support=20translating=20between=20a?= =?UTF-8?q?pi=20versions.=20=20-=20updated=20validations=20to=20validate?= =?UTF-8?q?=20session=20affinity=20type=20if=20specified.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/api/types.go | 14 ++++++++++++++ pkg/api/v1beta1/conversion.go | 8 ++++++++ pkg/api/v1beta1/types.go | 14 ++++++++++++++ pkg/api/v1beta2/conversion.go | 6 ++++++ pkg/api/v1beta2/types.go | 14 ++++++++++++++ pkg/api/v1beta3/types.go | 14 ++++++++++++++ pkg/api/validation/validation.go | 8 ++++++++ 7 files changed, 78 insertions(+) diff --git a/pkg/api/types.go b/pkg/api/types.go index ec8542cd671..886a1b1902d 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -572,6 +572,17 @@ type ServiceList struct { Items []Service `json:"items"` } +// Session Affinity Type string +type AffinityType string + +const ( + // AffinityTypeClientIP is the Client IP based. + AffinityTypeClientIP AffinityType = "ClientIP" + + // AffinityTypeNone - no session affinity. + AffinityTypeNone AffinityType = "None" +) + // ServiceStatus represents the current status of a service type ServiceStatus struct{} @@ -606,6 +617,9 @@ type ServiceSpec struct { // ContainerPort is the name of the port on the container to direct traffic to. // Optional, if unspecified use the first port on the container. ContainerPort util.IntOrString `json:"containerPort,omitempty"` + + // Optional: Supports "ClientIP" and "None". Used to maintain session affinity. + SessionAffinity *AffinityType `json:"sessionAffinity,omitempty"` } // Service is a named abstraction of software service (for example, mysql) consisting of local port diff --git a/pkg/api/v1beta1/conversion.go b/pkg/api/v1beta1/conversion.go index 8fde109d9b3..28b8087194f 100644 --- a/pkg/api/v1beta1/conversion.go +++ b/pkg/api/v1beta1/conversion.go @@ -436,6 +436,10 @@ func init() { out.ContainerPort = in.Spec.ContainerPort out.PortalIP = in.Spec.PortalIP out.ProxyPort = in.Spec.ProxyPort + if err := s.Convert(&in.Spec.SessionAffinity, &out.SessionAffinity, 0); err != nil { + return err + } + return nil }, func(in *Service, out *newer.Service, s conversion.Scope) error { @@ -459,6 +463,10 @@ func init() { out.Spec.ContainerPort = in.ContainerPort out.Spec.PortalIP = in.PortalIP out.Spec.ProxyPort = in.ProxyPort + if err := s.Convert(&in.SessionAffinity, &out.Spec.SessionAffinity, 0); err != nil { + return err + } + return nil }, diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index 6c0a390d5a4..5b05a3e74e0 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -448,6 +448,17 @@ type PodTemplate struct { Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize the pods created from the template; must match the selector of the replication controller to which the template belongs; may match selectors of services"` } +// Session Affinity Type string +type AffinityType string + +const ( + // AffinityTypeClientIP is the Client IP based. + AffinityTypeClientIP AffinityType = "ClientIP" + + // AffinityTypeNone - no session affinity. + AffinityTypeNone AffinityType = "None" +) + // ServiceList holds a list of services. type ServiceList struct { TypeMeta `json:",inline"` @@ -487,6 +498,9 @@ type Service struct { // ProxyPort is assigned by the master. If specified by the user it will be ignored. ProxyPort int `json:"proxyPort,omitempty" description:"if non-zero, a pre-allocated host port used for this service by the proxy on each node; assigned by the master and ignored on input"` + + // Optional: Supports "ClientIP" and "None". Used to maintain session affinity. + SessionAffinity *AffinityType `json:"sessionAffinity,omitempty" description:"enable client IP based session affinity; must be ClientIP or None; Disabled if unspecified"` } // Endpoints is a collection of endpoints that implement the actual service, for example: diff --git a/pkg/api/v1beta2/conversion.go b/pkg/api/v1beta2/conversion.go index 20c6ab794f2..96e5ff6a5ce 100644 --- a/pkg/api/v1beta2/conversion.go +++ b/pkg/api/v1beta2/conversion.go @@ -352,6 +352,9 @@ func init() { out.ContainerPort = in.Spec.ContainerPort out.PortalIP = in.Spec.PortalIP out.ProxyPort = in.Spec.ProxyPort + if err := s.Convert(&in.Spec.SessionAffinity, &out.SessionAffinity, 0); err != nil { + return err + } return nil }, @@ -376,6 +379,9 @@ func init() { out.Spec.ContainerPort = in.ContainerPort out.Spec.PortalIP = in.PortalIP out.Spec.ProxyPort = in.ProxyPort + if err := s.Convert(&in.SessionAffinity, &out.Spec.SessionAffinity, 0); err != nil { + return err + } return nil }, diff --git a/pkg/api/v1beta2/types.go b/pkg/api/v1beta2/types.go index 1ec2afb5f41..cfb6303e35d 100644 --- a/pkg/api/v1beta2/types.go +++ b/pkg/api/v1beta2/types.go @@ -413,6 +413,17 @@ type PodTemplate struct { Labels map[string]string `json:"labels,omitempty" description:"map of string keys and values that can be used to organize and categorize the pods created from the template; must match the selector of the replication controller to which the template belongs; may match selectors of services"` } +// Session Affinity Type string +type AffinityType string + +const ( + // AffinityTypeClientIP is the Client IP based. + AffinityTypeClientIP AffinityType = "ClientIP" + + // AffinityTypeNone - no session affinity. + AffinityTypeNone AffinityType = "None" +) + // ServiceList holds a list of services. type ServiceList struct { TypeMeta `json:",inline"` @@ -452,6 +463,9 @@ type Service struct { // ProxyPort is assigned by the master. If specified by the user it will be ignored. ProxyPort int `json:"proxyPort,omitempty" description:"if non-zero, a pre-allocated host port used for this service by the proxy on each node; assigned by the master and ignored on input"` + + // Optional: Supports "ClientIP" and "None". Used to maintain session affinity. + SessionAffinity *AffinityType `json:"sessionAffinity,omitempty" description:"enable client IP based session affinity; must be ClientIP or None; Disabled if unspecified"` } // Endpoints is a collection of endpoints that implement the actual service, for example: diff --git a/pkg/api/v1beta3/types.go b/pkg/api/v1beta3/types.go index 62c33ad89ce..b6760df0f2f 100644 --- a/pkg/api/v1beta3/types.go +++ b/pkg/api/v1beta3/types.go @@ -604,6 +604,17 @@ type ReplicationControllerList struct { Items []ReplicationController `json:"items"` } +// Session Affinity Type string +type AffinityType string + +const ( + // AffinityTypeClientIP is the Client IP based. + AffinityTypeClientIP AffinityType = "ClientIP" + + // AffinityTypeNone - no session affinity. + AffinityTypeNone AffinityType = "None" +) + // ServiceStatus represents the current status of a service type ServiceStatus struct{} @@ -635,6 +646,9 @@ type ServiceSpec struct { // ContainerPort is the name of the port on the container to direct traffic to. // Optional, if unspecified use the first port on the container. ContainerPort util.IntOrString `json:"containerPort,omitempty"` + + // Optional: Supports "ClientIP" and "None". Used to maintain session affinity. + SessionAffinity *AffinityType `json:"sessionAffinity,omitempty"` } // Service is a named abstraction of software service (for example, mysql) consisting of local port diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index e94f627f860..85d689af6f3 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -414,6 +414,8 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList { return allErrs } +var supportedSessionAffinityType = util.NewStringSet(string(api.AffinityTypeClientIP), string(api.AffinityTypeNone)) + // ValidateService tests if required fields in the service are set. func ValidateService(service *api.Service, lister ServiceLister, ctx api.Context) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} @@ -454,6 +456,12 @@ func ValidateService(service *api.Service, lister ServiceLister, ctx api.Context } } } + if service.Spec.SessionAffinity != nil { + if !supportedSessionAffinityType.Has(string(*service.Spec.SessionAffinity)) { + allErrs = append(allErrs, errs.NewFieldNotSupported("spec.sessionAffinity", service.Spec.SessionAffinity)) + } + } + return allErrs }