func TestDoRequestNewWay(t *testing.T) { reqBody := "request body" expectedObj := &api.Service{Spec: api.ServiceSpec{Ports: []api.ServicePort{{ Protocol: "TCP", Port: 12345, TargetPort: intstr.FromInt(12345), }}}} expectedBody, _ := runtime.Encode(testapi.Default.Codec(), expectedObj) fakeHandler := utiltesting.FakeHandler{ StatusCode: 200, ResponseBody: string(expectedBody), T: t, } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() c := testRESTClient(t, testServer) obj, err := c.Verb("POST"). Prefix("foo", "bar"). Suffix("baz"). Timeout(time.Second). Body([]byte(reqBody)). Do().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) } requestURL := testapi.Default.ResourcePathWithPrefix("foo/bar", "", "", "baz") requestURL += "?timeout=1s" fakeHandler.ValidateRequest(t, requestURL, "POST", &reqBody) }
func SetDefaults_ServiceSpec(obj *ServiceSpec) { if obj.SessionAffinity == "" { obj.SessionAffinity = ServiceAffinityNone } if obj.Type == "" { obj.Type = ServiceTypeClusterIP } for i := range obj.Ports { sp := &obj.Ports[i] if sp.Protocol == "" { sp.Protocol = ProtocolTCP } if sp.TargetPort == intstr.FromInt(0) || sp.TargetPort == intstr.FromString("") { sp.TargetPort = intstr.FromInt(int(sp.Port)) } } }
func TestDoRequestNewWayFile(t *testing.T) { reqObj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} reqBodyExpected, err := runtime.Encode(testapi.Default.Codec(), reqObj) if err != nil { t.Errorf("unexpected error: %v", err) } file, err := ioutil.TempFile("", "foo") if err != nil { t.Errorf("unexpected error: %v", err) } defer file.Close() defer os.Remove(file.Name()) _, 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: intstr.FromInt(12345), }}}} expectedBody, _ := runtime.Encode(testapi.Default.Codec(), expectedObj) fakeHandler := utiltesting.FakeHandler{ StatusCode: 200, ResponseBody: string(expectedBody), T: t, } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() c := testRESTClient(t, testServer) 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 created") } tmpStr := string(reqBodyExpected) requestURL := testapi.Default.ResourcePathWithPrefix("foo/bar/baz", "", "", "") requestURL += "?timeout=1s" fakeHandler.ValidateRequest(t, requestURL, "POST", &tmpStr) }
func SetDefaults_Deployment(obj *Deployment) { // Default labels and selector to labels from pod template spec. labels := obj.Spec.Template.Labels if labels != nil { if obj.Spec.Selector == nil { obj.Spec.Selector = &LabelSelector{MatchLabels: labels} } if len(obj.Labels) == 0 { obj.Labels = labels } } // Set DeploymentSpec.Replicas to 1 if it is not set. if obj.Spec.Replicas == nil { obj.Spec.Replicas = new(int32) *obj.Spec.Replicas = 1 } strategy := &obj.Spec.Strategy // Set default DeploymentStrategyType as RollingUpdate. if strategy.Type == "" { strategy.Type = RollingUpdateDeploymentStrategyType } if strategy.Type == RollingUpdateDeploymentStrategyType { if strategy.RollingUpdate == nil { rollingUpdate := RollingUpdateDeployment{} strategy.RollingUpdate = &rollingUpdate } if strategy.RollingUpdate.MaxUnavailable == nil { // Set default MaxUnavailable as 1 by default. maxUnavailable := intstr.FromInt(1) strategy.RollingUpdate.MaxUnavailable = &maxUnavailable } if strategy.RollingUpdate.MaxSurge == nil { // Set default MaxSurge as 1 by default. maxSurge := intstr.FromInt(1) strategy.RollingUpdate.MaxSurge = &maxSurge } } }
func TestDoRequestNewWayObj(t *testing.T) { reqObj := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}} reqBodyExpected, _ := runtime.Encode(testapi.Default.Codec(), reqObj) expectedObj := &api.Service{Spec: api.ServiceSpec{Ports: []api.ServicePort{{ Protocol: "TCP", Port: 12345, TargetPort: intstr.FromInt(12345), }}}} expectedBody, _ := runtime.Encode(testapi.Default.Codec(), expectedObj) fakeHandler := utiltesting.FakeHandler{ StatusCode: 200, ResponseBody: string(expectedBody), T: t, } testServer := httptest.NewServer(&fakeHandler) defer testServer.Close() c := testRESTClient(t, testServer) obj, err := c.Verb("POST"). Suffix("baz"). Name("bar"). Resource("foo"). LabelsSelectorParam(labels.Set{"name": "foo"}.AsSelector()). Timeout(time.Second). Body(reqObj). Do().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) } tmpStr := string(reqBodyExpected) requestURL := testapi.Default.ResourcePath("foo", "", "bar/baz") requestURL += "?" + unversioned.LabelSelectorQueryParam(testapi.Default.GroupVersion().String()) + "=name%3Dfoo&timeout=1s" fakeHandler.ValidateRequest(t, requestURL, "POST", &tmpStr) }
var cs *kubernetes.Clientset BeforeEach(func() { // skip on GKE since alpha features are disabled framework.SkipIfProviderIs("gke") cs = f.StagingClient ns = f.Namespace.Name }) It("should create a PodDisruptionBudget", func() { createPodDisruptionBudgetOrDie(cs, ns, intstr.FromString("1%")) }) It("should update PodDisruptionBudget status", func() { createPodDisruptionBudgetOrDie(cs, ns, intstr.FromInt(2)) createPodsOrDie(cs, ns, 3) // Since disruptionAllowed starts out false, if we see it ever become true, // that means the controller is working. err := wait.PollImmediate(framework.Poll, timeout, func() (bool, error) { pdb, err := cs.Policy().PodDisruptionBudgets(ns).Get("foo") if err != nil { return false, err } return pdb.Status.PodDisruptionAllowed, nil }) Expect(err).NotTo(HaveOccurred()) })
func TestLoadMultipleNamespacedIngresses(t *testing.T) { ingresses := []*v1beta1.Ingress{ { ObjectMeta: v1.ObjectMeta{ Namespace: "awesome", }, Spec: v1beta1.IngressSpec{ Rules: []v1beta1.IngressRule{ { Host: "foo", IngressRuleValue: v1beta1.IngressRuleValue{ HTTP: &v1beta1.HTTPIngressRuleValue{ Paths: []v1beta1.HTTPIngressPath{ { Path: "/bar", Backend: v1beta1.IngressBackend{ ServiceName: "service1", ServicePort: intstr.FromInt(801), }, }, }, }, }, }, { Host: "bar", IngressRuleValue: v1beta1.IngressRuleValue{ HTTP: &v1beta1.HTTPIngressRuleValue{ Paths: []v1beta1.HTTPIngressPath{ { Backend: v1beta1.IngressBackend{ ServiceName: "service3", ServicePort: intstr.FromInt(443), }, }, { Backend: v1beta1.IngressBackend{ ServiceName: "service2", ServicePort: intstr.FromInt(802), }, }, }, }, }, }, }, }, }, { ObjectMeta: v1.ObjectMeta{ Namespace: "somewhat-awesome", }, Spec: v1beta1.IngressSpec{ Rules: []v1beta1.IngressRule{ { Host: "awesome", IngressRuleValue: v1beta1.IngressRuleValue{ HTTP: &v1beta1.HTTPIngressRuleValue{ Paths: []v1beta1.HTTPIngressPath{ { Path: "/quix", Backend: v1beta1.IngressBackend{ ServiceName: "service1", ServicePort: intstr.FromInt(801), }, }, }, }, }, }, }, }, }, { ObjectMeta: v1.ObjectMeta{ Namespace: "not-awesome", }, Spec: v1beta1.IngressSpec{ Rules: []v1beta1.IngressRule{ { Host: "baz", IngressRuleValue: v1beta1.IngressRuleValue{ HTTP: &v1beta1.HTTPIngressRuleValue{ Paths: []v1beta1.HTTPIngressPath{ { Path: "/baz", Backend: v1beta1.IngressBackend{ ServiceName: "service1", ServicePort: intstr.FromInt(801), }, }, }, }, }, }, }, }, }, } services := []*v1.Service{ { ObjectMeta: v1.ObjectMeta{ Name: "service1", Namespace: "awesome", UID: "1", }, Spec: v1.ServiceSpec{ ClusterIP: "10.0.0.1", Ports: []v1.ServicePort{ { Name: "http", Port: 801, }, }, }, }, { ObjectMeta: v1.ObjectMeta{ Namespace: "somewhat-awesome", Name: "service1", UID: "17", }, Spec: v1.ServiceSpec{ ClusterIP: "10.0.0.4", Ports: []v1.ServicePort{ { Name: "http", Port: 801, }, }, }, }, { ObjectMeta: v1.ObjectMeta{ Namespace: "awesome", Name: "service2", UID: "2", }, Spec: v1.ServiceSpec{ ClusterIP: "10.0.0.2", Ports: []v1.ServicePort{ { Port: 802, }, }, }, }, { ObjectMeta: v1.ObjectMeta{ Namespace: "awesome", Name: "service3", UID: "3", }, Spec: v1.ServiceSpec{ ClusterIP: "10.0.0.3", Ports: []v1.ServicePort{ { Name: "http", Port: 443, }, }, }, }, } watchChan := make(chan interface{}) client := clientMock{ ingresses: ingresses, services: services, watchChan: watchChan, } provider := Kubernetes{ Namespaces: []string{"awesome", "somewhat-awesome"}, } actual, err := provider.loadIngresses(client) if err != nil { t.Fatalf("error %+v", err) } expected := &types.Configuration{ Backends: map[string]*types.Backend{ "foo/bar": { Servers: map[string]types.Server{ "1": { URL: "http://10.0.0.1:801", Weight: 1, }, }, CircuitBreaker: nil, LoadBalancer: nil, }, "bar": { Servers: map[string]types.Server{ "2": { URL: "http://10.0.0.2:802", Weight: 1, }, "3": { URL: "https://10.0.0.3:443", Weight: 1, }, }, CircuitBreaker: nil, LoadBalancer: nil, }, "awesome/quix": { Servers: map[string]types.Server{ "17": { URL: "http://10.0.0.4:801", Weight: 1, }, }, CircuitBreaker: nil, LoadBalancer: nil, }, }, Frontends: map[string]*types.Frontend{ "foo/bar": { Backend: "foo/bar", PassHostHeader: true, Priority: len("/bar"), Routes: map[string]types.Route{ "/bar": { Rule: "PathPrefix:/bar", }, "foo": { Rule: "Host:foo", }, }, }, "bar": { Backend: "bar", PassHostHeader: true, Routes: map[string]types.Route{ "bar": { Rule: "Host:bar", }, }, }, "awesome/quix": { Backend: "awesome/quix", PassHostHeader: true, Priority: len("/quix"), Routes: map[string]types.Route{ "/quix": { Rule: "PathPrefix:/quix", }, "awesome": { Rule: "Host:awesome", }, }, }, }, } actualJSON, _ := json.Marshal(actual) expectedJSON, _ := json.Marshal(expected) if !reflect.DeepEqual(actual, expected) { t.Fatalf("expected %+v, got %+v", string(expectedJSON), string(actualJSON)) } }
func TestOnlyReferencesServicesFromOwnNamespace(t *testing.T) { ingresses := []*v1beta1.Ingress{ { ObjectMeta: v1.ObjectMeta{ Namespace: "awesome", }, Spec: v1beta1.IngressSpec{ Rules: []v1beta1.IngressRule{ { Host: "foo", IngressRuleValue: v1beta1.IngressRuleValue{ HTTP: &v1beta1.HTTPIngressRuleValue{ Paths: []v1beta1.HTTPIngressPath{ { Backend: v1beta1.IngressBackend{ ServiceName: "service", ServicePort: intstr.FromInt(80), }, }, }, }, }, }, }, }, }, } services := []*v1.Service{ { ObjectMeta: v1.ObjectMeta{ Name: "service", UID: "1", Namespace: "awesome", }, Spec: v1.ServiceSpec{ ClusterIP: "10.0.0.1", Ports: []v1.ServicePort{ { Name: "http", Port: 80, }, }, }, }, { ObjectMeta: v1.ObjectMeta{ Name: "service", UID: "2", Namespace: "not-awesome", }, Spec: v1.ServiceSpec{ ClusterIP: "10.0.0.2", Ports: []v1.ServicePort{ { Name: "http", Port: 80, }, }, }, }, } watchChan := make(chan interface{}) client := clientMock{ ingresses: ingresses, services: services, watchChan: watchChan, } provider := Kubernetes{} actual, err := provider.loadIngresses(client) if err != nil { t.Fatalf("error %+v", err) } expected := &types.Configuration{ Backends: map[string]*types.Backend{ "foo": { Servers: map[string]types.Server{ "1": { URL: "http://10.0.0.1:80", Weight: 1, }, }, CircuitBreaker: nil, LoadBalancer: nil, }, }, Frontends: map[string]*types.Frontend{ "foo": { Backend: "foo", PassHostHeader: true, Routes: map[string]types.Route{ "foo": { Rule: "Host:foo", }, }, }, }, } actualJSON, _ := json.Marshal(actual) expectedJSON, _ := json.Marshal(expected) if !reflect.DeepEqual(actual, expected) { t.Fatalf("expected %+v, got %+v", string(expectedJSON), string(actualJSON)) } }
func TestRuleType(t *testing.T) { ingresses := []*v1beta1.Ingress{ { ObjectMeta: v1.ObjectMeta{ Annotations: map[string]string{"traefik.frontend.rule.type": "PathPrefixStrip"}, //camel case }, Spec: v1beta1.IngressSpec{ Rules: []v1beta1.IngressRule{ { Host: "foo1", IngressRuleValue: v1beta1.IngressRuleValue{ HTTP: &v1beta1.HTTPIngressRuleValue{ Paths: []v1beta1.HTTPIngressPath{ { Path: "/bar1", Backend: v1beta1.IngressBackend{ ServiceName: "service1", ServicePort: intstr.FromInt(801), }, }, }, }, }, }, }, }, }, { ObjectMeta: v1.ObjectMeta{ Annotations: map[string]string{"traefik.frontend.rule.type": "path"}, //lower case }, Spec: v1beta1.IngressSpec{ Rules: []v1beta1.IngressRule{ { Host: "foo1", IngressRuleValue: v1beta1.IngressRuleValue{ HTTP: &v1beta1.HTTPIngressRuleValue{ Paths: []v1beta1.HTTPIngressPath{ { Path: "/bar2", Backend: v1beta1.IngressBackend{ ServiceName: "service1", ServicePort: intstr.FromInt(801), }, }, }, }, }, }, }, }, }, { ObjectMeta: v1.ObjectMeta{ Annotations: map[string]string{"traefik.frontend.rule.type": "PathPrefix"}, //path prefix }, Spec: v1beta1.IngressSpec{ Rules: []v1beta1.IngressRule{ { Host: "foo2", IngressRuleValue: v1beta1.IngressRuleValue{ HTTP: &v1beta1.HTTPIngressRuleValue{ Paths: []v1beta1.HTTPIngressPath{ { Path: "/bar1", Backend: v1beta1.IngressBackend{ ServiceName: "service1", ServicePort: intstr.FromInt(801), }, }, }, }, }, }, }, }, }, { ObjectMeta: v1.ObjectMeta{ Annotations: map[string]string{"traefik.frontend.rule.type": "PathStrip"}, //path strip }, Spec: v1beta1.IngressSpec{ Rules: []v1beta1.IngressRule{ { Host: "foo2", IngressRuleValue: v1beta1.IngressRuleValue{ HTTP: &v1beta1.HTTPIngressRuleValue{ Paths: []v1beta1.HTTPIngressPath{ { Path: "/bar2", Backend: v1beta1.IngressBackend{ ServiceName: "service1", ServicePort: intstr.FromInt(801), }, }, }, }, }, }, }, }, }, { ObjectMeta: v1.ObjectMeta{ Annotations: map[string]string{"traefik.frontend.rule.type": "PathXXStrip"}, //wrong rule }, Spec: v1beta1.IngressSpec{ Rules: []v1beta1.IngressRule{ { Host: "foo1", IngressRuleValue: v1beta1.IngressRuleValue{ HTTP: &v1beta1.HTTPIngressRuleValue{ Paths: []v1beta1.HTTPIngressPath{ { Path: "/bar3", Backend: v1beta1.IngressBackend{ ServiceName: "service1", ServicePort: intstr.FromInt(801), }, }, }, }, }, }, }, }, }, } services := []*v1.Service{ { ObjectMeta: v1.ObjectMeta{ Name: "service1", UID: "1", }, Spec: v1.ServiceSpec{ ClusterIP: "10.0.0.1", Ports: []v1.ServicePort{ { Name: "http", Port: 801, }, }, }, }, } watchChan := make(chan interface{}) client := clientMock{ ingresses: ingresses, services: services, watchChan: watchChan, } provider := Kubernetes{DisablePassHostHeaders: true} actualConfig, err := provider.loadIngresses(client) actual := actualConfig.Frontends if err != nil { t.Fatalf("error %+v", err) } expected := map[string]*types.Frontend{ "foo1/bar1": { Backend: "foo1/bar1", Priority: len("/bar1"), Routes: map[string]types.Route{ "/bar1": { Rule: "PathPrefixStrip:/bar1", }, "foo1": { Rule: "Host:foo1", }, }, }, "foo1/bar2": { Backend: "foo1/bar2", Priority: len("/bar2"), Routes: map[string]types.Route{ "/bar2": { Rule: "Path:/bar2", }, "foo1": { Rule: "Host:foo1", }, }, }, "foo2/bar1": { Backend: "foo2/bar1", Priority: len("/bar1"), Routes: map[string]types.Route{ "/bar1": { Rule: "PathPrefix:/bar1", }, "foo2": { Rule: "Host:foo2", }, }, }, "foo2/bar2": { Backend: "foo2/bar2", Priority: len("/bar2"), Routes: map[string]types.Route{ "/bar2": { Rule: "PathStrip:/bar2", }, "foo2": { Rule: "Host:foo2", }, }, }, "foo1/bar3": { Backend: "foo1/bar3", Priority: len("/bar3"), Routes: map[string]types.Route{ "/bar3": { Rule: "PathPrefix:/bar3", }, "foo1": { Rule: "Host:foo1", }, }, }, } actualJSON, _ := json.Marshal(actual) expectedJSON, _ := json.Marshal(expected) if !reflect.DeepEqual(actual, expected) { t.Fatalf("expected %+v, got %+v", string(expectedJSON), string(actualJSON)) } }
func TestMakeNextRule(t *testing.T) { tg := TranslateGroup{ kubePolicy: &v1beta1.NetworkPolicy{ Spec: v1beta1.NetworkPolicySpec{ Ingress: []v1beta1.NetworkPolicyIngressRule{ v1beta1.NetworkPolicyIngressRule{}, }, }, }, romanaPolicy: &common.Policy{ Name: "TestPolicy", }, ingressIndex: 0, } translator := Translator{ cacheMu: &sync.Mutex{}, segmentLabelName: "role", } var portTCP v1.Protocol = "TCP" var portUDP v1.Protocol = "UDP" var port53 intstr.IntOrString = intstr.FromInt(53) var port80 intstr.IntOrString = intstr.FromInt(80) testCases := []struct { ToPorts []v1beta1.NetworkPolicyPort RomanaPolicy common.Policy expected func(*common.Policy) bool }{ { ToPorts: []v1beta1.NetworkPolicyPort{ v1beta1.NetworkPolicyPort{ Port: &port80, Protocol: &portTCP, }, v1beta1.NetworkPolicyPort{ Port: &port53, Protocol: &portUDP, }, }, RomanaPolicy: common.Policy{ Name: "TestPolicyWithPorts", Ingress: []common.RomanaIngress{ common.RomanaIngress{}, }, }, expected: func(p *common.Policy) bool { return p.Ingress[0].Rules[0].Ports[0] == 80 && p.Ingress[0].Rules[0].Protocol == "tcp" && p.Ingress[0].Rules[1].Ports[0] == 53 && p.Ingress[0].Rules[1].Protocol == "udp" }, }, } for _, testCase := range testCases { tg.kubePolicy.Spec.Ingress[tg.ingressIndex].Ports = testCase.ToPorts tg.romanaPolicy = &testCase.RomanaPolicy err := tg.makeNextRule(&translator) if err != nil { t.Errorf("%s", err) } if !testCase.expected(tg.romanaPolicy) { t.Errorf("Failed to translate romana policy %s", tg.romanaPolicy.Name) } } }