diff --git a/pkg/api/types.go b/pkg/api/types.go index 8c965264fe90c..4630cbd7644ea 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -720,6 +720,9 @@ type ServiceSpec struct { CreateExternalLoadBalancer bool `json:"createExternalLoadBalancer,omitempty"` // 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"` // ContainerPort is the name or number of the port on the container to direct traffic to. diff --git a/pkg/cloudprovider/cloud.go b/pkg/cloudprovider/cloud.go index 7960c00c57e84..6ff011aff4a98 100644 --- a/pkg/cloudprovider/cloud.go +++ b/pkg/cloudprovider/cloud.go @@ -47,8 +47,8 @@ type TCPLoadBalancer interface { // TCPLoadBalancerExists returns whether the specified load balancer exists. // TODO: Break this up into different interfaces (LB, etc) when we have more than one type of service TCPLoadBalancerExists(name, region string) (bool, error) - // CreateTCPLoadBalancer creates a new tcp load balancer. Returns the IP address of the balancer - CreateTCPLoadBalancer(name, region string, externalIP net.IP, port int, hosts []string, affinityType api.AffinityType) (net.IP, error) + // CreateTCPLoadBalancer creates a new tcp load balancer. Returns the IP address or hostname of the balancer + CreateTCPLoadBalancer(name, region string, externalIP net.IP, port int, hosts []string, affinityType api.AffinityType) (string, error) // UpdateTCPLoadBalancer updates hosts under the specified load balancer. UpdateTCPLoadBalancer(name, region string, hosts []string) error // DeleteTCPLoadBalancer deletes a specified load balancer. diff --git a/pkg/cloudprovider/fake/fake.go b/pkg/cloudprovider/fake/fake.go index 84c8d9e9ba039..266b474e5c05d 100644 --- a/pkg/cloudprovider/fake/fake.go +++ b/pkg/cloudprovider/fake/fake.go @@ -95,10 +95,10 @@ func (f *FakeCloud) TCPLoadBalancerExists(name, region string) (bool, error) { // CreateTCPLoadBalancer is a test-spy implementation of TCPLoadBalancer.CreateTCPLoadBalancer. // It adds an entry "create" into the internal method call record. -func (f *FakeCloud) CreateTCPLoadBalancer(name, region string, externalIP net.IP, port int, hosts []string, affinityType api.AffinityType) (net.IP, error) { +func (f *FakeCloud) CreateTCPLoadBalancer(name, region string, externalIP net.IP, port int, hosts []string, affinityType api.AffinityType) (string, error) { f.addCall("create") f.Balancers = append(f.Balancers, FakeBalancer{name, region, externalIP, port, hosts}) - return f.ExternalIP, f.Err + return f.ExternalIP.String(), f.Err } // UpdateTCPLoadBalancer is a test-spy implementation of TCPLoadBalancer.UpdateTCPLoadBalancer. diff --git a/pkg/cloudprovider/gce/gce.go b/pkg/cloudprovider/gce/gce.go index f897440c32bd1..a25cf771f855a 100644 --- a/pkg/cloudprovider/gce/gce.go +++ b/pkg/cloudprovider/gce/gce.go @@ -222,10 +222,10 @@ func translateAffinityType(affinityType api.AffinityType) GCEAffinityType { } // CreateTCPLoadBalancer is an implementation of TCPLoadBalancer.CreateTCPLoadBalancer. -func (gce *GCECloud) CreateTCPLoadBalancer(name, region string, externalIP net.IP, port int, hosts []string, affinityType api.AffinityType) (net.IP, error) { +func (gce *GCECloud) CreateTCPLoadBalancer(name, region string, externalIP net.IP, port int, hosts []string, affinityType api.AffinityType) (string, error) { pool, err := gce.makeTargetPool(name, region, hosts, translateAffinityType(affinityType)) if err != nil { - return nil, err + return "", err } req := &compute.ForwardingRule{ Name: name, @@ -238,17 +238,17 @@ func (gce *GCECloud) CreateTCPLoadBalancer(name, region string, externalIP net.I } op, err := gce.service.ForwardingRules.Insert(gce.projectID, region, req).Do() if err != nil { - return nil, err + return "", err } err = gce.waitForRegionOp(op, region) if err != nil { - return nil, err + return "", err } fwd, err := gce.service.ForwardingRules.Get(gce.projectID, region, name).Do() if err != nil { - return nil, err + return "", err } - return net.ParseIP(fwd.IPAddress), nil + return fwd.IPAddress, nil } // UpdateTCPLoadBalancer is an implementation of TCPLoadBalancer.UpdateTCPLoadBalancer. diff --git a/pkg/cloudprovider/openstack/openstack.go b/pkg/cloudprovider/openstack/openstack.go index 409495c75d672..9de1722d63948 100644 --- a/pkg/cloudprovider/openstack/openstack.go +++ b/pkg/cloudprovider/openstack/openstack.go @@ -425,10 +425,10 @@ func (lb *LoadBalancer) TCPLoadBalancerExists(name, region string) (bool, error) // a list of regions (from config) and query/create loadbalancers in // each region. -func (lb *LoadBalancer) CreateTCPLoadBalancer(name, region string, externalIP net.IP, port int, hosts []string, affinity api.AffinityType) (net.IP, error) { +func (lb *LoadBalancer) CreateTCPLoadBalancer(name, region string, externalIP net.IP, port int, hosts []string, affinity api.AffinityType) (string, error) { glog.V(2).Infof("CreateTCPLoadBalancer(%v, %v, %v, %v, %v)", name, region, externalIP, port, hosts) if affinity != api.AffinityTypeNone { - return nil, fmt.Errorf("unsupported load balancer affinity: %v", affinity) + return "", fmt.Errorf("unsupported load balancer affinity: %v", affinity) } pool, err := pools.Create(lb.network, pools.CreateOpts{ Name: name, @@ -436,13 +436,13 @@ func (lb *LoadBalancer) CreateTCPLoadBalancer(name, region string, externalIP ne SubnetID: lb.opts.SubnetId, }).Extract() if err != nil { - return nil, err + return "", err } for _, host := range hosts { addr, err := getAddressByName(lb.compute, host) if err != nil { - return nil, err + return "", err } _, err = members.Create(lb.network, members.CreateOpts{ @@ -452,7 +452,7 @@ func (lb *LoadBalancer) CreateTCPLoadBalancer(name, region string, externalIP ne }).Extract() if err != nil { pools.Delete(lb.network, pool.ID) - return nil, err + return "", err } } @@ -466,14 +466,14 @@ func (lb *LoadBalancer) CreateTCPLoadBalancer(name, region string, externalIP ne }).Extract() if err != nil { pools.Delete(lb.network, pool.ID) - return nil, err + return "", err } _, err = pools.AssociateMonitor(lb.network, pool.ID, mon.ID).Extract() if err != nil { monitors.Delete(lb.network, mon.ID) pools.Delete(lb.network, pool.ID) - return nil, err + return "", err } } @@ -490,10 +490,10 @@ func (lb *LoadBalancer) CreateTCPLoadBalancer(name, region string, externalIP ne monitors.Delete(lb.network, mon.ID) } pools.Delete(lb.network, pool.ID) - return nil, err + return "", err } - return net.ParseIP(vip.Address), nil + return vip.Address, nil } func (lb *LoadBalancer) UpdateTCPLoadBalancer(name, region string, hosts []string) error { diff --git a/pkg/registry/service/rest.go b/pkg/registry/service/rest.go index 3875b0019e075..ff313eae9c8e4 100644 --- a/pkg/registry/service/rest.go +++ b/pkg/registry/service/rest.go @@ -272,11 +272,11 @@ func (rs *REST) createExternalLoadBalancer(ctx api.Context, service *api.Service } } } else { - ip, err := balancer.CreateTCPLoadBalancer(name, zone.Region, nil, service.Spec.Port, hostsFromMinionList(hosts), affinityType) + endpoint, err := balancer.CreateTCPLoadBalancer(name, zone.Region, nil, service.Spec.Port, hostsFromMinionList(hosts), affinityType) if err != nil { return err } - service.Spec.PublicIPs = []string{ip.String()} + service.Spec.PublicIPs = []string{endpoint} } return nil }