diff --git a/pkg/api/types.go b/pkg/api/types.go index 2eea3ede178..e545987084f 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -1071,12 +1071,10 @@ type ServiceSpec struct { // Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer Type ServiceType `json:"type,omitempty"` - // PublicIPs are used by external load balancers, or can be set by + // DeprecatedPublicIPs are deprecated and silently ignored. + // Old behaviour: PublicIPs are used by external load balancers, or can be set by // users to handle external traffic that arrives at a node. - // For load balancers, the publicIP will usually be the IP address of the load balancer, - // but some load balancers (notably AWS ELB) use a hostname instead of an IP address. - // For hostnames, the user will use a CNAME record (instead of using an A record with the IP) - PublicIPs []string `json:"publicIPs,omitempty"` + DeprecatedPublicIPs []string `json:"deprecatedPublicIPs,omitempty"` // Required: Supports "ClientIP" and "None". Used to maintain session affinity. SessionAffinity ServiceAffinity `json:"sessionAffinity,omitempty"` diff --git a/pkg/api/v1/conversion_generated.go b/pkg/api/v1/conversion_generated.go index 154ddec2e66..03127b35e51 100644 --- a/pkg/api/v1/conversion_generated.go +++ b/pkg/api/v1/conversion_generated.go @@ -2099,13 +2099,13 @@ func convert_api_ServiceSpec_To_v1_ServiceSpec(in *api.ServiceSpec, out *Service } out.PortalIP = in.PortalIP out.Type = ServiceType(in.Type) - if in.PublicIPs != nil { - out.PublicIPs = make([]string, len(in.PublicIPs)) - for i := range in.PublicIPs { - out.PublicIPs[i] = in.PublicIPs[i] + if in.DeprecatedPublicIPs != nil { + out.DeprecatedPublicIPs = make([]string, len(in.DeprecatedPublicIPs)) + for i := range in.DeprecatedPublicIPs { + out.DeprecatedPublicIPs[i] = in.DeprecatedPublicIPs[i] } } else { - out.PublicIPs = nil + out.DeprecatedPublicIPs = nil } out.SessionAffinity = ServiceAffinity(in.SessionAffinity) return nil @@ -4355,13 +4355,13 @@ func convert_v1_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.Service } out.PortalIP = in.PortalIP out.Type = api.ServiceType(in.Type) - if in.PublicIPs != nil { - out.PublicIPs = make([]string, len(in.PublicIPs)) - for i := range in.PublicIPs { - out.PublicIPs[i] = in.PublicIPs[i] + if in.DeprecatedPublicIPs != nil { + out.DeprecatedPublicIPs = make([]string, len(in.DeprecatedPublicIPs)) + for i := range in.DeprecatedPublicIPs { + out.DeprecatedPublicIPs[i] = in.DeprecatedPublicIPs[i] } } else { - out.PublicIPs = nil + out.DeprecatedPublicIPs = nil } out.SessionAffinity = api.ServiceAffinity(in.SessionAffinity) return nil diff --git a/pkg/api/v1/types.go b/pkg/api/v1/types.go index 0fc6a6a74cc..cb37158fef8 100644 --- a/pkg/api/v1/types.go +++ b/pkg/api/v1/types.go @@ -1051,9 +1051,9 @@ type ServiceSpec struct { // Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer Type ServiceType `json:"type,omitempty" description:"type of this service; must be ClusterIP, NodePort, or LoadBalancer; defaults to ClusterIP"` - // PublicIPs are used by external load balancers, or can be set by + // Deprecated. PublicIPs are used by external load balancers, or can be set by // users to handle external traffic that arrives at a node. - PublicIPs []string `json:"publicIPs,omitempty" description:"externally visible IPs (e.g. load balancers) that should be proxied to this service"` + DeprecatedPublicIPs []string `json:"deprecatedPublicIPs,omitempty" description:"deprecated. externally visible IPs (e.g. load balancers) that should be proxied to this service"` // Optional: Supports "ClientIP" and "None". Used to maintain session affinity. SessionAffinity ServiceAffinity `json:"sessionAffinity,omitempty" description:"enable client IP based session affinity; must be ClientIP or None; defaults to None"` diff --git a/pkg/api/v1beta1/conversion.go b/pkg/api/v1beta1/conversion.go index f138bb14de2..ab151c95520 100644 --- a/pkg/api/v1beta1/conversion.go +++ b/pkg/api/v1beta1/conversion.go @@ -781,7 +781,7 @@ func addConversionFuncs() { if err := s.Convert(&in.Spec.Selector, &out.Selector, 0); err != nil { return err } - out.PublicIPs = in.Spec.PublicIPs + out.PublicIPs = in.Spec.DeprecatedPublicIPs out.PortalIP = in.Spec.PortalIP if err := s.Convert(&in.Spec.SessionAffinity, &out.SessionAffinity, 0); err != nil { return err @@ -832,7 +832,7 @@ func addConversionFuncs() { if err := s.Convert(&in.Selector, &out.Spec.Selector, 0); err != nil { return err } - out.Spec.PublicIPs = in.PublicIPs + out.Spec.DeprecatedPublicIPs = in.PublicIPs out.Spec.PortalIP = in.PortalIP if err := s.Convert(&in.SessionAffinity, &out.Spec.SessionAffinity, 0); err != nil { return err diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index 768b3d54e33..139173aba64 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -890,9 +890,9 @@ type Service struct { // Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer Type ServiceType `json:"type,omitempty" description:"type of this service; must be ClusterIP, NodePort, or LoadBalancer; defaults to ClusterIP"` - // PublicIPs are used by external load balancers, or can be set by + // Deprecated. PublicIPs are used by external load balancers, or can be set by // users to handle external traffic that arrives at a node. - PublicIPs []string `json:"publicIPs,omitempty" description:"externally visible IPs (e.g. load balancers) that should be proxied to this service"` + PublicIPs []string `json:"publicIPs,omitempty" description:"deprecated. externally visible IPs (e.g. load balancers) that should be proxied to this service"` // PortalIP is usually assigned by the master. If specified by the user // we will try to respect it or else fail the request. This field can diff --git a/pkg/api/v1beta2/conversion.go b/pkg/api/v1beta2/conversion.go index ce2311500c9..8e02bcbf6ba 100644 --- a/pkg/api/v1beta2/conversion.go +++ b/pkg/api/v1beta2/conversion.go @@ -703,7 +703,7 @@ func addConversionFuncs() { if err := s.Convert(&in.Spec.Selector, &out.Selector, 0); err != nil { return err } - out.PublicIPs = in.Spec.PublicIPs + out.PublicIPs = in.Spec.DeprecatedPublicIPs out.PortalIP = in.Spec.PortalIP if err := s.Convert(&in.Spec.SessionAffinity, &out.SessionAffinity, 0); err != nil { return err @@ -754,7 +754,7 @@ func addConversionFuncs() { if err := s.Convert(&in.Selector, &out.Spec.Selector, 0); err != nil { return err } - out.Spec.PublicIPs = in.PublicIPs + out.Spec.DeprecatedPublicIPs = in.PublicIPs out.Spec.PortalIP = in.PortalIP if err := s.Convert(&in.SessionAffinity, &out.Spec.SessionAffinity, 0); err != nil { return err diff --git a/pkg/api/v1beta2/types.go b/pkg/api/v1beta2/types.go index 06f483ae673..1fef9c353fb 100644 --- a/pkg/api/v1beta2/types.go +++ b/pkg/api/v1beta2/types.go @@ -894,9 +894,9 @@ type Service struct { // Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer Type ServiceType `json:"type,omitempty" description:"type of this service; must be ClusterIP, NodePort, or LoadBalancer; defaults to ClusterIP"` - // PublicIPs are used by external load balancers, or can be set by + // Deprecated. PublicIPs are used by external load balancers, or can be set by // users to handle external traffic that arrives at a node. - PublicIPs []string `json:"publicIPs,omitempty" description:"externally visible IPs (e.g. load balancers) that should be proxied to this service"` + PublicIPs []string `json:"publicIPs,omitempty" description:"deprecated. externally visible IPs (e.g. load balancers) that should be proxied to this service"` // PortalIP is usually assigned by the master. If specified by the user // we will try to respect it or else fail the request. This field can diff --git a/pkg/api/v1beta3/conversion.go b/pkg/api/v1beta3/conversion.go index 87817b130c2..a4de8508a28 100644 --- a/pkg/api/v1beta3/conversion.go +++ b/pkg/api/v1beta3/conversion.go @@ -369,12 +369,12 @@ func convert_v1beta3_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.Se } if in.PublicIPs != nil { - out.PublicIPs = make([]string, len(in.PublicIPs)) + out.DeprecatedPublicIPs = make([]string, len(in.PublicIPs)) for i := range in.PublicIPs { - out.PublicIPs[i] = in.PublicIPs[i] + out.DeprecatedPublicIPs[i] = in.PublicIPs[i] } } else { - out.PublicIPs = nil + out.DeprecatedPublicIPs = nil } out.SessionAffinity = api.ServiceAffinity(in.SessionAffinity) return nil @@ -409,10 +409,10 @@ func convert_api_ServiceSpec_To_v1beta3_ServiceSpec(in *api.ServiceSpec, out *Se } out.CreateExternalLoadBalancer = in.Type == api.ServiceTypeLoadBalancer - if in.PublicIPs != nil { - out.PublicIPs = make([]string, len(in.PublicIPs)) - for i := range in.PublicIPs { - out.PublicIPs[i] = in.PublicIPs[i] + if in.DeprecatedPublicIPs != nil { + out.PublicIPs = make([]string, len(in.DeprecatedPublicIPs)) + for i := range in.DeprecatedPublicIPs { + out.PublicIPs[i] = in.DeprecatedPublicIPs[i] } } else { out.PublicIPs = nil diff --git a/pkg/api/v1beta3/types.go b/pkg/api/v1beta3/types.go index e00ac2d4350..3f3125f1ae7 100644 --- a/pkg/api/v1beta3/types.go +++ b/pkg/api/v1beta3/types.go @@ -1058,9 +1058,9 @@ type ServiceSpec struct { // Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer Type ServiceType `json:"type,omitempty" description:"type of this service; must be ClusterIP, NodePort, or LoadBalancer; defaults to ClusterIP"` - // PublicIPs are used by external load balancers, or can be set by + // Deprecated. PublicIPs are used by external load balancers, or can be set by // users to handle external traffic that arrives at a node. - PublicIPs []string `json:"publicIPs,omitempty" description:"externally visible IPs (e.g. load balancers) that should be proxied to this service"` + PublicIPs []string `json:"publicIPs,omitempty" description:"deprecated. externally visible IPs (e.g. load balancers) that should be proxied to this service"` // Optional: Supports "ClientIP" and "None". Used to maintain session affinity. SessionAffinity ServiceAffinity `json:"sessionAffinity,omitempty" description:"enable client IP based session affinity; must be ClientIP or None; defaults to None"` diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index a4a13c0b811..8012cca7052 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -1064,7 +1064,7 @@ func ValidateService(service *api.Service) errs.ValidationErrorList { } } - for _, ip := range service.Spec.PublicIPs { + for _, ip := range service.Spec.DeprecatedPublicIPs { if ip == "0.0.0.0" { allErrs = append(allErrs, errs.NewFieldInvalid("spec.publicIPs", ip, "is not an IP address")) } else if util.IsValidIPv4(ip) && net.ParseIP(ip).IsLoopback() { diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index df71462e45b..47a74bb03e7 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -1611,21 +1611,21 @@ func TestValidateService(t *testing.T) { { name: "invalid publicIPs localhost", tweakSvc: func(s *api.Service) { - s.Spec.PublicIPs = []string{"127.0.0.1"} + s.Spec.DeprecatedPublicIPs = []string{"127.0.0.1"} }, numErrs: 1, }, { name: "invalid publicIPs", tweakSvc: func(s *api.Service) { - s.Spec.PublicIPs = []string{"0.0.0.0"} + s.Spec.DeprecatedPublicIPs = []string{"0.0.0.0"} }, numErrs: 1, }, { name: "valid publicIPs host", tweakSvc: func(s *api.Service) { - s.Spec.PublicIPs = []string{"myhost.mydomain"} + s.Spec.DeprecatedPublicIPs = []string{"myhost.mydomain"} }, numErrs: 0, }, diff --git a/pkg/cloudprovider/servicecontroller/servicecontroller.go b/pkg/cloudprovider/servicecontroller/servicecontroller.go index 170ab20da9b..a7474dd7c6f 100644 --- a/pkg/cloudprovider/servicecontroller/servicecontroller.go +++ b/pkg/cloudprovider/servicecontroller/servicecontroller.go @@ -249,7 +249,7 @@ func (s *ServiceController) createLoadBalancerIfNeeded(namespacedName types.Name return nil, notRetryable } else if exists { glog.Infof("Deleting old LB for previously uncached service %s whose endpoint %s doesn't match the service's desired IPs %v", - namespacedName, status, service.Spec.PublicIPs) + namespacedName, status, service.Spec.DeprecatedPublicIPs) if err := s.balancer.EnsureTCPLoadBalancerDeleted(s.loadBalancerName(service), s.zone.Region); err != nil { return err, retryable } @@ -324,8 +324,8 @@ func (s *ServiceController) createExternalLoadBalancer(service *api.Service) err return err } name := s.loadBalancerName(service) - if len(service.Spec.PublicIPs) > 0 { - for _, publicIP := range service.Spec.PublicIPs { + if len(service.Spec.DeprecatedPublicIPs) > 0 { + for _, publicIP := range service.Spec.DeprecatedPublicIPs { // TODO: Make this actually work for multiple IPs by using different // names for each. For now, we'll just create the first and break. status, err := s.balancer.CreateTCPLoadBalancer(name, s.zone.Region, net.ParseIP(publicIP), @@ -413,11 +413,11 @@ func needsUpdate(oldService *api.Service, newService *api.Service) bool { if !portsEqual(oldService, newService) || oldService.Spec.SessionAffinity != newService.Spec.SessionAffinity { return true } - if len(oldService.Spec.PublicIPs) != len(newService.Spec.PublicIPs) { + if len(oldService.Spec.DeprecatedPublicIPs) != len(newService.Spec.DeprecatedPublicIPs) { return true } - for i := range oldService.Spec.PublicIPs { - if oldService.Spec.PublicIPs[i] != newService.Spec.PublicIPs[i] { + for i := range oldService.Spec.DeprecatedPublicIPs { + if oldService.Spec.DeprecatedPublicIPs[i] != newService.Spec.DeprecatedPublicIPs[i] { return true } } diff --git a/pkg/kubectl/resource_printer_test.go b/pkg/kubectl/resource_printer_test.go index fe0d2662510..8e518a58e42 100644 --- a/pkg/kubectl/resource_printer_test.go +++ b/pkg/kubectl/resource_printer_test.go @@ -933,9 +933,6 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) { ObjectMeta: api.ObjectMeta{Name: name, Namespace: namespaceName}, Spec: api.ServiceSpec{ PortalIP: "1.2.3.4", - PublicIPs: []string{ - "2.3.4.5", - }, Ports: []api.ServicePort{ { Port: 80, @@ -943,6 +940,15 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) { }, }, }, + Status: api.ServiceStatus{ + LoadBalancer: api.LoadBalancerStatus{ + Ingress: []api.LoadBalancerIngress{ + { + IP: "2.3.4.5", + }, + }, + }, + }, }, printNamespace: true, }, diff --git a/pkg/kubectl/service.go b/pkg/kubectl/service.go index 08c0becafc1..8c631b2751a 100644 --- a/pkg/kubectl/service.go +++ b/pkg/kubectl/service.go @@ -106,7 +106,7 @@ func (ServiceGenerator) Generate(params map[string]string) (runtime.Object, erro service.Spec.Type = api.ServiceTypeLoadBalancer } if len(params["public-ip"]) != 0 { - service.Spec.PublicIPs = []string{params["public-ip"]} + service.Spec.DeprecatedPublicIPs = []string{params["public-ip"]} } if len(params["type"]) != 0 { service.Spec.Type = api.ServiceType(params["type"]) diff --git a/pkg/kubectl/service_test.go b/pkg/kubectl/service_test.go index d98a40eed38..e3c7682ef85 100644 --- a/pkg/kubectl/service_test.go +++ b/pkg/kubectl/service_test.go @@ -144,7 +144,7 @@ func TestGenerateService(t *testing.T) { TargetPort: util.NewIntOrStringFromString("foobar"), }, }, - PublicIPs: []string{"1.2.3.4"}, + DeprecatedPublicIPs: []string{"1.2.3.4"}, }, }, }, @@ -175,8 +175,8 @@ func TestGenerateService(t *testing.T) { TargetPort: util.NewIntOrStringFromString("foobar"), }, }, - PublicIPs: []string{"1.2.3.4"}, - Type: api.ServiceTypeLoadBalancer, + Type: api.ServiceTypeLoadBalancer, + DeprecatedPublicIPs: []string{"1.2.3.4"}, }, }, }, diff --git a/pkg/proxy/proxier_test.go b/pkg/proxy/proxier_test.go index 350da4b3f04..ddf9c92e6c2 100644 --- a/pkg/proxy/proxier_test.go +++ b/pkg/proxy/proxier_test.go @@ -723,8 +723,8 @@ func TestProxyUpdatePublicIPs(t *testing.T) { Port: svcInfo.portalPort, Protocol: "TCP", }}, - PortalIP: svcInfo.portalIP.String(), - PublicIPs: []string{"4.3.2.1"}, + PortalIP: svcInfo.portalIP.String(), + DeprecatedPublicIPs: []string{"4.3.2.1"}, }, }}) // Wait for the socket to actually get free.