func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { ctx := api.NewDefaultContext() storage, _ := NewTestREST(t, nil) // Create external load balancer. svc1 := &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeLoadBalancer, Ports: []api.ServicePort{{ Name: "p", Port: 6502, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(6502), }, { Name: "q", Port: 8086, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(8086), }}, }, } if _, err := storage.Create(ctx, svc1); err != nil { t.Fatalf("Unexpected error: %v", err) } // Modify ports svc2 := deepCloneService(svc1) svc2.Spec.Ports[1].Port = 8088 if _, _, err := storage.Update(ctx, svc2); err != nil { t.Fatalf("Unexpected error: %v", err) } }
// RunControllerManager starts a controller func RunControllerManager(machineList []string, cl *client.Client, nodeMilliCPU, nodeMemory int64) { if int64(int(nodeMilliCPU)) != nodeMilliCPU { glog.Warningf("node_milli_cpu is too big for platform. Clamping: %d -> %d", nodeMilliCPU, math.MaxInt32) nodeMilliCPU = math.MaxInt32 } if int64(int(nodeMemory)) != nodeMemory { glog.Warningf("node_memory is too big for platform. Clamping: %d -> %d", nodeMemory, math.MaxInt32) nodeMemory = math.MaxInt32 } nodeResources := &api.NodeResources{ Capacity: api.ResourceList{ resources.CPU: util.NewIntOrStringFromInt(int(nodeMilliCPU)), resources.Memory: util.NewIntOrStringFromInt(int(nodeMemory)), }, } minionController := minionControllerPkg.NewMinionController(nil, "", machineList, nodeResources, cl) minionController.Run(10 * time.Second) endpoints := service.NewEndpointController(cl) go util.Forever(func() { endpoints.SyncServiceEndpoints() }, time.Second*10) controllerManager := controller.NewReplicationManager(cl) controllerManager.Run(10 * time.Second) }
func TestCreateMinion(t *testing.T) { requestMinion := &api.Minion{ ObjectMeta: api.ObjectMeta{ Name: "minion-1", }, Status: api.NodeStatus{ HostIP: "123.321.456.654", }, Spec: api.NodeSpec{ Capacity: api.ResourceList{ resources.CPU: util.NewIntOrStringFromInt(1000), resources.Memory: util.NewIntOrStringFromInt(1024 * 1024), }, }, } c := &testClient{ Request: testRequest{Method: "POST", Path: "/minions", Body: requestMinion}, Response: Response{ StatusCode: 200, Body: requestMinion, }, } receivedMinion, err := c.Setup().Minions().Create(requestMinion) c.Validate(t, receivedMinion, err) }
func TestSetDefaultServicePort(t *testing.T) { // Unchanged if set. in := ¤t.Service{Ports: []current.ServicePort{{Protocol: "UDP", Port: 9376, ContainerPort: util.NewIntOrStringFromInt(118)}}} out := roundTrip(t, runtime.Object(in)).(*current.Service) if out.Ports[0].Protocol != current.ProtocolUDP { t.Errorf("Expected protocol %s, got %s", current.ProtocolUDP, out.Ports[0].Protocol) } if out.Ports[0].ContainerPort != in.Ports[0].ContainerPort { t.Errorf("Expected port %d, got %d", in.Ports[0].ContainerPort, out.Ports[0].ContainerPort) } // Defaulted. in = ¤t.Service{Ports: []current.ServicePort{{Protocol: "", Port: 9376, ContainerPort: util.NewIntOrStringFromInt(0)}}} out = roundTrip(t, runtime.Object(in)).(*current.Service) if out.Ports[0].Protocol != current.ProtocolTCP { t.Errorf("Expected protocol %s, got %s", current.ProtocolTCP, out.Ports[0].Protocol) } if out.Ports[0].ContainerPort != util.NewIntOrStringFromInt(in.Ports[0].Port) { t.Errorf("Expected port %d, got %v", in.Ports[0].Port, out.Ports[0].ContainerPort) } // Defaulted. in = ¤t.Service{Ports: []current.ServicePort{{Protocol: "", Port: 9376, ContainerPort: util.NewIntOrStringFromString("")}}} out = roundTrip(t, runtime.Object(in)).(*current.Service) if out.Ports[0].Protocol != current.ProtocolTCP { t.Errorf("Expected protocol %s, got %s", current.ProtocolTCP, out.Ports[0].Protocol) } if out.Ports[0].ContainerPort != util.NewIntOrStringFromInt(in.Ports[0].Port) { t.Errorf("Expected port %d, got %v", in.Ports[0].Port, out.Ports[0].ContainerPort) } }
// Instances returns an implementation of Instances for OpenStack. func (os *OpenStack) Instances() (cloudprovider.Instances, bool) { servers, err := gophercloud.ServersApi(os.access, gophercloud.ApiCriteria{ Type: "compute", UrlChoice: gophercloud.PublicURL, Region: os.region, }) if err != nil { return nil, false } flavors, err := servers.ListFlavors() if err != nil { return nil, false } flavor_to_resource := make(map[string]*api.NodeResources, len(flavors)) for _, flavor := range flavors { rsrc := api.NodeResources{ Capacity: api.ResourceList{ "cpu": util.NewIntOrStringFromInt(flavor.VCpus), "memory": util.NewIntOrStringFromString(fmt.Sprintf("%dMiB", flavor.Ram)), "openstack.org/disk": util.NewIntOrStringFromString(fmt.Sprintf("%dGB", flavor.Disk)), "openstack.org/rxTxFactor": util.NewIntOrStringFromInt(int(flavor.RxTxFactor * 1000)), "openstack.org/swap": util.NewIntOrStringFromString(fmt.Sprintf("%dMiB", flavor.Swap)), }, } flavor_to_resource[flavor.Id] = &rsrc } return &Instances{servers, flavor_to_resource}, true }
func TestGetInteger(t *testing.T) { tests := []struct { res api.ResourceList name api.ResourceName expected int def int test string }{ { res: api.ResourceList{}, name: CPU, expected: 1, def: 1, test: "nothing present", }, { res: api.ResourceList{ CPU: util.NewIntOrStringFromInt(2), }, name: CPU, expected: 2, def: 1, test: "present", }, { res: api.ResourceList{ Memory: util.NewIntOrStringFromInt(2), }, name: CPU, expected: 1, def: 1, test: "not-present", }, { res: api.ResourceList{ CPU: util.NewIntOrStringFromString("2"), }, name: CPU, expected: 2, def: 1, test: "present-string", }, { res: api.ResourceList{ CPU: util.NewIntOrStringFromString("foo"), }, name: CPU, expected: 1, def: 1, test: "present-invalid", }, } for _, test := range tests { val := GetIntegerResource(test.res, test.name, test.def) if val != test.expected { t.Errorf("expected: %d found %d", test.expected, val) } } }
func makeResources(cpu float32, memory float32) *api.NodeResources { return &api.NodeResources{ Capacity: api.ResourceList{ resources.CPU: util.NewIntOrStringFromInt(int(cpu * 1000)), resources.Memory: util.NewIntOrStringFromInt(int(memory * 1024 * 1024 * 1024)), }, } }
func TestGetURLParts(t *testing.T) { testCases := []struct { probe *api.HTTPGetAction ok bool host string port int path string }{ {&api.HTTPGetAction{Host: "", Port: util.NewIntOrStringFromInt(-1), Path: ""}, false, "", -1, ""}, {&api.HTTPGetAction{Host: "", Port: util.NewIntOrStringFromString(""), Path: ""}, false, "", -1, ""}, {&api.HTTPGetAction{Host: "", Port: util.NewIntOrStringFromString("-1"), Path: ""}, false, "", -1, ""}, {&api.HTTPGetAction{Host: "", Port: util.NewIntOrStringFromString("not-found"), Path: ""}, false, "", -1, ""}, {&api.HTTPGetAction{Host: "", Port: util.NewIntOrStringFromString("found"), Path: ""}, true, "127.0.0.1", 93, ""}, {&api.HTTPGetAction{Host: "", Port: util.NewIntOrStringFromInt(76), Path: ""}, true, "127.0.0.1", 76, ""}, {&api.HTTPGetAction{Host: "", Port: util.NewIntOrStringFromString("118"), Path: ""}, true, "127.0.0.1", 118, ""}, {&api.HTTPGetAction{Host: "hostname", Port: util.NewIntOrStringFromInt(76), Path: "path"}, true, "hostname", 76, "path"}, } for _, test := range testCases { state := api.PodStatus{PodIP: "127.0.0.1"} container := api.Container{ Ports: []api.ContainerPort{{Name: "found", HostPort: 93}}, LivenessProbe: &api.Probe{ Handler: api.Handler{ HTTPGet: test.probe, }, }, } scheme := test.probe.Scheme if scheme == "" { scheme = api.URISchemeHTTP } host := test.probe.Host if host == "" { host = state.PodIP } port, err := extractPort(test.probe.Port, container) if test.ok && err != nil { t.Errorf("Unexpected error: %v", err) } path := test.probe.Path if !test.ok && err == nil { t.Errorf("Expected error for %+v, got %s%s:%d/%s", test, scheme, host, port, path) } if test.ok { if host != test.host || port != test.port || path != test.path { t.Errorf("Expected %s:%d/%s, got %s:%d/%s", test.host, test.port, test.path, host, port, path) } } } }
func makeMinion(node string, cpu, memory int) api.Minion { return api.Minion{ ObjectMeta: api.ObjectMeta{Name: node}, Spec: api.NodeSpec{ Capacity: api.ResourceList{ resources.CPU: util.NewIntOrStringFromInt(cpu), resources.Memory: util.NewIntOrStringFromInt(memory), }, }, } }
func TestServiceRegistryIPReallocation(t *testing.T) { rest, _ := NewTestREST(t, nil) svc1 := &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeClusterIP, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(6502), }}, }, } ctx := api.NewDefaultContext() created_svc1, _ := rest.Create(ctx, svc1) created_service_1 := created_svc1.(*api.Service) if created_service_1.Name != "foo" { t.Errorf("Expected foo, but got %v", created_service_1.Name) } if !makeIPNet(t).Contains(net.ParseIP(created_service_1.Spec.ClusterIP)) { t.Errorf("Unexpected ClusterIP: %s", created_service_1.Spec.ClusterIP) } _, err := rest.Delete(ctx, created_service_1.Name) if err != nil { t.Errorf("Unexpected error deleting service: %v", err) } svc2 := &api.Service{ ObjectMeta: api.ObjectMeta{Name: "bar"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeClusterIP, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(6502), }}, }, } ctx = api.NewDefaultContext() created_svc2, _ := rest.Create(ctx, svc2) created_service_2 := created_svc2.(*api.Service) if created_service_2.Name != "bar" { t.Errorf("Expected bar, but got %v", created_service_2.Name) } if !makeIPNet(t).Contains(net.ParseIP(created_service_2.Spec.ClusterIP)) { t.Errorf("Unexpected ClusterIP: %s", created_service_2.Spec.ClusterIP) } }
func getResourceRequirements(cpu, memory resource.Quantity) current.ResourceRequirements { res := current.ResourceRequirements{} res.Limits = current.ResourceList{} if cpu.Value() > 0 { res.Limits[current.ResourceCPU] = util.NewIntOrStringFromInt(int(cpu.Value())) } if memory.Value() > 0 { res.Limits[current.ResourceMemory] = util.NewIntOrStringFromInt(int(memory.Value())) } return res }
func TestServiceStorageValidatesUpdate(t *testing.T) { ctx := api.NewDefaultContext() storage, registry := NewTestREST(t, nil) registry.CreateService(ctx, &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, }}, }, }) failureCases := map[string]api.Service{ "empty ID": { ObjectMeta: api.ObjectMeta{Name: ""}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeClusterIP, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(6502), }}, }, }, "invalid selector": { ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{ Selector: map[string]string{"ThisSelectorFailsValidation": "ok"}, SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeClusterIP, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(6502), }}, }, }, } for _, failureCase := range failureCases { c, created, err := storage.Update(ctx, &failureCase) if c != nil || created { t.Errorf("Expected nil object or created false") } if !errors.IsInvalid(err) { t.Errorf("Expected to get an invalid resource error, got %v", err) } } }
func TestServiceRegistryUpdate(t *testing.T) { ctx := api.NewDefaultContext() storage, registry := NewTestREST(t, nil) svc, err := registry.CreateService(ctx, &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: api.NamespaceDefault}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz1"}, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(6502), }}, }, }) if err != nil { t.Fatalf("Expected no error: %v", err) } updated_svc, created, err := storage.Update(ctx, &api.Service{ ObjectMeta: api.ObjectMeta{ Name: "foo", ResourceVersion: svc.ResourceVersion}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz2"}, SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeClusterIP, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(6502), }}, }, }) if err != nil { t.Fatalf("Expected no error: %v", err) } if updated_svc == nil { t.Errorf("Expected non-nil object") } if created { t.Errorf("expected not created") } updated_service := updated_svc.(*api.Service) if updated_service.Name != "foo" { t.Errorf("Expected foo, but got %v", updated_service.Name) } if e, a := "foo", registry.UpdatedID; e != a { t.Errorf("Expected %v, but got %v", e, a) } }
func main() { flag.Parse() util.InitLogs() defer util.FlushLogs() verflag.PrintAndExitIfRequested() verifyMinionFlags() if len(clientConfig.Host) == 0 { glog.Fatal("usage: controller-manager -master <master>") } kubeClient, err := client.New(clientConfig) if err != nil { glog.Fatalf("Invalid API configuration: %v", err) } if int64(int(*nodeMilliCPU)) != *nodeMilliCPU { glog.Warningf("node_milli_cpu is too big for platform. Clamping: %d -> %d", *nodeMilliCPU, math.MaxInt32) *nodeMilliCPU = math.MaxInt32 } if int64(int(*nodeMemory)) != *nodeMemory { glog.Warningf("node_memory is too big for platform. Clamping: %d -> %d", *nodeMemory, math.MaxInt32) *nodeMemory = math.MaxInt32 } go http.ListenAndServe(net.JoinHostPort(address.String(), strconv.Itoa(*port)), nil) endpoints := service.NewEndpointController(kubeClient) go util.Forever(func() { endpoints.SyncServiceEndpoints() }, time.Second*10) controllerManager := replicationControllerPkg.NewReplicationManager(kubeClient) controllerManager.Run(10 * time.Second) cloud := cloudprovider.InitCloudProvider(*cloudProvider, *cloudConfigFile) nodeResources := &api.NodeResources{ Capacity: api.ResourceList{ resources.CPU: util.NewIntOrStringFromInt(int(*nodeMilliCPU)), resources.Memory: util.NewIntOrStringFromInt(int(*nodeMemory)), }, } minionController := minionControllerPkg.NewMinionController(cloud, *minionRegexp, machineList, nodeResources, kubeClient) minionController.Run(10 * time.Second) select {} }
func TestSetDefaulServiceTargetPort(t *testing.T) { in := &versioned.Service{Spec: versioned.ServiceSpec{Ports: []versioned.ServicePort{{Port: 1234}}}} obj := roundTrip(t, runtime.Object(in)) out := obj.(*versioned.Service) if out.Spec.Ports[0].TargetPort != util.NewIntOrStringFromInt(1234) { t.Errorf("Expected TargetPort to be defaulted, got %s", out.Spec.Ports[0].TargetPort) } in = &versioned.Service{Spec: versioned.ServiceSpec{Ports: []versioned.ServicePort{{Port: 1234, TargetPort: util.NewIntOrStringFromInt(5678)}}}} obj = roundTrip(t, runtime.Object(in)) out = obj.(*versioned.Service) if out.Spec.Ports[0].TargetPort != util.NewIntOrStringFromInt(5678) { t.Errorf("Expected TargetPort to be unchanged, got %s", out.Spec.Ports[0].TargetPort) } }
func generateService(name string, portSpec string) { if portSpec == "" { return } servicePort, containerPort, err := portsFromString(portSpec) checkErr(err) svc := []v1beta3.Service{{ TypeMeta: v1beta3.TypeMeta{APIVersion: "v1beta3", Kind: "Service"}, ObjectMeta: v1beta3.ObjectMeta{ Name: name, Labels: map[string]string{ "service": name, }, }, Spec: v1beta3.ServiceSpec{ Port: servicePort, ContainerPort: util.NewIntOrStringFromInt(containerPort), Selector: map[string]string{ "service": name, }, }, }} svcOutData, err := yaml.Marshal(svc) checkErr(err) fmt.Print(string(svcOutData)) }
func TestSyncEndpointsItemsPreexistingIdentical(t *testing.T) { ns := api.NamespaceDefault testServer, endpointsHandler := makeTestServer(t, api.NamespaceDefault, serverResponse{http.StatusOK, &api.Endpoints{ ObjectMeta: api.ObjectMeta{ ResourceVersion: "1", Name: "foo", Namespace: ns, }, Subsets: []api.EndpointSubset{{ Addresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: &api.ObjectReference{Kind: "Pod", Name: "pod0", Namespace: ns}}}, Ports: []api.EndpointPort{{Port: 8080, Protocol: "TCP"}}, }}, }}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Version()}) endpoints := NewEndpointController(client) addPods(endpoints.podStore.Store, api.NamespaceDefault, 1, 1) endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault}, Spec: api.ServiceSpec{ Selector: map[string]string{"foo": "bar"}, Ports: []api.ServicePort{{Port: 80, Protocol: "TCP", TargetPort: util.NewIntOrStringFromInt(8080)}}, }, }) endpoints.syncService(ns + "/foo") endpointsHandler.ValidateRequest(t, testapi.ResourcePathWithNamespaceQuery("endpoints", api.NamespaceDefault, "foo"), "GET", nil) }
func TestServiceRegistryIPLoadBalancer(t *testing.T) { rest, _ := NewTestREST(t, nil) svc := &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeLoadBalancer, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(6502), }}, }, } ctx := api.NewDefaultContext() created_svc, _ := rest.Create(ctx, svc) created_service := created_svc.(*api.Service) if created_service.Spec.Ports[0].Port != 6502 { t.Errorf("Expected port 6502, but got %v", created_service.Spec.Ports[0].Port) } if !makeIPNet(t).Contains(net.ParseIP(created_service.Spec.ClusterIP)) { t.Errorf("Unexpected ClusterIP: %s", created_service.Spec.ClusterIP) } update := deepCloneService(created_service) _, _, err := rest.Update(ctx, update) if err != nil { t.Errorf("Unexpected error %v", err) } }
func TestServiceRegistryExternalService(t *testing.T) { ctx := api.NewDefaultContext() storage, registry := NewTestREST(t, nil) svc := &api.Service{ ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, SessionAffinity: api.ServiceAffinityNone, Type: api.ServiceTypeLoadBalancer, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(6502), }}, }, } _, err := storage.Create(ctx, svc) if err != nil { t.Errorf("Failed to create service: %#v", err) } srv, err := registry.GetService(ctx, svc.Name) if err != nil { t.Errorf("Unexpected error: %v", err) } if srv == nil { t.Errorf("Failed to find service: %s", svc.Name) } }
// Creates a replication controller that serves its hostname and a service on top of it. func startServeHostnameService(c *client.Client, ns, name string, port, replicas int) ([]string, string, error) { podNames := make([]string, replicas) _, err := c.Services(ns).Create(&api.Service{ ObjectMeta: api.ObjectMeta{ Name: name, }, Spec: api.ServiceSpec{ Ports: []api.ServicePort{{ Port: port, TargetPort: util.NewIntOrStringFromInt(9376), Protocol: "TCP", }}, Selector: map[string]string{ "name": name, }, }, }) if err != nil { return podNames, "", err } var createdPods []*api.Pod maxContainerFailures := 0 config := RCConfig{ Client: c, Image: "gcr.io/google_containers/serve_hostname:1.1", Name: name, Namespace: ns, PollInterval: 3 * time.Second, Timeout: 30 * time.Second, Replicas: replicas, CreatedPods: &createdPods, MaxContainerFailures: &maxContainerFailures, } err = RunRC(config) if err != nil { return podNames, "", err } if len(createdPods) != replicas { return podNames, "", fmt.Errorf("Incorrect number of running pods: %v", len(createdPods)) } for i := range createdPods { podNames[i] = createdPods[i].ObjectMeta.Name } sort.StringSlice(podNames).Sort() service, err := c.Services(ns).Get(name) if err != nil { return podNames, "", err } if service.Spec.ClusterIP == "" { return podNames, "", fmt.Errorf("Service IP is blank for %v", name) } serviceIP := service.Spec.ClusterIP return podNames, serviceIP, nil }
func TestSyncEndpointsItemsWithLabels(t *testing.T) { ns := "other" testServer, endpointsHandler := makeTestServer(t, ns, serverResponse{http.StatusOK, &api.Endpoints{}}) defer testServer.Close() client := client.NewOrDie(&client.Config{Host: testServer.URL, Version: testapi.Version()}) endpoints := NewEndpointController(client) addPods(endpoints.podStore.Store, ns, 3, 2) serviceLabels := map[string]string{"foo": "bar"} endpoints.serviceStore.Store.Add(&api.Service{ ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: ns, Labels: serviceLabels, }, Spec: api.ServiceSpec{ Selector: map[string]string{"foo": "bar"}, Ports: []api.ServicePort{ {Name: "port0", Port: 80, Protocol: "TCP", TargetPort: util.NewIntOrStringFromInt(8080)}, {Name: "port1", Port: 88, Protocol: "TCP", TargetPort: util.NewIntOrStringFromInt(8088)}, }, }, }) endpoints.syncService(ns + "/foo") expectedSubsets := []api.EndpointSubset{{ Addresses: []api.EndpointAddress{ {IP: "1.2.3.4", TargetRef: &api.ObjectReference{Kind: "Pod", Name: "pod0", Namespace: ns}}, {IP: "1.2.3.5", TargetRef: &api.ObjectReference{Kind: "Pod", Name: "pod1", Namespace: ns}}, {IP: "1.2.3.6", TargetRef: &api.ObjectReference{Kind: "Pod", Name: "pod2", Namespace: ns}}, }, Ports: []api.EndpointPort{ {Name: "port0", Port: 8080, Protocol: "TCP"}, {Name: "port1", Port: 8088, Protocol: "TCP"}, }, }} data := runtime.EncodeOrDie(testapi.Codec(), &api.Endpoints{ ObjectMeta: api.ObjectMeta{ ResourceVersion: "", Labels: serviceLabels, }, Subsets: endptspkg.SortSubsets(expectedSubsets), }) // endpointsHandler should get 2 requests - one for "GET" and the next for "POST". endpointsHandler.ValidateRequestCount(t, 2) endpointsHandler.ValidateRequest(t, testapi.ResourcePathWithNamespaceQuery("endpoints", ns, ""), "POST", &data) }
func (ServiceGenerator) Generate(params map[string]string) (runtime.Object, error) { selectorString, found := params["selector"] if !found || len(selectorString) == 0 { return nil, fmt.Errorf("'selector' is a required parameter.") } selector := ParseLabels(selectorString) name, found := params["name"] if !found { return nil, fmt.Errorf("'name' is a required parameter.") } portString, found := params["port"] if !found { return nil, fmt.Errorf("'port' is a required parameter.") } port, err := strconv.Atoi(portString) if err != nil { return nil, err } service := api.Service{ ObjectMeta: api.ObjectMeta{ Name: name, }, Spec: api.ServiceSpec{ Port: port, Protocol: api.Protocol(params["protocol"]), Selector: selector, }, } containerPort, found := params["container-port"] if found && len(containerPort) > 0 { if cPort, err := strconv.Atoi(containerPort); err != nil { service.Spec.ContainerPort = util.NewIntOrStringFromString(containerPort) } else { service.Spec.ContainerPort = util.NewIntOrStringFromInt(cPort) } } else { service.Spec.ContainerPort = util.NewIntOrStringFromInt(port) } if params["create-external-load-balancer"] == "true" { service.Spec.CreateExternalLoadBalancer = true } if len(params["public-ip"]) != 0 { service.Spec.PublicIPs = []string{params["public-ip"]} } return &service, nil }
func (b webserverProbeBuilder) build() *api.Probe { probe := &api.Probe{ Handler: api.Handler{ HTTPGet: &api.HTTPGetAction{ Port: util.NewIntOrStringFromInt(80), Path: "/", }, }, } if b.initialDelay { probe.InitialDelaySeconds = 30 } if b.failing { probe.HTTPGet.Port = util.NewIntOrStringFromInt(81) } return probe }
func TestDoRequestNewWayFile(t *testing.T) { reqObj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} reqBodyExpected, err := testapi.Codec().Encode(reqObj) if err != nil { t.Errorf("unexpected error: %v", err) } file, err := ioutil.TempFile("", "foo") if err != nil { t.Errorf("unexpected error: %v", err) } _, err = file.Write(reqBodyExpected) if err != nil { t.Errorf("unexpected error: %v", err) } expectedObj := &api.Service{Spec: api.ServiceSpec{Ports: []api.ServicePort{{ Protocol: "TCP", Port: 12345, TargetPort: util.NewIntOrStringFromInt(12345), }}}} expectedBody, _ := testapi.Codec().Encode(expectedObj) fakeHandler := util.FakeHandler{ StatusCode: 200, ResponseBody: string(expectedBody), T: t, } testServer := httptest.NewServer(&fakeHandler) c := NewOrDie(&Config{Host: testServer.URL, Version: testapi.Version(), Username: "******", Password: "******"}) wasCreated := true obj, err := c.Verb("POST"). Prefix("foo/bar", "baz"). Timeout(time.Second). Body(file.Name()). Do().WasCreated(&wasCreated).Get() if err != nil { t.Errorf("Unexpected error: %v %#v", err, err) return } if obj == nil { t.Error("nil obj") } else if !api.Semantic.DeepDerivative(expectedObj, obj) { t.Errorf("Expected: %#v, got %#v", expectedObj, obj) } if wasCreated { t.Errorf("expected object was not created") } tmpStr := string(reqBodyExpected) requestURL := testapi.ResourcePathWithPrefix("foo/bar/baz", "", "", "") requestURL += "?timeout=1s" fakeHandler.ValidateRequest(t, requestURL, "POST", &tmpStr) if fakeHandler.RequestReceived.Header["Authorization"] == nil { t.Errorf("Request is missing authorization header: %#v", *fakeHandler.RequestReceived) } }
// RunControllerManager starts a controller func RunControllerManager(machineList []string, cl *client.Client, nodeMilliCPU, nodeMemory int64) { if int64(int(nodeMilliCPU)) != nodeMilliCPU || int64(int(nodeMemory)) != nodeMemory { glog.Fatalf("Overflow, nodeCPU or nodeMemory too large for the platform") } nodeResources := &api.NodeResources{ Capacity: api.ResourceList{ resources.CPU: util.NewIntOrStringFromInt(int(nodeMilliCPU)), resources.Memory: util.NewIntOrStringFromInt(int(nodeMemory)), }, } minionController := minionControllerPkg.NewMinionController(nil, "", machineList, nodeResources, cl) minionController.Run(10 * time.Second) endpoints := service.NewEndpointController(cl) go util.Forever(func() { endpoints.SyncServiceEndpoints() }, time.Second*10) controllerManager := controller.NewReplicationManager(cl) controllerManager.Run(10 * time.Second) }
func TestSetDefaultServicePort(t *testing.T) { // Unchanged if set. in := &versioned.Service{Spec: versioned.ServiceSpec{ Ports: []versioned.ServicePort{ {Protocol: "UDP", Port: 9376, TargetPort: util.NewIntOrStringFromString("p")}, {Protocol: "UDP", Port: 8675, TargetPort: util.NewIntOrStringFromInt(309)}, }, }} out := roundTrip(t, runtime.Object(in)).(*versioned.Service) if out.Spec.Ports[0].Protocol != versioned.ProtocolUDP { t.Errorf("Expected protocol %s, got %s", versioned.ProtocolUDP, out.Spec.Ports[0].Protocol) } if out.Spec.Ports[0].TargetPort != util.NewIntOrStringFromString("p") { t.Errorf("Expected port %d, got %s", in.Spec.Ports[0].Port, out.Spec.Ports[0].TargetPort) } if out.Spec.Ports[1].Protocol != versioned.ProtocolUDP { t.Errorf("Expected protocol %s, got %s", versioned.ProtocolUDP, out.Spec.Ports[1].Protocol) } if out.Spec.Ports[1].TargetPort != util.NewIntOrStringFromInt(309) { t.Errorf("Expected port %d, got %s", in.Spec.Ports[1].Port, out.Spec.Ports[1].TargetPort) } // Defaulted. in = &versioned.Service{Spec: versioned.ServiceSpec{ Ports: []versioned.ServicePort{ {Protocol: "", Port: 9376, TargetPort: util.NewIntOrStringFromString("")}, {Protocol: "", Port: 8675, TargetPort: util.NewIntOrStringFromInt(0)}, }, }} out = roundTrip(t, runtime.Object(in)).(*versioned.Service) if out.Spec.Ports[0].Protocol != versioned.ProtocolTCP { t.Errorf("Expected protocol %s, got %s", versioned.ProtocolTCP, out.Spec.Ports[0].Protocol) } if out.Spec.Ports[0].TargetPort != util.NewIntOrStringFromInt(in.Spec.Ports[0].Port) { t.Errorf("Expected port %d, got %d", in.Spec.Ports[0].Port, out.Spec.Ports[0].TargetPort) } if out.Spec.Ports[1].Protocol != versioned.ProtocolTCP { t.Errorf("Expected protocol %s, got %s", versioned.ProtocolTCP, out.Spec.Ports[1].Protocol) } if out.Spec.Ports[1].TargetPort != util.NewIntOrStringFromInt(in.Spec.Ports[1].Port) { t.Errorf("Expected port %d, got %d", in.Spec.Ports[1].Port, out.Spec.Ports[1].TargetPort) } }
func TestGetURLParts(t *testing.T) { testCases := []struct { probe *api.HTTPGetProbe ok bool host string port int path string }{ {&api.HTTPGetProbe{Host: "", Port: util.NewIntOrStringFromInt(-1), Path: ""}, false, "", -1, ""}, {&api.HTTPGetProbe{Host: "", Port: util.NewIntOrStringFromString(""), Path: ""}, false, "", -1, ""}, {&api.HTTPGetProbe{Host: "", Port: util.NewIntOrStringFromString("-1"), Path: ""}, false, "", -1, ""}, {&api.HTTPGetProbe{Host: "", Port: util.NewIntOrStringFromString("not-found"), Path: ""}, false, "", -1, ""}, {&api.HTTPGetProbe{Host: "", Port: util.NewIntOrStringFromString("found"), Path: ""}, true, "127.0.0.1", 93, ""}, {&api.HTTPGetProbe{Host: "", Port: util.NewIntOrStringFromInt(76), Path: ""}, true, "127.0.0.1", 76, ""}, {&api.HTTPGetProbe{Host: "", Port: util.NewIntOrStringFromString("118"), Path: ""}, true, "127.0.0.1", 118, ""}, {&api.HTTPGetProbe{Host: "hostname", Port: util.NewIntOrStringFromInt(76), Path: "path"}, true, "hostname", 76, "path"}, } for _, test := range testCases { state := api.PodState{PodIP: "127.0.0.1"} container := api.Container{ Ports: []api.Port{{Name: "found", HostPort: 93}}, LivenessProbe: &api.LivenessProbe{ HTTPGet: test.probe, Type: "http", }, } host, port, path, err := getURLParts(state, container) if !test.ok && err == nil { t.Errorf("Expected error for %+v, got %s:%d/%s", test, host, port, path) } if test.ok && err != nil { t.Errorf("Unexpected error: %v", err) } if test.ok { if host != test.host || port != test.port || path != test.path { t.Errorf("Expected %s:%d/%s, got %s:%d/%s", test.host, test.port, test.path, host, port, path) } } } }
func TestGetTCPAddrParts(t *testing.T) { testCases := []struct { probe *api.TCPSocketAction ok bool host string port int }{ {&api.TCPSocketAction{Port: util.NewIntOrStringFromInt(-1)}, false, "", -1}, {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("")}, false, "", -1}, {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("-1")}, false, "", -1}, {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("not-found")}, false, "", -1}, {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("found")}, true, "1.2.3.4", 93}, {&api.TCPSocketAction{Port: util.NewIntOrStringFromInt(76)}, true, "1.2.3.4", 76}, {&api.TCPSocketAction{Port: util.NewIntOrStringFromString("118")}, true, "1.2.3.4", 118}, } for _, test := range testCases { host := "1.2.3.4" container := api.Container{ Ports: []api.ContainerPort{{Name: "found", HostPort: 93}}, LivenessProbe: &api.Probe{ Handler: api.Handler{ TCPSocket: test.probe, }, }, } port, err := extractPort(test.probe.Port, container) if !test.ok && err == nil { t.Errorf("Expected error for %+v, got %s:%d", test, host, port) } if test.ok && err != nil { t.Errorf("Unexpected error: %v", err) } if test.ok { if host != test.host || port != test.port { t.Errorf("Expected %s:%d, got %s:%d", test.host, test.port, host, port) } } } }
func TestGetEndpoints(t *testing.T) { // 2 pods each of which have 3 targetPorts exposed via a single service endpointAddresses := []api.EndpointAddress{ {IP: "1.2.3.4"}, {IP: "6.7.8.9"}, } ports := []int{80, 443, 3306} endpointPorts := []api.EndpointPort{ {Port: ports[0], Protocol: "TCP"}, {Port: ports[1], Protocol: "TCP"}, {Port: ports[2], Protocol: "TCP", Name: "mysql"}, } servicePorts := []api.ServicePort{ {Port: 10, TargetPort: util.NewIntOrStringFromInt(ports[0])}, {Port: 20, TargetPort: util.NewIntOrStringFromInt(ports[1])}, {Port: 30, TargetPort: util.NewIntOrStringFromString("mysql")}, } svc := getService(servicePorts) endpoints := []*api.Endpoints{getEndpoints(svc, endpointAddresses, endpointPorts)} flb := newFakeLoadBalancerController(endpoints, []*api.Service{svc}) for i := range ports { eps := flb.getEndpoints(svc, &svc.Spec.Ports[i]) expectedEps := util.NewStringSet() for _, address := range endpointAddresses { expectedEps.Insert(fmt.Sprintf("%v:%v", address.IP, ports[i])) } receivedEps := util.NewStringSet() for _, ep := range eps { receivedEps.Insert(ep) } if len(receivedEps) != len(expectedEps) || !expectedEps.IsSuperset(receivedEps) { t.Fatalf("Unexpected endpoints, received %+v, expected %+v", receivedEps, expectedEps) } glog.Infof("Got endpoints %+v", receivedEps) } }
func TestCreate(t *testing.T) { rest, registry := NewTestREST(t, nil) test := resttest.New(t, rest, registry.SetError) test.TestCreate( // valid &api.Service{ Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, ClusterIP: "None", SessionAffinity: "None", Type: api.ServiceTypeClusterIP, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(6502), }}, }, }, // invalid &api.Service{ Spec: api.ServiceSpec{}, }, // invalid &api.Service{ Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, ClusterIP: "invalid", SessionAffinity: "None", Type: api.ServiceTypeClusterIP, Ports: []api.ServicePort{{ Port: 6502, Protocol: api.ProtocolTCP, TargetPort: util.NewIntOrStringFromInt(6502), }}, }, }, ) }