From 6faab8eb769d3f3d3d08fa888a0aa964e1472cfd Mon Sep 17 00:00:00 2001 From: Tuna Date: Wed, 3 Jan 2018 11:30:46 +0700 Subject: [PATCH] use default svcSpec if it doesn't present in function spec --- pkg/utils/k8sutil.go | 38 +++++++++++++++++++++++++---- pkg/utils/k8sutil_test.go | 50 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/pkg/utils/k8sutil.go b/pkg/utils/k8sutil.go index e24448dab..1a896137c 100644 --- a/pkg/utils/k8sutil.go +++ b/pkg/utils/k8sutil.go @@ -549,6 +549,27 @@ func EnsureFuncConfigMap(client kubernetes.Interface, funcObj *spec.Function, or return err } +// this function resolves backward incompatibility in case user uses old client which doesn't include serviceSpec into funcSpec. +// if serviceSpec is empty, we will use the default serviceSpec whose port is 8080 +func serviceSpec(funcObj *spec.Function) v1.ServiceSpec { + if len(funcObj.Spec.ServiceSpec.Ports) != 0 && len(funcObj.Spec.ServiceSpec.Selector) != 0 { + return funcObj.Spec.ServiceSpec + } + + return v1.ServiceSpec{ + Ports: []v1.ServicePort{ + { + Name: "function-port", + Protocol: v1.ProtocolTCP, + Port: 8080, + TargetPort: intstr.FromInt(8080), + }, + }, + Selector: funcObj.Metadata.Labels, + Type: v1.ServiceTypeClusterIP, + } +} + // EnsureFuncService creates/updates a function service func EnsureFuncService(client kubernetes.Interface, funcObj *spec.Function, or []metav1.OwnerReference) error { svc := &v1.Service{ @@ -557,7 +578,7 @@ func EnsureFuncService(client kubernetes.Interface, funcObj *spec.Function, or [ Labels: funcObj.Metadata.Labels, OwnerReferences: or, }, - Spec: funcObj.Spec.ServiceSpec, + Spec: serviceSpec(funcObj), } _, err := client.Core().Services(funcObj.Metadata.Namespace).Create(svc) @@ -582,6 +603,13 @@ func EnsureFuncService(client kubernetes.Interface, funcObj *spec.Function, or [ return err } +func svcPort(funcObj *spec.Function) int32 { + if len(funcObj.Spec.ServiceSpec.Ports) != 0 { + return funcObj.Spec.ServiceSpec.Ports[0].Port + } + return int32(8080) +} + // EnsureFuncDeployment creates/updates a function deployment func EnsureFuncDeployment(client kubernetes.Interface, funcObj *spec.Function, or []metav1.OwnerReference) error { runtimeVolumeName := funcObj.Metadata.Name @@ -594,7 +622,7 @@ func EnsureFuncDeployment(client kubernetes.Interface, funcObj *spec.Function, o // "targets") "prometheus.io/scrape": "true", "prometheus.io/path": "/metrics", - "prometheus.io/port": strconv.Itoa(int(funcObj.Spec.ServiceSpec.Ports[0].Port)), + "prometheus.io/port": strconv.Itoa(int(svcPort(funcObj))), } //add deployment @@ -697,13 +725,13 @@ func EnsureFuncDeployment(client kubernetes.Interface, funcObj *spec.Function, o dpm.Spec.Template.Spec.Containers[0].Env = append(dpm.Spec.Template.Spec.Containers[0].Env, v1.EnvVar{ Name: "FUNC_PORT", - Value: strconv.Itoa(int(funcObj.Spec.ServiceSpec.Ports[0].Port)), + Value: strconv.Itoa(int(svcPort(funcObj))), }, ) dpm.Spec.Template.Spec.Containers[0].Name = funcObj.Metadata.Name dpm.Spec.Template.Spec.Containers[0].Ports = append(dpm.Spec.Template.Spec.Containers[0].Ports, v1.ContainerPort{ - ContainerPort: funcObj.Spec.ServiceSpec.Ports[0].Port, + ContainerPort: svcPort(funcObj), }) dpm.Spec.Template.Spec.Containers[0].Env = append(dpm.Spec.Template.Spec.Containers[0].Env, v1.EnvVar{ @@ -773,7 +801,7 @@ func EnsureFuncDeployment(client kubernetes.Interface, funcObj *spec.Function, o Handler: v1.Handler{ HTTPGet: &v1.HTTPGetAction{ Path: "/healthz", - Port: intstr.FromInt(int(funcObj.Spec.ServiceSpec.Ports[0].Port)), + Port: intstr.FromInt(int(svcPort(funcObj))), }, }, } diff --git a/pkg/utils/k8sutil_test.go b/pkg/utils/k8sutil_test.go index a0c92e00e..70dfa5904 100644 --- a/pkg/utils/k8sutil_test.go +++ b/pkg/utils/k8sutil_test.go @@ -918,3 +918,53 @@ func TestGetProvisionContainer(t *testing.T) { } } + +func TestServiceSpec(t *testing.T) { + f1 := &spec.Function{ + Metadata: metav1.ObjectMeta{ + Name: "foo", + Namespace: "myns", + Labels: map[string]string{ + "function": "foo", + }, + }, + Spec: spec.FunctionSpec{ + ServiceSpec: v1.ServiceSpec{ + Ports: []v1.ServicePort{ + { + TargetPort: intstr.FromInt(9000), + }, + }, + Selector: map[string]string{ + "function": "foo", + }, + }, + }, + } + + eSvc := v1.ServiceSpec{ + Ports: []v1.ServicePort{ + { + Name: "function-port", + Protocol: v1.ProtocolTCP, + Port: 8080, + TargetPort: intstr.FromInt(8080), + }, + }, + Selector: map[string]string{ + "function": "foo", + }, + Type: v1.ServiceTypeClusterIP, + } + + aSvc := serviceSpec(f1) + if !reflect.DeepEqual(f1.Spec.ServiceSpec, aSvc) { + t.Errorf("Unexpected result:\n %+v", aSvc) + } + + f1.Spec.ServiceSpec = v1.ServiceSpec{} + aSvc = serviceSpec(f1) + if !reflect.DeepEqual(aSvc, eSvc) { + t.Errorf("Unexpected result:\n %+v", aSvc) + } +}