mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
refactor services to v1beta3
This commit is contained in:
parent
5a649f2b93
commit
bd7643c033
@ -285,10 +285,12 @@ func runSelfLinkTest(c *client.Client) {
|
||||
"name": "selflinktest",
|
||||
},
|
||||
},
|
||||
Port: 12345,
|
||||
// This is here because validation requires it.
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 12345,
|
||||
// This is here because validation requires it.
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
).Do().Into(&svc)
|
||||
@ -345,10 +347,12 @@ func runAtomicPutTest(c *client.Client) {
|
||||
"name": "atomicService",
|
||||
},
|
||||
},
|
||||
Port: 12345,
|
||||
// This is here because validation requires it.
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 12345,
|
||||
// This is here because validation requires it.
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
).Do().Into(&svc)
|
||||
@ -379,10 +383,10 @@ func runAtomicPutTest(c *client.Client) {
|
||||
glog.Errorf("Error getting atomicService: %v", err)
|
||||
continue
|
||||
}
|
||||
if tmpSvc.Selector == nil {
|
||||
tmpSvc.Selector = map[string]string{l: v}
|
||||
if tmpSvc.Spec.Selector == nil {
|
||||
tmpSvc.Spec.Selector = map[string]string{l: v}
|
||||
} else {
|
||||
tmpSvc.Selector[l] = v
|
||||
tmpSvc.Spec.Selector[l] = v
|
||||
}
|
||||
glog.Infof("Posting update (%s, %s)", l, v)
|
||||
err = c.Put().Path("services").Path(svc.Name).Body(&tmpSvc).Do().Error()
|
||||
@ -405,8 +409,8 @@ func runAtomicPutTest(c *client.Client) {
|
||||
if err := c.Get().Path("services").Path(svc.Name).Do().Into(&svc); err != nil {
|
||||
glog.Fatalf("Failed getting atomicService after writers are complete: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(testLabels, labels.Set(svc.Selector)) {
|
||||
glog.Fatalf("Selector PUTs were not atomic: wanted %v, got %v", testLabels, svc.Selector)
|
||||
if !reflect.DeepEqual(testLabels, labels.Set(svc.Spec.Selector)) {
|
||||
glog.Fatalf("Selector PUTs were not atomic: wanted %v, got %v", testLabels, svc.Spec.Selector)
|
||||
}
|
||||
glog.Info("Atomic PUTs work.")
|
||||
}
|
||||
@ -508,10 +512,12 @@ func runServiceTest(client *client.Client) {
|
||||
}
|
||||
svc1 := api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "service1"},
|
||||
Selector: map[string]string{
|
||||
"name": "thisisalonglabel",
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{
|
||||
"name": "thisisalonglabel",
|
||||
},
|
||||
Port: 8080,
|
||||
},
|
||||
Port: 8080,
|
||||
}
|
||||
_, err = client.Services(api.NamespaceDefault).Create(&svc1)
|
||||
if err != nil {
|
||||
@ -523,10 +529,12 @@ func runServiceTest(client *client.Client) {
|
||||
// A second service with the same port.
|
||||
svc2 := api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "service2"},
|
||||
Selector: map[string]string{
|
||||
"name": "thisisalonglabel",
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{
|
||||
"name": "thisisalonglabel",
|
||||
},
|
||||
Port: 8080,
|
||||
},
|
||||
Port: 8080,
|
||||
}
|
||||
_, err = client.Services(api.NamespaceDefault).Create(&svc2)
|
||||
if err != nil {
|
||||
|
@ -479,6 +479,38 @@ type ServiceList struct {
|
||||
Items []Service `json:"items" yaml:"items"`
|
||||
}
|
||||
|
||||
// ServiceStatus represents the current status of a service
|
||||
type ServiceStatus struct{}
|
||||
|
||||
// ServiceSpec describes the attributes that a user creates on a service
|
||||
type ServiceSpec struct {
|
||||
// Port is the TCP or UDP port that will be made available to each pod for connecting to the pods
|
||||
// proxied by this service.
|
||||
Port int `json:"port" yaml:"port"`
|
||||
|
||||
// Optional: Supports "TCP" and "UDP". Defaults to "TCP".
|
||||
Protocol Protocol `json:"protocol,omitempty" yaml:"protocol,omitempty"`
|
||||
|
||||
// This service will route traffic to pods having labels matching this selector.
|
||||
Selector map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"`
|
||||
|
||||
// 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
|
||||
// not be changed by updates.
|
||||
PortalIP string `json:"portalIP,omitempty" yaml:"portalIP,omitempty"`
|
||||
|
||||
// ProxyPort is assigned by the master. If 0, the proxy will choose an ephemeral port.
|
||||
// TODO: This is awkward - if we had a BoundService, it would be better factored.
|
||||
ProxyPort int `json:"proxyPort,omitempty" yaml:"proxyPort,omitempty"`
|
||||
|
||||
// CreateExternalLoadBalancer indicates whether a load balancer should be created for this service.
|
||||
CreateExternalLoadBalancer bool `json:"createExternalLoadBalancer,omitempty" yaml:"createExternalLoadBalancer,omitempty"`
|
||||
|
||||
// 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" yaml:"containerPort,omitempty"`
|
||||
}
|
||||
|
||||
// Service is a named abstraction of software service (for example, mysql) consisting of local port
|
||||
// (for example 3306) that the proxy listens on, and the selector that determines which pods
|
||||
// will answer requests sent through the proxy.
|
||||
@ -486,27 +518,11 @@ type Service struct {
|
||||
TypeMeta `json:",inline" yaml:",inline"`
|
||||
ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
|
||||
|
||||
// Required.
|
||||
Port int `json:"port" yaml:"port"`
|
||||
// Optional: Defaults to "TCP".
|
||||
Protocol Protocol `yaml:"protocol,omitempty" json:"protocol,omitempty"`
|
||||
// Spec defines the behavior of a service.
|
||||
Spec ServiceSpec `json:"spec,omitempty" yaml:"spec,omitempty"`
|
||||
|
||||
// This service will route traffic to pods having labels matching this selector.
|
||||
Selector map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"`
|
||||
CreateExternalLoadBalancer bool `json:"createExternalLoadBalancer,omitempty" yaml:"createExternalLoadBalancer,omitempty"`
|
||||
|
||||
// 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" yaml:"containerPort,omitempty"`
|
||||
|
||||
// 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
|
||||
// not be changed by updates.
|
||||
PortalIP string `json:"portalIP,omitempty" yaml:"portalIP,omitempty"`
|
||||
|
||||
// ProxyPort is assigned by the master. If specified by the user it will be ignored.
|
||||
// TODO: This is awkward - if we had a BoundService, it would be better factored.
|
||||
ProxyPort int `json:"proxyPort,omitempty" yaml:"proxyPort,omitempty"`
|
||||
// Status represents the current status of a service.
|
||||
Status ServiceStatus `json:"status,omitempty" yaml:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Endpoints is a collection of endpoints that implement the actual service, for example:
|
||||
|
@ -247,6 +247,7 @@ func init() {
|
||||
},
|
||||
|
||||
func(in *newer.Service, out *Service, s conversion.Scope) error {
|
||||
|
||||
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -257,16 +258,15 @@ func init() {
|
||||
return err
|
||||
}
|
||||
|
||||
out.Port = in.Port
|
||||
out.Protocol = Protocol(in.Protocol)
|
||||
if err := s.Convert(&in.Selector, &out.Selector, 0); err != nil {
|
||||
out.Port = in.Spec.Port
|
||||
out.Protocol = Protocol(in.Spec.Protocol)
|
||||
if err := s.Convert(&in.Spec.Selector, &out.Selector, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
out.CreateExternalLoadBalancer = in.CreateExternalLoadBalancer
|
||||
out.ContainerPort = in.ContainerPort
|
||||
out.PortalIP = in.PortalIP
|
||||
out.ProxyPort = in.ProxyPort
|
||||
|
||||
out.CreateExternalLoadBalancer = in.Spec.CreateExternalLoadBalancer
|
||||
out.ContainerPort = in.Spec.ContainerPort
|
||||
out.PortalIP = in.Spec.PortalIP
|
||||
out.ProxyPort = in.Spec.ProxyPort
|
||||
return nil
|
||||
},
|
||||
func(in *Service, out *newer.Service, s conversion.Scope) error {
|
||||
@ -280,16 +280,15 @@ func init() {
|
||||
return err
|
||||
}
|
||||
|
||||
out.Port = in.Port
|
||||
out.Protocol = newer.Protocol(in.Protocol)
|
||||
if err := s.Convert(&in.Selector, &out.Selector, 0); err != nil {
|
||||
out.Spec.Port = in.Port
|
||||
out.Spec.Protocol = newer.Protocol(in.Protocol)
|
||||
if err := s.Convert(&in.Selector, &out.Spec.Selector, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
out.CreateExternalLoadBalancer = in.CreateExternalLoadBalancer
|
||||
out.ContainerPort = in.ContainerPort
|
||||
out.PortalIP = in.PortalIP
|
||||
out.ProxyPort = in.ProxyPort
|
||||
|
||||
out.Spec.CreateExternalLoadBalancer = in.CreateExternalLoadBalancer
|
||||
out.Spec.ContainerPort = in.ContainerPort
|
||||
out.Spec.PortalIP = in.PortalIP
|
||||
out.Spec.ProxyPort = in.ProxyPort
|
||||
return nil
|
||||
},
|
||||
|
||||
|
@ -188,15 +188,15 @@ func init() {
|
||||
return err
|
||||
}
|
||||
|
||||
out.Port = in.Port
|
||||
out.Protocol = Protocol(in.Protocol)
|
||||
if err := s.Convert(&in.Selector, &out.Selector, 0); err != nil {
|
||||
out.Port = in.Spec.Port
|
||||
out.Protocol = Protocol(in.Spec.Protocol)
|
||||
if err := s.Convert(&in.Spec.Selector, &out.Selector, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
out.CreateExternalLoadBalancer = in.CreateExternalLoadBalancer
|
||||
out.ContainerPort = in.ContainerPort
|
||||
out.PortalIP = in.PortalIP
|
||||
out.ProxyPort = in.ProxyPort
|
||||
out.CreateExternalLoadBalancer = in.Spec.CreateExternalLoadBalancer
|
||||
out.ContainerPort = in.Spec.ContainerPort
|
||||
out.PortalIP = in.Spec.PortalIP
|
||||
out.ProxyPort = in.Spec.ProxyPort
|
||||
|
||||
return nil
|
||||
},
|
||||
@ -211,15 +211,15 @@ func init() {
|
||||
return err
|
||||
}
|
||||
|
||||
out.Port = in.Port
|
||||
out.Protocol = newer.Protocol(in.Protocol)
|
||||
if err := s.Convert(&in.Selector, &out.Selector, 0); err != nil {
|
||||
out.Spec.Port = in.Port
|
||||
out.Spec.Protocol = newer.Protocol(in.Protocol)
|
||||
if err := s.Convert(&in.Selector, &out.Spec.Selector, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
out.CreateExternalLoadBalancer = in.CreateExternalLoadBalancer
|
||||
out.ContainerPort = in.ContainerPort
|
||||
out.PortalIP = in.PortalIP
|
||||
out.ProxyPort = in.ProxyPort
|
||||
out.Spec.CreateExternalLoadBalancer = in.CreateExternalLoadBalancer
|
||||
out.Spec.ContainerPort = in.ContainerPort
|
||||
out.Spec.PortalIP = in.PortalIP
|
||||
out.Spec.ProxyPort = in.ProxyPort
|
||||
|
||||
return nil
|
||||
},
|
||||
|
@ -123,36 +123,37 @@ const (
|
||||
NamespaceAll string = ""
|
||||
)
|
||||
|
||||
// ContainerManifest corresponds to the Container Manifest format, documented at:
|
||||
// https://developers.google.com/compute/docs/containers/container_vms#container_manifest
|
||||
// This is used as the representation of Kubernetes workloads.
|
||||
// DEPRECATED: Exists to allow backwards compatible storage for clients accessing etcd
|
||||
// directly.
|
||||
type ContainerManifest struct {
|
||||
// Required: This must be a supported version string, such as "v1beta1".
|
||||
Version string `json:"version" yaml:"version"`
|
||||
// Required: This must be a DNS_SUBDOMAIN.
|
||||
// TODO: ID on Manifest is deprecated and will be removed in the future.
|
||||
ID string `json:"id" yaml:"id"`
|
||||
// TODO: UUID on Manifest is deprecated in the future once we are done
|
||||
// with the API refactoring. It is required for now to determine the instance
|
||||
// of a Pod.
|
||||
UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"`
|
||||
Volumes []Volume `json:"volumes" yaml:"volumes"`
|
||||
Containers []Container `json:"containers" yaml:"containers"`
|
||||
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"`
|
||||
}
|
||||
|
||||
// ContainerManifestList is used to communicate container manifests to kubelet.
|
||||
// DEPRECATED: Exists to allow backwards compatible storage for clients accessing etcd
|
||||
// directly.
|
||||
type ContainerManifestList struct {
|
||||
TypeMeta `json:",inline" yaml:",inline"`
|
||||
// ID is the legacy field representing Name
|
||||
ID string `json:"id,omitempty" yaml:"id,omitempty"`
|
||||
|
||||
Items []ContainerManifest `json:"items,omitempty" yaml:"items,omitempty"`
|
||||
}
|
||||
//
|
||||
//// ContainerManifest corresponds to the Container Manifest format, documented at:
|
||||
//// https://developers.google.com/compute/docs/containers/container_vms#container_manifest
|
||||
//// This is used as the representation of Kubernetes workloads.
|
||||
//// DEPRECATED: Exists to allow backwards compatible storage for clients accessing etcd
|
||||
//// directly.
|
||||
//type ContainerManifest struct {
|
||||
// // Required: This must be a supported version string, such as "v1beta1".
|
||||
// Version string `json:"version" yaml:"version"`
|
||||
// // Required: This must be a DNS_SUBDOMAIN.
|
||||
// // TODO: ID on Manifest is deprecated and will be removed in the future.
|
||||
// ID string `json:"id" yaml:"id"`
|
||||
// // TODO: UUID on Manifest is deprecated in the future once we are done
|
||||
// // with the API refactoring. It is required for now to determine the instance
|
||||
// // of a Pod.
|
||||
// UUID string `json:"uuid,omitempty" yaml:"uuid,omitempty"`
|
||||
// Volumes []Volume `json:"volumes" yaml:"volumes"`
|
||||
// Containers []Container `json:"containers" yaml:"containers"`
|
||||
// RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" yaml:"restartPolicy,omitempty"`
|
||||
//}
|
||||
//
|
||||
//// ContainerManifestList is used to communicate container manifests to kubelet.
|
||||
//// DEPRECATED: Exists to allow backwards compatible storage for clients accessing etcd
|
||||
//// directly.
|
||||
//type ContainerManifestList struct {
|
||||
// TypeMeta `json:",inline" yaml:",inline"`
|
||||
// // ID is the legacy field representing Name
|
||||
// ID string `json:"id,omitempty" yaml:"id,omitempty"`
|
||||
//
|
||||
// Items []ContainerManifest `json:"items,omitempty" yaml:"items,omitempty"`
|
||||
//}
|
||||
|
||||
// Volume represents a named volume in a pod that may be accessed by any containers in the pod.
|
||||
type Volume struct {
|
||||
@ -583,10 +584,7 @@ type ReplicationControllerList struct {
|
||||
}
|
||||
|
||||
// ServiceStatus represents the current status of a service
|
||||
type ServiceStatus struct {
|
||||
// ProxyPort is assigned by the master. If 0, the proxy will choose an ephemeral port.
|
||||
ProxyPort int `json:"proxyPort,omitempty" yaml:"proxyPort,omitempty"`
|
||||
}
|
||||
type ServiceStatus struct{}
|
||||
|
||||
// ServiceSpec describes the attributes that a user creates on a service
|
||||
type ServiceSpec struct {
|
||||
@ -605,6 +603,9 @@ type ServiceSpec struct {
|
||||
// not be changed by updates.
|
||||
PortalIP string `json:"portalIP,omitempty" yaml:"portalIP,omitempty"`
|
||||
|
||||
// ProxyPort is assigned by the master. If 0, the proxy will choose an ephemeral port.
|
||||
ProxyPort int `json:"proxyPort,omitempty" yaml:"proxyPort,omitempty"`
|
||||
|
||||
// CreateExternalLoadBalancer indicates whether a load balancer should be created for this service.
|
||||
CreateExternalLoadBalancer bool `json:"createExternalLoadBalancer,omitempty" yaml:"createExternalLoadBalancer,omitempty"`
|
||||
|
||||
|
@ -392,19 +392,19 @@ func ValidateService(service *api.Service) errs.ValidationErrorList {
|
||||
if !util.IsDNSSubdomain(service.Namespace) {
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid("namespace", service.Namespace))
|
||||
}
|
||||
if !util.IsValidPortNum(service.Port) {
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid("port", service.Port))
|
||||
if !util.IsValidPortNum(service.Spec.Port) {
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid("spec.port", service.Spec.Port))
|
||||
}
|
||||
if len(service.Protocol) == 0 {
|
||||
service.Protocol = "TCP"
|
||||
} else if !supportedPortProtocols.Has(strings.ToUpper(string(service.Protocol))) {
|
||||
allErrs = append(allErrs, errs.NewFieldNotSupported("protocol", service.Protocol))
|
||||
if len(service.Spec.Protocol) == 0 {
|
||||
service.Spec.Protocol = "TCP"
|
||||
} else if !supportedPortProtocols.Has(strings.ToUpper(string(service.Spec.Protocol))) {
|
||||
allErrs = append(allErrs, errs.NewFieldNotSupported("spec.protocol", service.Spec.Protocol))
|
||||
}
|
||||
if labels.Set(service.Selector).AsSelector().Empty() {
|
||||
allErrs = append(allErrs, errs.NewFieldRequired("selector", service.Selector))
|
||||
if labels.Set(service.Spec.Selector).AsSelector().Empty() {
|
||||
allErrs = append(allErrs, errs.NewFieldRequired("spec.selector", service.Spec.Selector))
|
||||
}
|
||||
allErrs = append(allErrs, validateLabels(service.Labels)...)
|
||||
allErrs = append(allErrs, validateLabels(service.Selector)...)
|
||||
allErrs = append(allErrs, validateLabels(service.Spec.Selector)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
|
@ -633,8 +633,10 @@ func TestValidateService(t *testing.T) {
|
||||
name: "missing id",
|
||||
svc: api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Namespace: api.NamespaceDefault},
|
||||
Port: 8675,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8675,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
// Should fail because the ID is missing.
|
||||
numErrs: 1,
|
||||
@ -643,8 +645,10 @@ func TestValidateService(t *testing.T) {
|
||||
name: "missing namespace",
|
||||
svc: api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Port: 8675,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8675,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
// Should fail because the Namespace is missing.
|
||||
numErrs: 1,
|
||||
@ -653,8 +657,10 @@ func TestValidateService(t *testing.T) {
|
||||
name: "invalid id",
|
||||
svc: api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "123abc", Namespace: api.NamespaceDefault},
|
||||
Port: 8675,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8675,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
// Should fail because the ID is invalid.
|
||||
numErrs: 1,
|
||||
@ -663,7 +669,9 @@ func TestValidateService(t *testing.T) {
|
||||
name: "missing port",
|
||||
svc: api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc123", Namespace: api.NamespaceDefault},
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
// Should fail because the port number is missing/invalid.
|
||||
numErrs: 1,
|
||||
@ -672,8 +680,10 @@ func TestValidateService(t *testing.T) {
|
||||
name: "invalid port",
|
||||
svc: api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc123", Namespace: api.NamespaceDefault},
|
||||
Port: 65536,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 66536,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
// Should fail because the port number is invalid.
|
||||
numErrs: 1,
|
||||
@ -682,9 +692,11 @@ func TestValidateService(t *testing.T) {
|
||||
name: "invalid protocol",
|
||||
svc: api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc123", Namespace: api.NamespaceDefault},
|
||||
Port: 8675,
|
||||
Protocol: "INVALID",
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8675,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Protocol: "INVALID",
|
||||
},
|
||||
},
|
||||
// Should fail because the protocol is invalid.
|
||||
numErrs: 1,
|
||||
@ -693,7 +705,9 @@ func TestValidateService(t *testing.T) {
|
||||
name: "missing selector",
|
||||
svc: api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault},
|
||||
Port: 8675,
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8675,
|
||||
},
|
||||
},
|
||||
// Should fail because the selector is missing.
|
||||
numErrs: 1,
|
||||
@ -702,9 +716,11 @@ func TestValidateService(t *testing.T) {
|
||||
name: "valid 1",
|
||||
svc: api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc123", Namespace: api.NamespaceDefault},
|
||||
Port: 1,
|
||||
Protocol: "TCP",
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8675,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Protocol: "TCP",
|
||||
},
|
||||
},
|
||||
numErrs: 0,
|
||||
},
|
||||
@ -712,9 +728,11 @@ func TestValidateService(t *testing.T) {
|
||||
name: "valid 2",
|
||||
svc: api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc123", Namespace: api.NamespaceDefault},
|
||||
Port: 65535,
|
||||
Protocol: "UDP",
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8675,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Protocol: "UDP",
|
||||
},
|
||||
},
|
||||
numErrs: 0,
|
||||
},
|
||||
@ -722,8 +740,10 @@ func TestValidateService(t *testing.T) {
|
||||
name: "valid 3",
|
||||
svc: api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc123", Namespace: api.NamespaceDefault},
|
||||
Port: 80,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8675,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
},
|
||||
},
|
||||
numErrs: 0,
|
||||
},
|
||||
@ -737,8 +757,10 @@ func TestValidateService(t *testing.T) {
|
||||
"NoUppercaseOrSpecialCharsLike=Equals": "bar",
|
||||
},
|
||||
},
|
||||
Port: 80,
|
||||
Selector: map[string]string{"foo": "bar", "NoUppercaseOrSpecialCharsLike=Equals": "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8675,
|
||||
Selector: map[string]string{"foo": "bar", "NoUppercaseOrSpecialCharsLike=Equals": "bar"},
|
||||
},
|
||||
},
|
||||
numErrs: 2,
|
||||
},
|
||||
@ -752,15 +774,17 @@ func TestValidateService(t *testing.T) {
|
||||
}
|
||||
|
||||
svc := api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault},
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8675,
|
||||
Selector: map[string]string{"foo": "bar"},
|
||||
},
|
||||
}
|
||||
errs := ValidateService(&svc)
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("Unexpected non-zero error list: %#v", errs)
|
||||
}
|
||||
if svc.Protocol != "TCP" {
|
||||
if svc.Spec.Protocol != "TCP" {
|
||||
t.Errorf("Expected default protocol of 'TCP': %#v", errs)
|
||||
}
|
||||
}
|
||||
|
@ -429,8 +429,10 @@ func TestListServices(t *testing.T) {
|
||||
"name": "baz",
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{
|
||||
"one": "two",
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{
|
||||
"one": "two",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -456,8 +458,10 @@ func TestListServicesLabels(t *testing.T) {
|
||||
"name": "baz",
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{
|
||||
"one": "two",
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{
|
||||
"one": "two",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -276,7 +276,7 @@ func TestRequestDo(t *testing.T) {
|
||||
|
||||
func TestDoRequestNewWay(t *testing.T) {
|
||||
reqBody := "request body"
|
||||
expectedObj := &api.Service{Port: 12345}
|
||||
expectedObj := &api.Service{Spec: api.ServiceSpec{Port: 12345}}
|
||||
expectedBody, _ := v1beta2.Codec.Encode(expectedObj)
|
||||
fakeHandler := util.FakeHandler{
|
||||
StatusCode: 200,
|
||||
@ -311,7 +311,7 @@ func TestDoRequestNewWay(t *testing.T) {
|
||||
func TestDoRequestNewWayReader(t *testing.T) {
|
||||
reqObj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
|
||||
reqBodyExpected, _ := v1beta1.Codec.Encode(reqObj)
|
||||
expectedObj := &api.Service{Port: 12345}
|
||||
expectedObj := &api.Service{Spec: api.ServiceSpec{Port: 12345}}
|
||||
expectedBody, _ := v1beta1.Codec.Encode(expectedObj)
|
||||
fakeHandler := util.FakeHandler{
|
||||
StatusCode: 200,
|
||||
@ -347,7 +347,7 @@ func TestDoRequestNewWayReader(t *testing.T) {
|
||||
func TestDoRequestNewWayObj(t *testing.T) {
|
||||
reqObj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}
|
||||
reqBodyExpected, _ := v1beta2.Codec.Encode(reqObj)
|
||||
expectedObj := &api.Service{Port: 12345}
|
||||
expectedObj := &api.Service{Spec: api.ServiceSpec{Port: 12345}}
|
||||
expectedBody, _ := v1beta2.Codec.Encode(expectedObj)
|
||||
fakeHandler := util.FakeHandler{
|
||||
StatusCode: 200,
|
||||
@ -396,7 +396,7 @@ func TestDoRequestNewWayFile(t *testing.T) {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
expectedObj := &api.Service{Port: 12345}
|
||||
expectedObj := &api.Service{Spec: api.ServiceSpec{Port: 12345}}
|
||||
expectedBody, _ := v1beta1.Codec.Encode(expectedObj)
|
||||
fakeHandler := util.FakeHandler{
|
||||
StatusCode: 200,
|
||||
@ -439,7 +439,7 @@ func TestWasCreated(t *testing.T) {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
expectedObj := &api.Service{Port: 12345}
|
||||
expectedObj := &api.Service{Spec: api.ServiceSpec{Port: 12345}}
|
||||
expectedBody, _ := v1beta1.Codec.Encode(expectedObj)
|
||||
fakeHandler := util.FakeHandler{
|
||||
StatusCode: 201,
|
||||
|
@ -309,9 +309,11 @@ func createService(ctx api.Context, name string, port int, client client.Interfa
|
||||
"name": name,
|
||||
},
|
||||
},
|
||||
Port: port,
|
||||
Selector: map[string]string{
|
||||
"name": name,
|
||||
Spec: api.ServiceSpec{
|
||||
Port: port,
|
||||
Selector: map[string]string{
|
||||
"name": name,
|
||||
},
|
||||
},
|
||||
}
|
||||
svc, err := client.Services(api.Namespace(ctx)).Create(svc)
|
||||
|
@ -94,9 +94,11 @@ func TestParseService(t *testing.T) {
|
||||
"area": "staging",
|
||||
},
|
||||
},
|
||||
Port: 8080,
|
||||
Selector: map[string]string{
|
||||
"area": "staging",
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8080,
|
||||
Selector: map[string]string{
|
||||
"area": "staging",
|
||||
},
|
||||
},
|
||||
}, v1beta1.Codec, testParser)
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ func printReplicationControllerList(list *api.ReplicationControllerList, w io.Wr
|
||||
|
||||
func printService(svc *api.Service, w io.Writer) error {
|
||||
_, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%d\n", svc.Name, labels.Set(svc.Labels),
|
||||
labels.Set(svc.Selector), svc.PortalIP, svc.Port)
|
||||
labels.Set(svc.Spec.Selector), svc.Spec.PortalIP, svc.Spec.Port)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -155,8 +155,8 @@ func (d *ServiceDescriber) Describe(namespace, name string) (string, error) {
|
||||
return tabbedString(func(out *tabwriter.Writer) error {
|
||||
fmt.Fprintf(out, "Name:\t%s\n", service.Name)
|
||||
fmt.Fprintf(out, "Labels:\t%s\n", formatLabels(service.Labels))
|
||||
fmt.Fprintf(out, "Selector:\t%s\n", formatLabels(service.Selector))
|
||||
fmt.Fprintf(out, "Port:\t%d\n", service.Port)
|
||||
fmt.Fprintf(out, "Selector:\t%s\n", formatLabels(service.Spec.Selector))
|
||||
fmt.Fprintf(out, "Port:\t%d\n", service.Spec.Port)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ func printReplicationControllerList(list *api.ReplicationControllerList, w io.Wr
|
||||
|
||||
func printService(svc *api.Service, w io.Writer) error {
|
||||
_, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%d\n", svc.Name, labels.Set(svc.Labels),
|
||||
labels.Set(svc.Selector), svc.PortalIP, svc.Port)
|
||||
labels.Set(svc.Spec.Selector), svc.Spec.PortalIP, svc.Spec.Port)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -42,10 +42,7 @@ func (s sortedPods) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
func (s sortedPods) Less(i, j int) bool {
|
||||
if s[i].Namespace < s[j].Namespace {
|
||||
return true
|
||||
}
|
||||
return s[i].Name < s[j].Name
|
||||
return s[i].Namespace < s[j].Namespace
|
||||
}
|
||||
|
||||
func CreateValidPod(name, namespace, source string) api.BoundPod {
|
||||
|
@ -83,11 +83,13 @@ func (m *Master) createMasterServiceIfNeeded(serviceName string, port int) error
|
||||
Name: serviceName,
|
||||
Namespace: "default",
|
||||
},
|
||||
Port: port,
|
||||
// We're going to add the endpoints by hand, so this selector is mainly to
|
||||
// prevent identification of other pods. This selector will be useful when
|
||||
// we start hosting apiserver in a pod.
|
||||
Selector: map[string]string{"provider": "kubernetes", "component": "apiserver"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: port,
|
||||
// We're going to add the endpoints by hand, so this selector is mainly to
|
||||
// prevent identification of other pods. This selector will be useful when
|
||||
// we start hosting apiserver in a pod.
|
||||
Selector: map[string]string{"provider": "kubernetes", "component": "apiserver"},
|
||||
},
|
||||
}
|
||||
// Kids, don't do this at home: this is a hack. There's no good way to call the business
|
||||
// logic which lives in the REST object from here.
|
||||
|
@ -136,7 +136,7 @@ func TestNewServiceAddedAndNotified(t *testing.T) {
|
||||
handler := NewServiceHandlerMock()
|
||||
handler.Wait(1)
|
||||
config.RegisterHandler(handler)
|
||||
serviceUpdate := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}, Port: 10})
|
||||
serviceUpdate := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{Port: 10}})
|
||||
channel <- serviceUpdate
|
||||
handler.ValidateServices(t, serviceUpdate.Services)
|
||||
|
||||
@ -147,12 +147,12 @@ func TestServiceAddedRemovedSetAndNotified(t *testing.T) {
|
||||
channel := config.Channel("one")
|
||||
handler := NewServiceHandlerMock()
|
||||
config.RegisterHandler(handler)
|
||||
serviceUpdate := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}, Port: 10})
|
||||
serviceUpdate := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{Port: 10}})
|
||||
handler.Wait(1)
|
||||
channel <- serviceUpdate
|
||||
handler.ValidateServices(t, serviceUpdate.Services)
|
||||
|
||||
serviceUpdate2 := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "bar"}, Port: 20})
|
||||
serviceUpdate2 := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "bar"}, Spec: api.ServiceSpec{Port: 20}})
|
||||
handler.Wait(1)
|
||||
channel <- serviceUpdate2
|
||||
services := []api.Service{serviceUpdate2.Services[0], serviceUpdate.Services[0]}
|
||||
@ -164,7 +164,7 @@ func TestServiceAddedRemovedSetAndNotified(t *testing.T) {
|
||||
services = []api.Service{serviceUpdate2.Services[0]}
|
||||
handler.ValidateServices(t, services)
|
||||
|
||||
serviceUpdate4 := CreateServiceUpdate(SET, api.Service{ObjectMeta: api.ObjectMeta{Name: "foobar"}, Port: 99})
|
||||
serviceUpdate4 := CreateServiceUpdate(SET, api.Service{ObjectMeta: api.ObjectMeta{Name: "foobar"}, Spec: api.ServiceSpec{Port: 99}})
|
||||
handler.Wait(1)
|
||||
channel <- serviceUpdate4
|
||||
services = []api.Service{serviceUpdate4.Services[0]}
|
||||
@ -180,8 +180,8 @@ func TestNewMultipleSourcesServicesAddedAndNotified(t *testing.T) {
|
||||
}
|
||||
handler := NewServiceHandlerMock()
|
||||
config.RegisterHandler(handler)
|
||||
serviceUpdate1 := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}, Port: 10})
|
||||
serviceUpdate2 := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "bar"}, Port: 20})
|
||||
serviceUpdate1 := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{Port: 10}})
|
||||
serviceUpdate2 := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "bar"}, Spec: api.ServiceSpec{Port: 20}})
|
||||
handler.Wait(2)
|
||||
channelOne <- serviceUpdate1
|
||||
channelTwo <- serviceUpdate2
|
||||
@ -197,8 +197,8 @@ func TestNewMultipleSourcesServicesMultipleHandlersAddedAndNotified(t *testing.T
|
||||
handler2 := NewServiceHandlerMock()
|
||||
config.RegisterHandler(handler)
|
||||
config.RegisterHandler(handler2)
|
||||
serviceUpdate1 := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}, Port: 10})
|
||||
serviceUpdate2 := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "bar"}, Port: 20})
|
||||
serviceUpdate1 := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{Port: 10}})
|
||||
serviceUpdate2 := CreateServiceUpdate(ADD, api.Service{ObjectMeta: api.ObjectMeta{Name: "bar"}, Spec: api.ServiceSpec{Port: 20}})
|
||||
handler.Wait(2)
|
||||
handler2.Wait(2)
|
||||
channelOne <- serviceUpdate1
|
||||
|
@ -148,7 +148,7 @@ func (s ConfigSourceEtcd) decodeServices(node *etcd.Node, retServices []api.Serv
|
||||
glog.Errorf("Couldn't get endpoints for %s %s : %v skipping", svc.Namespace, svc.Name, err)
|
||||
endpoints = api.Endpoints{}
|
||||
} else {
|
||||
glog.V(3).Infof("Got service: %s %s on localport %d mapping to: %s", svc.Namespace, svc.Name, svc.Port, endpoints)
|
||||
glog.V(3).Infof("Got service: %s %s on localport %d mapping to: %s", svc.Namespace, svc.Name, svc.Spec.Port, endpoints)
|
||||
}
|
||||
retEndpoints = append(retEndpoints, endpoints)
|
||||
}
|
||||
|
@ -435,12 +435,12 @@ func (proxier *Proxier) OnUpdate(services []api.Service) {
|
||||
for _, service := range services {
|
||||
activeServices.Insert(service.Name)
|
||||
info, exists := proxier.getServiceInfo(service.Name)
|
||||
serviceIP := net.ParseIP(service.PortalIP)
|
||||
serviceIP := net.ParseIP(service.Spec.PortalIP)
|
||||
// TODO: check health of the socket? What if ProxyLoop exited?
|
||||
if exists && info.isActive() && info.portalPort == service.Port && info.portalIP.Equal(serviceIP) {
|
||||
if exists && info.isActive() && info.portalPort == service.Spec.Port && info.portalIP.Equal(serviceIP) {
|
||||
continue
|
||||
}
|
||||
if exists && (info.portalPort != service.Port || !info.portalIP.Equal(serviceIP)) {
|
||||
if exists && (info.portalPort != service.Spec.Port || !info.portalIP.Equal(serviceIP)) {
|
||||
glog.V(4).Infof("Something changed for service %q: stopping it", service.Name)
|
||||
err := proxier.closePortal(service.Name, info)
|
||||
if err != nil {
|
||||
@ -451,14 +451,14 @@ func (proxier *Proxier) OnUpdate(services []api.Service) {
|
||||
glog.Errorf("Failed to stop service %q: %s", service.Name, err)
|
||||
}
|
||||
}
|
||||
glog.V(1).Infof("Adding new service %q at %s:%d/%s (local :%d)", service.Name, serviceIP, service.Port, service.Protocol, service.ProxyPort)
|
||||
info, err := proxier.addServiceOnPort(service.Name, service.Protocol, service.ProxyPort, udpIdleTimeout)
|
||||
glog.V(1).Infof("Adding new service %q at %s:%d/%s (local :%d)", service.Name, serviceIP, service.Spec.Port, service.Spec.Protocol, service.Spec.ProxyPort)
|
||||
info, err := proxier.addServiceOnPort(service.Name, service.Spec.Protocol, service.Spec.ProxyPort, udpIdleTimeout)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to start proxy for %q: %+v", service.Name, err)
|
||||
continue
|
||||
}
|
||||
info.portalIP = serviceIP
|
||||
info.portalPort = service.Port
|
||||
info.portalPort = service.Spec.Port
|
||||
err = proxier.openPortal(service.Name, info)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to open portal for %q: %s", service.Name, err)
|
||||
|
@ -340,7 +340,7 @@ func TestTCPProxyUpdateDeleteUpdate(t *testing.T) {
|
||||
t.Fatalf(err.Error())
|
||||
}
|
||||
p.OnUpdate([]api.Service{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "echo"}, Port: svcInfo.proxyPort, ProxyPort: svcInfo.proxyPort, Protocol: "TCP"},
|
||||
{ObjectMeta: api.ObjectMeta{Name: "echo"}, Spec: api.ServiceSpec{Port: svcInfo.proxyPort, Protocol: "TCP", ProxyPort: svcInfo.proxyPort}, Status: api.ServiceStatus{}},
|
||||
})
|
||||
testEchoTCP(t, "127.0.0.1", svcInfo.proxyPort)
|
||||
}
|
||||
@ -371,7 +371,7 @@ func TestUDPProxyUpdateDeleteUpdate(t *testing.T) {
|
||||
t.Fatalf(err.Error())
|
||||
}
|
||||
p.OnUpdate([]api.Service{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "echo"}, Port: svcInfo.proxyPort, ProxyPort: svcInfo.proxyPort, Protocol: "UDP"},
|
||||
{ObjectMeta: api.ObjectMeta{Name: "echo"}, Spec: api.ServiceSpec{Port: svcInfo.proxyPort, Protocol: "UDP", ProxyPort: svcInfo.proxyPort}, Status: api.ServiceStatus{}},
|
||||
})
|
||||
testEchoUDP(t, "127.0.0.1", svcInfo.proxyPort)
|
||||
}
|
||||
@ -406,7 +406,7 @@ func TestTCPProxyUpdatePort(t *testing.T) {
|
||||
t.Errorf("expected difference, got %d %d", newPort, svcInfo.proxyPort)
|
||||
}
|
||||
p.OnUpdate([]api.Service{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "echo"}, Port: newPort, ProxyPort: newPort, Protocol: "TCP"},
|
||||
{ObjectMeta: api.ObjectMeta{Name: "echo"}, Spec: api.ServiceSpec{Port: newPort, Protocol: "TCP", ProxyPort: newPort}, Status: api.ServiceStatus{}},
|
||||
})
|
||||
if err := waitForClosedPortTCP(p, svcInfo.proxyPort); err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
@ -451,7 +451,7 @@ func TestUDPProxyUpdatePort(t *testing.T) {
|
||||
t.Errorf("expected difference, got %d %d", newPort, svcInfo.proxyPort)
|
||||
}
|
||||
p.OnUpdate([]api.Service{
|
||||
{ObjectMeta: api.ObjectMeta{Name: "echo"}, Port: newPort, ProxyPort: newPort, Protocol: "UDP"},
|
||||
{ObjectMeta: api.ObjectMeta{Name: "echo"}, Spec: api.ServiceSpec{Port: newPort, Protocol: "UDP", ProxyPort: newPort}, Status: api.ServiceStatus{}},
|
||||
})
|
||||
if err := waitForClosedPortUDP(p, svcInfo.proxyPort); err != nil {
|
||||
t.Fatalf(err.Error())
|
||||
|
@ -1144,27 +1144,28 @@ func TestEtcdUpdateService(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
fakeClient := tools.NewFakeEtcdClient(t)
|
||||
fakeClient.TestIndex = true
|
||||
key, _ := makeServiceKey(ctx, "foo")
|
||||
resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
|
||||
key, _ := makeServiceKey(ctx, "uniquefoo")
|
||||
resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Name: "uniquefoo"}}), 0)
|
||||
registry := NewTestEtcdRegistry(fakeClient)
|
||||
testService := api.Service{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Name: "uniquefoo",
|
||||
ResourceVersion: strconv.FormatUint(resp.Node.ModifiedIndex, 10),
|
||||
Labels: map[string]string{
|
||||
"baz": "bar",
|
||||
},
|
||||
},
|
||||
Selector: map[string]string{
|
||||
"baz": "bar",
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{
|
||||
"baz": "bar",
|
||||
},
|
||||
},
|
||||
}
|
||||
err := registry.UpdateService(ctx, &testService)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
svc, err := registry.GetService(ctx, "foo")
|
||||
svc, err := registry.GetService(ctx, "uniquefoo")
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -62,12 +62,14 @@ func TestMakeBoundPodServices(t *testing.T) {
|
||||
Items: []api.Service{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "test"},
|
||||
Port: 8080,
|
||||
ContainerPort: util.IntOrString{
|
||||
Kind: util.IntstrInt,
|
||||
IntVal: 900,
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8080,
|
||||
ContainerPort: util.IntOrString{
|
||||
Kind: util.IntstrInt,
|
||||
IntVal: 900,
|
||||
},
|
||||
PortalIP: "1.2.3.4",
|
||||
},
|
||||
PortalIP: "1.2.3.4",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -138,12 +140,14 @@ func TestMakeBoundPodServicesExistingEnvVar(t *testing.T) {
|
||||
Items: []api.Service{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "test"},
|
||||
Port: 8080,
|
||||
ContainerPort: util.IntOrString{
|
||||
Kind: util.IntstrInt,
|
||||
IntVal: 900,
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8080,
|
||||
ContainerPort: util.IntOrString{
|
||||
Kind: util.IntstrInt,
|
||||
IntVal: 900,
|
||||
},
|
||||
PortalIP: "1.2.3.4",
|
||||
},
|
||||
PortalIP: "1.2.3.4",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -71,18 +71,19 @@ func reloadIPsFromStorage(ipa *ipAllocator, registry Registry) {
|
||||
}
|
||||
for i := range services.Items {
|
||||
service := &services.Items[i]
|
||||
if service.PortalIP == "" {
|
||||
if service.Spec.PortalIP == "" {
|
||||
glog.Warningf("service %q has no PortalIP", service.Name)
|
||||
continue
|
||||
}
|
||||
if err := ipa.Allocate(net.ParseIP(service.PortalIP)); err != nil {
|
||||
if err := ipa.Allocate(net.ParseIP(service.Spec.PortalIP)); err != nil {
|
||||
// This is really bad.
|
||||
glog.Errorf("service %q PortalIP %s could not be allocated: %s", service.Name, service.PortalIP, err)
|
||||
glog.Errorf("service %q PortalIP %s could not be allocated: %s", service.Name, service.Spec.PortalIP, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) {
|
||||
|
||||
service := obj.(*api.Service)
|
||||
if !api.ValidNamespace(ctx, &service.ObjectMeta) {
|
||||
return nil, errors.NewConflict("service", service.Namespace, fmt.Errorf("Service.Namespace does not match the provided context"))
|
||||
@ -93,18 +94,18 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
|
||||
|
||||
service.CreationTimestamp = util.Now()
|
||||
|
||||
if service.PortalIP == "" {
|
||||
if service.Spec.PortalIP == "" {
|
||||
// Allocate next available.
|
||||
if ip, err := rs.portalMgr.AllocateNext(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
service.PortalIP = ip.String()
|
||||
service.Spec.PortalIP = ip.String()
|
||||
}
|
||||
} else {
|
||||
// Try to respect the requested IP.
|
||||
if err := rs.portalMgr.Allocate(net.ParseIP(service.PortalIP)); err != nil {
|
||||
if err := rs.portalMgr.Allocate(net.ParseIP(service.Spec.PortalIP)); err != nil {
|
||||
// TODO: Differentiate "IP already allocated" from real errors.
|
||||
el := errors.ValidationErrorList{errors.NewFieldInvalid("portalIP", service.PortalIP)}
|
||||
el := errors.ValidationErrorList{errors.NewFieldInvalid("spec.portalIP", service.Spec.PortalIP)}
|
||||
return nil, errors.NewInvalid("service", service.Name, el)
|
||||
}
|
||||
}
|
||||
@ -112,8 +113,8 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
|
||||
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||
// TODO: Consider moving this to a rectification loop, so that we make/remove external load balancers
|
||||
// correctly no matter what http operations happen.
|
||||
service.ProxyPort = 0
|
||||
if service.CreateExternalLoadBalancer {
|
||||
service.Spec.ProxyPort = 0
|
||||
if service.Spec.CreateExternalLoadBalancer {
|
||||
if rs.cloud == nil {
|
||||
return nil, fmt.Errorf("requested an external service, but no cloud provider supplied.")
|
||||
}
|
||||
@ -133,13 +134,13 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = balancer.CreateTCPLoadBalancer(service.Name, zone.Region, service.Port, hostsFromMinionList(hosts))
|
||||
err = balancer.CreateTCPLoadBalancer(service.Name, zone.Region, service.Spec.Port, hostsFromMinionList(hosts))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// External load-balancers require a known port for the service proxy.
|
||||
// TODO: If we end up brokering HostPorts between Pods and Services, this can be any port.
|
||||
service.ProxyPort = service.Port
|
||||
service.Spec.ProxyPort = service.Spec.Port
|
||||
}
|
||||
err := rs.registry.CreateService(ctx, service)
|
||||
if err != nil {
|
||||
@ -162,7 +163,7 @@ func (rs *REST) Delete(ctx api.Context, id string) (<-chan apiserver.RESTResult,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rs.portalMgr.Release(net.ParseIP(service.PortalIP))
|
||||
rs.portalMgr.Release(net.ParseIP(service.Spec.PortalIP))
|
||||
return apiserver.MakeAsync(func() (runtime.Object, error) {
|
||||
rs.deleteExternalLoadBalancer(service)
|
||||
return &api.Status{Status: api.StatusSuccess}, rs.registry.DeleteService(ctx, id)
|
||||
@ -214,10 +215,10 @@ func GetServiceEnvironmentVariables(ctx api.Context, registry Registry, machine
|
||||
for _, service := range services.Items {
|
||||
// Host
|
||||
name := makeEnvVariableName(service.Name) + "_SERVICE_HOST"
|
||||
result = append(result, api.EnvVar{Name: name, Value: service.PortalIP})
|
||||
result = append(result, api.EnvVar{Name: name, Value: service.Spec.PortalIP})
|
||||
// Port
|
||||
name = makeEnvVariableName(service.Name) + "_SERVICE_PORT"
|
||||
result = append(result, api.EnvVar{Name: name, Value: strconv.Itoa(service.Port)})
|
||||
result = append(result, api.EnvVar{Name: name, Value: strconv.Itoa(service.Spec.Port)})
|
||||
// Docker-compatible vars.
|
||||
result = append(result, makeLinkVariables(service)...)
|
||||
}
|
||||
@ -237,13 +238,13 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if service.PortalIP != cur.PortalIP {
|
||||
if service.Spec.PortalIP != cur.Spec.PortalIP {
|
||||
// TODO: Would be nice to pass "field is immutable" to users.
|
||||
el := errors.ValidationErrorList{errors.NewFieldInvalid("portalIP", service.PortalIP)}
|
||||
el := errors.ValidationErrorList{errors.NewFieldInvalid("spec.portalIP", service.Spec.PortalIP)}
|
||||
return nil, errors.NewInvalid("service", service.Name, el)
|
||||
}
|
||||
// Copy over non-user fields.
|
||||
service.ProxyPort = cur.ProxyPort
|
||||
service.Spec.ProxyPort = cur.Spec.ProxyPort
|
||||
// TODO: check to see if external load balancer status changed
|
||||
err = rs.registry.UpdateService(ctx, service)
|
||||
if err != nil {
|
||||
@ -268,7 +269,7 @@ func (rs *REST) ResourceLocation(ctx api.Context, id string) (string, error) {
|
||||
}
|
||||
|
||||
func (rs *REST) deleteExternalLoadBalancer(service *api.Service) error {
|
||||
if !service.CreateExternalLoadBalancer || rs.cloud == nil {
|
||||
if !service.Spec.CreateExternalLoadBalancer || rs.cloud == nil {
|
||||
return nil
|
||||
}
|
||||
zones, ok := rs.cloud.Zones()
|
||||
@ -300,18 +301,18 @@ func makeEnvVariableName(str string) string {
|
||||
func makeLinkVariables(service api.Service) []api.EnvVar {
|
||||
prefix := makeEnvVariableName(service.Name)
|
||||
protocol := string(api.ProtocolTCP)
|
||||
if service.Protocol != "" {
|
||||
protocol = string(service.Protocol)
|
||||
if service.Spec.Protocol != "" {
|
||||
protocol = string(service.Spec.Protocol)
|
||||
}
|
||||
portPrefix := fmt.Sprintf("%s_PORT_%d_%s", prefix, service.Port, strings.ToUpper(protocol))
|
||||
portPrefix := fmt.Sprintf("%s_PORT_%d_%s", prefix, service.Spec.Port, strings.ToUpper(protocol))
|
||||
return []api.EnvVar{
|
||||
{
|
||||
Name: prefix + "_PORT",
|
||||
Value: fmt.Sprintf("%s://%s:%d", strings.ToLower(protocol), service.PortalIP, service.Port),
|
||||
Value: fmt.Sprintf("%s://%s:%d", strings.ToLower(protocol), service.Spec.PortalIP, service.Spec.Port),
|
||||
},
|
||||
{
|
||||
Name: portPrefix,
|
||||
Value: fmt.Sprintf("%s://%s:%d", strings.ToLower(protocol), service.PortalIP, service.Port),
|
||||
Value: fmt.Sprintf("%s://%s:%d", strings.ToLower(protocol), service.Spec.PortalIP, service.Spec.Port),
|
||||
},
|
||||
{
|
||||
Name: portPrefix + "_PROTO",
|
||||
@ -319,11 +320,11 @@ func makeLinkVariables(service api.Service) []api.EnvVar {
|
||||
},
|
||||
{
|
||||
Name: portPrefix + "_PORT",
|
||||
Value: strconv.Itoa(service.Port),
|
||||
Value: strconv.Itoa(service.Spec.Port),
|
||||
},
|
||||
{
|
||||
Name: portPrefix + "_ADDR",
|
||||
Value: service.PortalIP,
|
||||
Value: service.Spec.PortalIP,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -45,9 +45,11 @@ func TestServiceRegistryCreate(t *testing.T) {
|
||||
machines := []string{"foo", "bar", "baz"}
|
||||
storage := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
svc := &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 6502,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
},
|
||||
}
|
||||
ctx := api.NewDefaultContext()
|
||||
c, _ := storage.Create(ctx, svc)
|
||||
@ -59,11 +61,11 @@ func TestServiceRegistryCreate(t *testing.T) {
|
||||
if created_service.CreationTimestamp.IsZero() {
|
||||
t.Errorf("Expected timestamp to be set, got: %v", created_service.CreationTimestamp)
|
||||
}
|
||||
if created_service.PortalIP != "1.2.3.1" {
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service.PortalIP)
|
||||
if created_service.Spec.PortalIP != "1.2.3.1" {
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service.Spec.PortalIP)
|
||||
}
|
||||
if created_service.ProxyPort != 0 {
|
||||
t.Errorf("Unexpected ProxyPort: %d", created_service.ProxyPort)
|
||||
if created_service.Spec.ProxyPort != 0 {
|
||||
t.Errorf("Unexpected ProxyPort: %d", created_service.Spec.ProxyPort)
|
||||
}
|
||||
if len(fakeCloud.Calls) != 0 {
|
||||
t.Errorf("Unexpected call(s): %#v", fakeCloud.Calls)
|
||||
@ -82,13 +84,17 @@ func TestServiceStorageValidatesCreate(t *testing.T) {
|
||||
storage := NewREST(registry, nil, nil, makeIPNet(t))
|
||||
failureCases := map[string]api.Service{
|
||||
"empty ID": {
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: ""},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 6502,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
},
|
||||
},
|
||||
"empty selector": {
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
},
|
||||
},
|
||||
}
|
||||
ctx := api.NewDefaultContext()
|
||||
@ -108,15 +114,19 @@ func TestServiceRegistryUpdate(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
registry := registrytest.NewServiceRegistry()
|
||||
registry.CreateService(ctx, &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz1"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 6502,
|
||||
Selector: map[string]string{"bar": "baz1"},
|
||||
},
|
||||
})
|
||||
storage := NewREST(registry, nil, nil, makeIPNet(t))
|
||||
c, err := storage.Update(ctx, &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz2"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 6502,
|
||||
Selector: map[string]string{"bar": "baz2"},
|
||||
},
|
||||
})
|
||||
if c == nil {
|
||||
t.Errorf("Expected non-nil channel")
|
||||
@ -138,21 +148,27 @@ func TestServiceStorageValidatesUpdate(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
registry := registrytest.NewServiceRegistry()
|
||||
registry.CreateService(ctx, &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 6502,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
},
|
||||
})
|
||||
storage := NewREST(registry, nil, nil, makeIPNet(t))
|
||||
failureCases := map[string]api.Service{
|
||||
"empty ID": {
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: ""},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 6502,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
},
|
||||
},
|
||||
"empty selector": {
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 6502,
|
||||
Selector: map[string]string{},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, failureCase := range failureCases {
|
||||
@ -173,10 +189,12 @@ func TestServiceRegistryExternalService(t *testing.T) {
|
||||
machines := []string{"foo", "bar", "baz"}
|
||||
storage := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
svc := &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
CreateExternalLoadBalancer: true,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 6502,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
CreateExternalLoadBalancer: true,
|
||||
},
|
||||
}
|
||||
c, _ := storage.Create(ctx, svc)
|
||||
<-c
|
||||
@ -200,10 +218,12 @@ func TestServiceRegistryExternalServiceError(t *testing.T) {
|
||||
machines := []string{"foo", "bar", "baz"}
|
||||
storage := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
svc := &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
CreateExternalLoadBalancer: true,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 6502,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
CreateExternalLoadBalancer: true,
|
||||
},
|
||||
}
|
||||
ctx := api.NewDefaultContext()
|
||||
c, _ := storage.Create(ctx, svc)
|
||||
@ -224,7 +244,9 @@ func TestServiceRegistryDelete(t *testing.T) {
|
||||
storage := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
svc := &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
},
|
||||
}
|
||||
registry.CreateService(ctx, svc)
|
||||
c, _ := storage.Delete(ctx, svc.Name)
|
||||
@ -244,9 +266,11 @@ func TestServiceRegistryDeleteExternal(t *testing.T) {
|
||||
machines := []string{"foo", "bar", "baz"}
|
||||
storage := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
svc := &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
CreateExternalLoadBalancer: true,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
CreateExternalLoadBalancer: true,
|
||||
},
|
||||
}
|
||||
registry.CreateService(ctx, svc)
|
||||
c, _ := storage.Delete(ctx, svc.Name)
|
||||
@ -266,24 +290,30 @@ func TestServiceRegistryMakeLinkVariables(t *testing.T) {
|
||||
Items: []api.Service{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo-bar"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Port: 8080,
|
||||
Protocol: "TCP",
|
||||
PortalIP: "1.2.3.4",
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8080,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Protocol: "TCP",
|
||||
PortalIP: "1.2.3.4",
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc-123"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Port: 8081,
|
||||
Protocol: "UDP",
|
||||
PortalIP: "5.6.7.8",
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8081,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Protocol: "UDP",
|
||||
PortalIP: "5.6.7.8",
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "q-u-u-x"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Port: 8082,
|
||||
Protocol: "",
|
||||
PortalIP: "9.8.7.6",
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8082,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Protocol: "TCP",
|
||||
PortalIP: "9.8.7.6",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -334,7 +364,9 @@ func TestServiceRegistryGet(t *testing.T) {
|
||||
storage := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
registry.CreateService(ctx, &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
},
|
||||
})
|
||||
storage.Get(ctx, "foo")
|
||||
if len(fakeCloud.Calls) != 0 {
|
||||
@ -354,7 +386,9 @@ func TestServiceRegistryResourceLocation(t *testing.T) {
|
||||
storage := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
registry.CreateService(ctx, &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
},
|
||||
})
|
||||
redirector := apiserver.Redirector(storage)
|
||||
location, err := redirector.ResourceLocation(ctx, "foo")
|
||||
@ -383,11 +417,15 @@ func TestServiceRegistryList(t *testing.T) {
|
||||
storage := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
registry.CreateService(ctx, &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
},
|
||||
})
|
||||
registry.CreateService(ctx, &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo2"},
|
||||
Selector: map[string]string{"bar2": "baz2"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar2": "baz2"},
|
||||
},
|
||||
})
|
||||
registry.List.ResourceVersion = "1"
|
||||
s, _ := storage.List(ctx, labels.Everything(), labels.Everything())
|
||||
@ -416,9 +454,11 @@ func TestServiceRegistryIPAllocation(t *testing.T) {
|
||||
rest := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
|
||||
svc1 := &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Port: 6502,
|
||||
},
|
||||
}
|
||||
ctx := api.NewDefaultContext()
|
||||
c1, _ := rest.Create(ctx, svc1)
|
||||
@ -427,15 +467,16 @@ func TestServiceRegistryIPAllocation(t *testing.T) {
|
||||
if created_service_1.Name != "foo" {
|
||||
t.Errorf("Expected foo, but got %v", created_service_1.Name)
|
||||
}
|
||||
if created_service_1.PortalIP != "1.2.3.1" {
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service_1.PortalIP)
|
||||
if created_service_1.Spec.PortalIP != "1.2.3.1" {
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service_1.Spec.PortalIP)
|
||||
}
|
||||
|
||||
svc2 := &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
}
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Port: 6502,
|
||||
}}
|
||||
ctx = api.NewDefaultContext()
|
||||
c2, _ := rest.Create(ctx, svc2)
|
||||
created_svc2 := <-c2
|
||||
@ -443,22 +484,24 @@ func TestServiceRegistryIPAllocation(t *testing.T) {
|
||||
if created_service_2.Name != "bar" {
|
||||
t.Errorf("Expected bar, but got %v", created_service_2.Name)
|
||||
}
|
||||
if created_service_2.PortalIP != "1.2.3.2" { // new IP
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service_2.PortalIP)
|
||||
if created_service_2.Spec.PortalIP != "1.2.3.2" { // new IP
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service_2.Spec.PortalIP)
|
||||
}
|
||||
|
||||
svc3 := &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "quux"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
PortalIP: "1.2.3.93",
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
PortalIP: "1.2.3.93",
|
||||
Port: 6502,
|
||||
},
|
||||
}
|
||||
ctx = api.NewDefaultContext()
|
||||
c3, _ := rest.Create(ctx, svc3)
|
||||
created_svc3 := <-c3
|
||||
created_service_3 := created_svc3.Object.(*api.Service)
|
||||
if created_service_3.PortalIP != "1.2.3.93" { // specific IP
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service_3.PortalIP)
|
||||
if created_service_3.Spec.PortalIP != "1.2.3.93" { // specific IP
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service_3.Spec.PortalIP)
|
||||
}
|
||||
}
|
||||
|
||||
@ -469,9 +512,11 @@ func TestServiceRegistryIPReallocation(t *testing.T) {
|
||||
rest := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
|
||||
svc1 := &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Port: 6502,
|
||||
},
|
||||
}
|
||||
ctx := api.NewDefaultContext()
|
||||
c1, _ := rest.Create(ctx, svc1)
|
||||
@ -480,17 +525,19 @@ func TestServiceRegistryIPReallocation(t *testing.T) {
|
||||
if created_service_1.Name != "foo" {
|
||||
t.Errorf("Expected foo, but got %v", created_service_1.Name)
|
||||
}
|
||||
if created_service_1.PortalIP != "1.2.3.1" {
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service_1.PortalIP)
|
||||
if created_service_1.Spec.PortalIP != "1.2.3.1" {
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service_1.Spec.PortalIP)
|
||||
}
|
||||
|
||||
c, _ := rest.Delete(ctx, created_service_1.Name)
|
||||
<-c
|
||||
|
||||
svc2 := &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Port: 6502,
|
||||
},
|
||||
}
|
||||
ctx = api.NewDefaultContext()
|
||||
c2, _ := rest.Create(ctx, svc2)
|
||||
@ -499,8 +546,8 @@ func TestServiceRegistryIPReallocation(t *testing.T) {
|
||||
if created_service_2.Name != "bar" {
|
||||
t.Errorf("Expected bar, but got %v", created_service_2.Name)
|
||||
}
|
||||
if created_service_2.PortalIP != "1.2.3.1" { // same IP as before
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service_2.PortalIP)
|
||||
if created_service_2.Spec.PortalIP != "1.2.3.1" { // same IP as before
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service_2.Spec.PortalIP)
|
||||
}
|
||||
}
|
||||
|
||||
@ -511,42 +558,44 @@ func TestServiceRegistryIPUpdate(t *testing.T) {
|
||||
rest := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
|
||||
svc := &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Port: 6502,
|
||||
},
|
||||
}
|
||||
ctx := api.NewDefaultContext()
|
||||
c, _ := rest.Create(ctx, svc)
|
||||
created_svc := <-c
|
||||
created_service := created_svc.Object.(*api.Service)
|
||||
if created_service.Port != 6502 {
|
||||
t.Errorf("Expected port 6502, but got %v", created_service.Port)
|
||||
if created_service.Spec.Port != 6502 {
|
||||
t.Errorf("Expected port 6502, but got %v", created_service.Spec.Port)
|
||||
}
|
||||
if created_service.PortalIP != "1.2.3.1" {
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service.PortalIP)
|
||||
if created_service.Spec.PortalIP != "1.2.3.1" {
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service.Spec.PortalIP)
|
||||
}
|
||||
if created_service.ProxyPort != 0 {
|
||||
t.Errorf("Unexpected ProxyPort: %d", created_service.ProxyPort)
|
||||
if created_service.Spec.ProxyPort != 0 {
|
||||
t.Errorf("Unexpected ProxyPort: %d", created_service.Spec.ProxyPort)
|
||||
}
|
||||
|
||||
update := new(api.Service)
|
||||
*update = *created_service
|
||||
update.Port = 6503
|
||||
update.ProxyPort = 309 // should be ignored
|
||||
update.Spec.Port = 6503
|
||||
update.Spec.ProxyPort = 309 // should be ignored
|
||||
|
||||
c, _ = rest.Update(ctx, update)
|
||||
updated_svc := <-c
|
||||
updated_service := updated_svc.Object.(*api.Service)
|
||||
if updated_service.Port != 6503 {
|
||||
t.Errorf("Expected port 6503, but got %v", updated_service.Port)
|
||||
if updated_service.Spec.Port != 6503 {
|
||||
t.Errorf("Expected port 6503, but got %v", updated_service.Spec.Port)
|
||||
}
|
||||
if updated_service.ProxyPort != 0 { // unchanged, despite trying
|
||||
t.Errorf("Unexpected ProxyPort: %d", updated_service.ProxyPort)
|
||||
if updated_service.Spec.ProxyPort != 0 { // unchanged, despite trying
|
||||
t.Errorf("Unexpected ProxyPort: %d", updated_service.Spec.ProxyPort)
|
||||
}
|
||||
|
||||
*update = *created_service
|
||||
update.Port = 6503
|
||||
update.PortalIP = "1.2.3.76" // error
|
||||
update.Spec.Port = 6503
|
||||
update.Spec.PortalIP = "1.2.3.76" // error
|
||||
|
||||
c, _ = rest.Update(ctx, update)
|
||||
result := <-c
|
||||
@ -563,23 +612,25 @@ func TestServiceRegistryIPExternalLoadBalancer(t *testing.T) {
|
||||
rest := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
|
||||
svc := &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
CreateExternalLoadBalancer: true,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Port: 6502,
|
||||
CreateExternalLoadBalancer: true,
|
||||
},
|
||||
}
|
||||
ctx := api.NewDefaultContext()
|
||||
c, _ := rest.Create(ctx, svc)
|
||||
created_svc := <-c
|
||||
created_service := created_svc.Object.(*api.Service)
|
||||
if created_service.Port != 6502 {
|
||||
t.Errorf("Expected port 6502, but got %v", created_service.Port)
|
||||
if created_service.Spec.Port != 6502 {
|
||||
t.Errorf("Expected port 6502, but got %v", created_service.Spec.Port)
|
||||
}
|
||||
if created_service.PortalIP != "1.2.3.1" {
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service.PortalIP)
|
||||
if created_service.Spec.PortalIP != "1.2.3.1" {
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service.Spec.PortalIP)
|
||||
}
|
||||
if created_service.ProxyPort != 6502 {
|
||||
t.Errorf("Unexpected ProxyPort: %d", created_service.ProxyPort)
|
||||
if created_service.Spec.ProxyPort != 6502 {
|
||||
t.Errorf("Unexpected ProxyPort: %d", created_service.Spec.ProxyPort)
|
||||
}
|
||||
}
|
||||
|
||||
@ -590,17 +641,21 @@ func TestServiceRegistryIPReloadFromStorage(t *testing.T) {
|
||||
rest1 := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
|
||||
svc := &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Port: 6502,
|
||||
},
|
||||
}
|
||||
ctx := api.NewDefaultContext()
|
||||
c, _ := rest1.Create(ctx, svc)
|
||||
<-c
|
||||
svc = &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Port: 6502,
|
||||
},
|
||||
}
|
||||
c, _ = rest1.Create(ctx, svc)
|
||||
<-c
|
||||
@ -609,15 +664,17 @@ func TestServiceRegistryIPReloadFromStorage(t *testing.T) {
|
||||
rest2 := NewREST(registry, fakeCloud, registrytest.NewMinionRegistry(machines, api.NodeResources{}), makeIPNet(t))
|
||||
|
||||
svc = &api.Service{
|
||||
Port: 6502,
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Port: 6502,
|
||||
},
|
||||
}
|
||||
c, _ = rest2.Create(ctx, svc)
|
||||
created_svc := <-c
|
||||
created_service := created_svc.Object.(*api.Service)
|
||||
if created_service.PortalIP != "1.2.3.3" {
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service.PortalIP)
|
||||
if created_service.Spec.PortalIP != "1.2.3.3" {
|
||||
t.Errorf("Unexpected PortalIP: %s", created_service.Spec.PortalIP)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ func (e *EndpointController) SyncServiceEndpoints() error {
|
||||
continue
|
||||
}
|
||||
glog.Infof("About to update endpoints for service %v", service.Name)
|
||||
pods, err := e.client.Pods(service.Namespace).List(labels.Set(service.Selector).AsSelector())
|
||||
pods, err := e.client.Pods(service.Namespace).List(labels.Set(service.Spec.Selector).AsSelector())
|
||||
if err != nil {
|
||||
glog.Errorf("Error syncing service: %#v, skipping.", service)
|
||||
resultErr = err
|
||||
@ -65,7 +65,7 @@ func (e *EndpointController) SyncServiceEndpoints() error {
|
||||
}
|
||||
endpoints := []string{}
|
||||
for _, pod := range pods.Items {
|
||||
port, err := findPort(&pod.DesiredState.Manifest, service.ContainerPort)
|
||||
port, err := findPort(&pod.DesiredState.Manifest, service.Spec.ContainerPort)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to find port for service: %v, %v", service, err)
|
||||
continue
|
||||
|
@ -182,8 +182,10 @@ func TestSyncEndpointsItemsPreexisting(t *testing.T) {
|
||||
Items: []api.Service{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -219,8 +221,10 @@ func TestSyncEndpointsItemsPreexistingIdentical(t *testing.T) {
|
||||
Items: []api.Service{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -248,8 +252,10 @@ func TestSyncEndpointsItems(t *testing.T) {
|
||||
Items: []api.Service{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -277,8 +283,10 @@ func TestSyncEndpointsPodError(t *testing.T) {
|
||||
serviceList := api.ServiceList{
|
||||
Items: []api.Service{
|
||||
{
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user