diff --git a/backend/service/k8s/deployment.go b/backend/service/k8s/deployment.go index 114224faf1..97cb61a94c 100644 --- a/backend/service/k8s/deployment.go +++ b/backend/service/k8s/deployment.go @@ -87,6 +87,62 @@ func ProtoForDeployment(cluster string, deployment *appsv1.Deployment) *k8sapiv1 return k8sDeployment } +func processObjProbe(objProbe *v1.Probe) *k8sapiv1.Probe { + HandlerObj := &k8sapiv1.Probe{} + + if objProbe.ProbeHandler.HTTPGet != nil { + ObjProbeHTTPHeaders := make([]*k8sapiv1.HTTPHeader, 0, len(objProbe.ProbeHandler.HTTPGet.HTTPHeaders)) + for _, value := range objProbe.ProbeHandler.HTTPGet.HTTPHeaders { + UniqueLivenessHeader := &k8sapiv1.HTTPHeader{ + Name: &value.Name, + Value: &value.Value, + } + ObjProbeHTTPHeaders = append(ObjProbeHTTPHeaders, UniqueLivenessHeader) + } + + ObjProbeHTTPObject := &k8sapiv1.HTTPGetAction{ + Path: objProbe.ProbeHandler.HTTPGet.Path, + Port: objProbe.ProbeHandler.HTTPGet.Port.IntVal, + Host: objProbe.ProbeHandler.HTTPGet.Host, + Scheme: string(objProbe.ProbeHandler.HTTPGet.Scheme), + HttpHeaders: ObjProbeHTTPHeaders, + } + HandlerObj.Handler = &k8sapiv1.Probe_HttpGet{ + HttpGet: ObjProbeHTTPObject, + } + } + + if objProbe.ProbeHandler.Exec != nil { + ObjProbeExec := &k8sapiv1.ExecAction{ + Command: objProbe.ProbeHandler.Exec.Command, + } + HandlerObj.Handler = &k8sapiv1.Probe_Exec{ + Exec: ObjProbeExec, + } + } + + if objProbe.ProbeHandler.TCPSocket != nil { + ObjProbeTCPSocket := &k8sapiv1.TCPSocketAction{ + Port: objProbe.ProbeHandler.TCPSocket.Port.IntVal, + Host: objProbe.ProbeHandler.TCPSocket.Host, + } + HandlerObj.Handler = &k8sapiv1.Probe_TcpSocket{ + TcpSocket: ObjProbeTCPSocket, + } + } + + if objProbe.ProbeHandler.GRPC != nil { + ObjProbeGRPC := &k8sapiv1.GRPCAction{ + Port: objProbe.ProbeHandler.GRPC.Port, + Service: *objProbe.ProbeHandler.GRPC.Service, + } + HandlerObj.Handler = &k8sapiv1.Probe_Grpc{ + Grpc: ObjProbeGRPC, + } + } + return HandlerObj +} + func ProtoForDeploymentSpec(deploymentSpec appsv1.DeploymentSpec) *k8sapiv1.Deployment_DeploymentSpec { deploymentContainers := make([]*k8sapiv1.Deployment_DeploymentSpec_PodTemplateSpec_PodSpec_Container, 0, len(deploymentSpec.Template.Spec.Containers)) for _, container := range deploymentSpec.Template.Spec.Containers { @@ -101,12 +157,44 @@ func ProtoForDeploymentSpec(deploymentSpec appsv1.DeploymentSpec) *k8sapiv1.Depl resourceRequests[string(res)] = quantity.String() } + LivenessProbeObject := &k8sapiv1.Probe{} + ReadinessProbeObject := &k8sapiv1.Probe{} + if container.LivenessProbe != nil { + HandlerObj := processObjProbe(container.LivenessProbe) + + LivenessProbeObject = &k8sapiv1.Probe{ + InitialDelaySeconds: &container.LivenessProbe.InitialDelaySeconds, + TimeoutSeconds: &container.LivenessProbe.TimeoutSeconds, + PeriodSeconds: &container.LivenessProbe.PeriodSeconds, + SuccessThreshold: &container.LivenessProbe.SuccessThreshold, + FailureThreshold: &container.LivenessProbe.FailureThreshold, + TerminationGracePeriodSeconds: container.LivenessProbe.TerminationGracePeriodSeconds, + Handler: HandlerObj.Handler, + } + } + + if container.ReadinessProbe != nil { + HandlerObj := processObjProbe(container.ReadinessProbe) + + ReadinessProbeObject = &k8sapiv1.Probe{ + InitialDelaySeconds: &container.ReadinessProbe.InitialDelaySeconds, + TimeoutSeconds: &container.ReadinessProbe.TimeoutSeconds, + PeriodSeconds: &container.ReadinessProbe.PeriodSeconds, + SuccessThreshold: &container.ReadinessProbe.SuccessThreshold, + FailureThreshold: &container.ReadinessProbe.FailureThreshold, + TerminationGracePeriodSeconds: container.ReadinessProbe.TerminationGracePeriodSeconds, + Handler: HandlerObj.Handler, + } + } + newContainer := &k8sapiv1.Deployment_DeploymentSpec_PodTemplateSpec_PodSpec_Container{ Name: container.Name, Resources: &k8sapiv1.Deployment_DeploymentSpec_PodTemplateSpec_PodSpec_Container_ResourceRequirements{ Limits: resourceLimits, Requests: resourceRequests, }, + LivenessProbe: LivenessProbeObject, + ReadinessProbe: ReadinessProbeObject, } deploymentContainers = append(deploymentContainers, newContainer) } @@ -179,6 +267,10 @@ func (s *svc) UpdateDeployment(ctx context.Context, clientset, cluster, namespac return err } + if err := updateContainerProbes(newDeployment, fields); err != nil { + return err + } + patchBytes, err := GenerateStrategicPatch(oldDeployment, newDeployment, appsv1.Deployment{}) if err != nil { return err @@ -236,3 +328,87 @@ func updateContainerResources(deployment *appsv1.Deployment, fields *k8sapiv1.Up } return nil } + +func setOptionalInt64Value(source *int64, target *int64) { + if source != nil { + *target = *source + } +} + +func setOptionalValue(source *int32, target *int32) { + if source != nil { + *target = *source + } +} + +func updateContainerProbes(deployment *appsv1.Deployment, fields *k8sapiv1.UpdateDeploymentRequest_Fields) error { + for _, containerProbes := range fields.ContainerProbes { + for _, container := range deployment.Spec.Template.Spec.Containers { + if container.Name == containerProbes.ContainerName { + if containerProbes.LivenessProbe != nil { + resourceProbe := containerProbes.LivenessProbe + setOptionalValue(resourceProbe.InitialDelaySeconds, &container.LivenessProbe.InitialDelaySeconds) + setOptionalValue(resourceProbe.PeriodSeconds, &container.LivenessProbe.PeriodSeconds) + setOptionalValue(resourceProbe.TimeoutSeconds, &container.LivenessProbe.TimeoutSeconds) + setOptionalValue(resourceProbe.SuccessThreshold, &container.LivenessProbe.SuccessThreshold) + setOptionalValue(resourceProbe.FailureThreshold, &container.LivenessProbe.FailureThreshold) + setOptionalInt64Value(resourceProbe.TerminationGracePeriodSeconds, container.LivenessProbe.TerminationGracePeriodSeconds) + if handler := resourceProbe.Handler; handler != nil { + switch resourceProbe.Handler.(type) { + case *k8sapiv1.Probe_Exec: + container.LivenessProbe.ProbeHandler.Exec.Command = resourceProbe.GetExec().Command + case *k8sapiv1.Probe_Grpc: + container.LivenessProbe.ProbeHandler.GRPC.Port = resourceProbe.GetGrpc().Port + container.LivenessProbe.ProbeHandler.GRPC.Service = &resourceProbe.GetGrpc().Service + case *k8sapiv1.Probe_TcpSocket: + container.LivenessProbe.ProbeHandler.TCPSocket.Port.IntVal = resourceProbe.GetTcpSocket().Port + container.LivenessProbe.ProbeHandler.TCPSocket.Host = resourceProbe.GetTcpSocket().Host + case *k8sapiv1.Probe_HttpGet: + container.LivenessProbe.ProbeHandler.HTTPGet.Host = resourceProbe.GetHttpGet().Host + container.LivenessProbe.ProbeHandler.HTTPGet.Path = resourceProbe.GetHttpGet().Path + container.LivenessProbe.ProbeHandler.HTTPGet.Port.IntVal = resourceProbe.GetHttpGet().Port + container.LivenessProbe.ProbeHandler.HTTPGet.Scheme = (v1.URIScheme)(resourceProbe.GetHttpGet().Scheme) + LivenessProbeHTTPHeaders := make([]v1.HTTPHeader, 0, len(resourceProbe.GetHttpGet().HttpHeaders)) + for _, value := range resourceProbe.GetHttpGet().HttpHeaders { + UniqueLivenessHeader := v1.HTTPHeader{ + Name: *value.Name, + Value: *value.Value, + } + LivenessProbeHTTPHeaders = append(LivenessProbeHTTPHeaders, UniqueLivenessHeader) + } + container.LivenessProbe.ProbeHandler.HTTPGet.HTTPHeaders = LivenessProbeHTTPHeaders + } + } + } + if containerProbes.ReadinessProbe == nil { + return nil + } + resourceReadinessProbe := containerProbes.ReadinessProbe + setOptionalValue(resourceReadinessProbe.InitialDelaySeconds, &container.ReadinessProbe.InitialDelaySeconds) + setOptionalValue(resourceReadinessProbe.PeriodSeconds, &container.ReadinessProbe.PeriodSeconds) + setOptionalValue(resourceReadinessProbe.TimeoutSeconds, &container.ReadinessProbe.TimeoutSeconds) + setOptionalValue(resourceReadinessProbe.SuccessThreshold, &container.ReadinessProbe.SuccessThreshold) + setOptionalValue(resourceReadinessProbe.FailureThreshold, &container.ReadinessProbe.FailureThreshold) + setOptionalInt64Value(resourceReadinessProbe.TerminationGracePeriodSeconds, container.ReadinessProbe.TerminationGracePeriodSeconds) + if handler := resourceReadinessProbe.Handler; handler != nil { + switch resourceReadinessProbe.Handler.(type) { + case *k8sapiv1.Probe_Exec: + container.ReadinessProbe.ProbeHandler.Exec.Command = resourceReadinessProbe.GetExec().Command + case *k8sapiv1.Probe_Grpc: + container.ReadinessProbe.ProbeHandler.GRPC.Port = resourceReadinessProbe.GetGrpc().Port + container.ReadinessProbe.ProbeHandler.GRPC.Service = &resourceReadinessProbe.GetGrpc().Service + case *k8sapiv1.Probe_TcpSocket: + container.ReadinessProbe.ProbeHandler.TCPSocket.Port.IntVal = resourceReadinessProbe.GetTcpSocket().Port + container.ReadinessProbe.ProbeHandler.TCPSocket.Host = resourceReadinessProbe.GetTcpSocket().Host + case *k8sapiv1.Probe_HttpGet: + container.ReadinessProbe.ProbeHandler.HTTPGet.Host = resourceReadinessProbe.GetHttpGet().Host + container.ReadinessProbe.ProbeHandler.HTTPGet.Path = resourceReadinessProbe.GetHttpGet().Path + container.ReadinessProbe.ProbeHandler.HTTPGet.Port.IntVal = resourceReadinessProbe.GetHttpGet().Port + container.ReadinessProbe.ProbeHandler.HTTPGet.Scheme = (v1.URIScheme)(resourceReadinessProbe.GetHttpGet().Scheme) + } + } + } + } + } + return nil +} diff --git a/backend/service/k8s/deployment_test.go b/backend/service/k8s/deployment_test.go index 19700335aa..b79747733e 100644 --- a/backend/service/k8s/deployment_test.go +++ b/backend/service/k8s/deployment_test.go @@ -10,6 +10,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" k8s "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/fake" @@ -364,3 +365,481 @@ func TestProtoForDeploymentStatus(t *testing.T) { }) } } + +func TestProtoForDeploymentSpecWithProbesLivenessHTTPGet(t *testing.T) { + t.Parallel() + var terminationVar int64 = 30 + var deploymentTestCase = &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + LivenessProbe: &v1.Probe{ + ProbeHandler: v1.ProbeHandler{ + HTTPGet: &v1.HTTPGetAction{ + Path: "/", + Port: intstr.IntOrString{ + IntVal: 8080, + }, + }, + }, + InitialDelaySeconds: 10, + PeriodSeconds: 30, + TimeoutSeconds: 1, + SuccessThreshold: 1, + FailureThreshold: 3, + TerminationGracePeriodSeconds: &terminationVar, + }, + }, + }, + }, + }, + }, + } + + t.Run("LivenessProbeHttpGetAction", func(t *testing.T) { + t.Parallel() + deployment := ProtoForDeployment("", deploymentTestCase) + assert.Equal(t, deploymentTestCase.Spec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds) + assert.Equal(t, deploymentTestCase.Spec.Template.Spec.Containers[0].LivenessProbe.PeriodSeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].LivenessProbe.PeriodSeconds) + + err := updateContainerProbes(deploymentTestCase, &k8sapiv1.UpdateDeploymentRequest_Fields{}) + assert.NoError(t, err) + err = updateContainerProbes(deploymentTestCase, &k8sapiv1.UpdateDeploymentRequest_Fields{ + ContainerProbes: []*k8sapiv1.UpdateDeploymentRequest_Fields_ContainerProbes{ + { + LivenessProbe: &k8sapiv1.Probe{ + Handler: &k8sapiv1.Probe_HttpGet{ + HttpGet: &k8sapiv1.HTTPGetAction{ + Port: 8081, + }, + }, + InitialDelaySeconds: newInt32(20), + PeriodSeconds: newInt32(15), + }, + }, + }, + }) + assert.NoError(t, err) + }) +} + +func TestProtoForDeploymentSpecWithProbesLivenessExec(t *testing.T) { + t.Parallel() + var terminationVar int64 = 30 + var deploymentTestCases = &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + LivenessProbe: &v1.Probe{ + ProbeHandler: v1.ProbeHandler{ + Exec: &v1.ExecAction{ + Command: []string{"ls", "-l"}, + }, + }, + InitialDelaySeconds: 5, + PeriodSeconds: 25, + TimeoutSeconds: 5, + SuccessThreshold: 4, + FailureThreshold: 8, + TerminationGracePeriodSeconds: &terminationVar, + }, + }, + }, + }, + }, + }, + } + + t.Run("LivenessProbeExecAction", func(t *testing.T) { + t.Parallel() + deployment := ProtoForDeployment("", deploymentTestCases) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].LivenessProbe.PeriodSeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].LivenessProbe.PeriodSeconds) + + err := updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{}) + assert.NoError(t, err) + err = updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{ + ContainerProbes: []*k8sapiv1.UpdateDeploymentRequest_Fields_ContainerProbes{ + { + LivenessProbe: &k8sapiv1.Probe{ + Handler: &k8sapiv1.Probe_Exec{ + Exec: &k8sapiv1.ExecAction{ + Command: []string{"ps"}, + }, + }, + InitialDelaySeconds: newInt32(20), + PeriodSeconds: newInt32(15), + }, + }, + }, + }) + assert.NoError(t, err) + }) +} + +func TestProtoForDeploymentSpecWithProbesLivenessTCP(t *testing.T) { + t.Parallel() + var terminationVar int64 = 30 + var deploymentTestCases = &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + LivenessProbe: &v1.Probe{ + ProbeHandler: v1.ProbeHandler{ + TCPSocket: &v1.TCPSocketAction{ + Port: intstr.IntOrString{ + IntVal: 8080, + }, + Host: "/", + }, + }, + InitialDelaySeconds: 6, + PeriodSeconds: 26, + TimeoutSeconds: 6, + SuccessThreshold: 10, + FailureThreshold: 9, + TerminationGracePeriodSeconds: &terminationVar, + }, + }, + }, + }, + }, + }, + } + + t.Run("LivenessProbeTCPAction", func(t *testing.T) { + t.Parallel() + deployment := ProtoForDeployment("", deploymentTestCases) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].LivenessProbe.PeriodSeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].LivenessProbe.PeriodSeconds) + + err := updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{}) + assert.NoError(t, err) + err = updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{ + ContainerProbes: []*k8sapiv1.UpdateDeploymentRequest_Fields_ContainerProbes{ + { + LivenessProbe: &k8sapiv1.Probe{ + Handler: &k8sapiv1.Probe_TcpSocket{ + TcpSocket: &k8sapiv1.TCPSocketAction{ + Port: 8081, + }, + }, + InitialDelaySeconds: newInt32(20), + PeriodSeconds: newInt32(15), + }, + }, + }, + }) + assert.NoError(t, err) + }) +} + +func TestProtoForDeploymentSpecWithProbesLivenessGRPC(t *testing.T) { + t.Parallel() + var terminationVar int64 = 30 + var portGRPC int32 = 8080 + var serviceGRPC string = "service" + var deploymentTestCases = &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + LivenessProbe: &v1.Probe{ + ProbeHandler: v1.ProbeHandler{ + GRPC: &v1.GRPCAction{ + Port: portGRPC, + Service: &serviceGRPC, + }, + }, + InitialDelaySeconds: 4, + PeriodSeconds: 24, + TimeoutSeconds: 2, + SuccessThreshold: 4, + FailureThreshold: 5, + TerminationGracePeriodSeconds: &terminationVar, + }, + }, + }, + }, + }, + }, + } + + t.Run("LivenessProbeGRPCAction", func(t *testing.T) { + t.Parallel() + deployment := ProtoForDeployment("", deploymentTestCases) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].LivenessProbe.PeriodSeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].LivenessProbe.PeriodSeconds) + + err := updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{}) + assert.NoError(t, err) + err = updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{ + ContainerProbes: []*k8sapiv1.UpdateDeploymentRequest_Fields_ContainerProbes{ + { + LivenessProbe: &k8sapiv1.Probe{ + Handler: &k8sapiv1.Probe_Grpc{ + Grpc: &k8sapiv1.GRPCAction{ + Service: "tmp", + }, + }, + InitialDelaySeconds: newInt32(20), + PeriodSeconds: newInt32(15), + }, + }, + }, + }) + assert.NoError(t, err) + }) +} + +func TestProtoForDeploymentSpecWithProbesReadinessHTTPGet(t *testing.T) { + t.Parallel() + var terminationVar int64 = 30 + var deploymentTestCases = &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + ReadinessProbe: &v1.Probe{ + ProbeHandler: v1.ProbeHandler{ + HTTPGet: &v1.HTTPGetAction{ + Path: "/", + Port: intstr.IntOrString{ + IntVal: 8080, + }, + }, + }, + InitialDelaySeconds: 10, + PeriodSeconds: 30, + TimeoutSeconds: 1, + SuccessThreshold: 1, + FailureThreshold: 3, + TerminationGracePeriodSeconds: &terminationVar, + }, + }, + }, + }, + }, + }, + } + + t.Run("ReadinessProbeHttpGetAction", func(t *testing.T) { + t.Parallel() + deployment := ProtoForDeployment("", deploymentTestCases) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe.InitialDelaySeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].ReadinessProbe.InitialDelaySeconds) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe.PeriodSeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].ReadinessProbe.PeriodSeconds) + + probeDeployment := processObjProbe(deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe.HTTPGet.Host, probeDeployment.GetHttpGet().Host) + + err := updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{}) + assert.NoError(t, err) + err = updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{ + ContainerProbes: []*k8sapiv1.UpdateDeploymentRequest_Fields_ContainerProbes{ + { + ReadinessProbe: &k8sapiv1.Probe{ + Handler: &k8sapiv1.Probe_HttpGet{ + HttpGet: &k8sapiv1.HTTPGetAction{ + Host: "/test", + }, + }, + InitialDelaySeconds: newInt32(20), + PeriodSeconds: newInt32(15), + }, + }, + }, + }) + assert.NoError(t, err) + }) +} + +func TestProtoForDeploymentSpecWithProbesReadinessExec(t *testing.T) { + t.Parallel() + var terminationVar int64 = 30 + var deploymentTestCases = &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + ReadinessProbe: &v1.Probe{ + ProbeHandler: v1.ProbeHandler{ + Exec: &v1.ExecAction{ + Command: []string{"ls", "-l"}, + }, + }, + InitialDelaySeconds: 5, + PeriodSeconds: 25, + TimeoutSeconds: 5, + SuccessThreshold: 4, + FailureThreshold: 8, + TerminationGracePeriodSeconds: &terminationVar, + }, + }, + }, + }, + }, + }, + } + + t.Run("ReadinessProbeExecAction", func(t *testing.T) { + t.Parallel() + deployment := ProtoForDeployment("", deploymentTestCases) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe.InitialDelaySeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].ReadinessProbe.InitialDelaySeconds) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe.PeriodSeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].ReadinessProbe.PeriodSeconds) + + probeDeployment := processObjProbe(deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe.Exec.Command, probeDeployment.GetExec().Command) + + err := updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{}) + assert.NoError(t, err) + err = updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{ + ContainerProbes: []*k8sapiv1.UpdateDeploymentRequest_Fields_ContainerProbes{ + { + ReadinessProbe: &k8sapiv1.Probe{ + Handler: &k8sapiv1.Probe_Exec{ + Exec: &k8sapiv1.ExecAction{ + Command: []string{"pwd"}, + }, + }, + InitialDelaySeconds: newInt32(20), + PeriodSeconds: newInt32(15), + }, + }, + }, + }) + assert.NoError(t, err) + }) +} + +func TestProtoForDeploymentSpecWithProbesReadinessTCP(t *testing.T) { + t.Parallel() + var terminationVar int64 = 30 + var deploymentTestCases = &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + ReadinessProbe: &v1.Probe{ + ProbeHandler: v1.ProbeHandler{ + TCPSocket: &v1.TCPSocketAction{ + Port: intstr.IntOrString{ + IntVal: 8080, + }, + Host: "/", + }, + }, + InitialDelaySeconds: 6, + PeriodSeconds: 26, + TimeoutSeconds: 6, + SuccessThreshold: 10, + FailureThreshold: 9, + TerminationGracePeriodSeconds: &terminationVar, + }, + }, + }, + }, + }, + }, + } + + t.Run("ReadinessProbeTCPAction", func(t *testing.T) { + t.Parallel() + deployment := ProtoForDeployment("", deploymentTestCases) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe.InitialDelaySeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].ReadinessProbe.InitialDelaySeconds) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe.PeriodSeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].ReadinessProbe.PeriodSeconds) + + probeDeployment := processObjProbe(deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe.TCPSocket.Host, probeDeployment.GetTcpSocket().Host) + + err := updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{}) + assert.NoError(t, err) + err = updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{ + ContainerProbes: []*k8sapiv1.UpdateDeploymentRequest_Fields_ContainerProbes{ + { + ReadinessProbe: &k8sapiv1.Probe{ + Handler: &k8sapiv1.Probe_TcpSocket{ + TcpSocket: &k8sapiv1.TCPSocketAction{ + Host: "/test", + }, + }, + InitialDelaySeconds: newInt32(20), + PeriodSeconds: newInt32(15), + }, + }, + }, + }) + assert.NoError(t, err) + }) +} + +func TestProtoForDeploymentSpecWithProbesReadinessGRPC(t *testing.T) { + t.Parallel() + var terminationVar int64 = 30 + var portGRPC int32 = 8080 + var serviceGRPC string = "service" + var deploymentTestCases = &appsv1.Deployment{ + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + ReadinessProbe: &v1.Probe{ + ProbeHandler: v1.ProbeHandler{ + GRPC: &v1.GRPCAction{ + Port: portGRPC, + Service: &serviceGRPC, + }, + }, + InitialDelaySeconds: 4, + PeriodSeconds: 24, + TimeoutSeconds: 2, + SuccessThreshold: 4, + FailureThreshold: 5, + TerminationGracePeriodSeconds: &terminationVar, + }, + }, + }, + }, + }, + }, + } + + t.Run("ReadinessProbeGRPCAction", func(t *testing.T) { + t.Parallel() + deployment := ProtoForDeployment("", deploymentTestCases) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe.InitialDelaySeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].ReadinessProbe.InitialDelaySeconds) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe.PeriodSeconds, *deployment.DeploymentSpec.Template.Spec.Containers[0].ReadinessProbe.PeriodSeconds) + + probeDeployment := processObjProbe(deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe) + assert.Equal(t, deploymentTestCases.Spec.Template.Spec.Containers[0].ReadinessProbe.GRPC.Port, probeDeployment.GetGrpc().Port) + + err := updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{}) + assert.NoError(t, err) + err = updateContainerProbes(deploymentTestCases, &k8sapiv1.UpdateDeploymentRequest_Fields{ + ContainerProbes: []*k8sapiv1.UpdateDeploymentRequest_Fields_ContainerProbes{ + { + ReadinessProbe: &k8sapiv1.Probe{ + Handler: &k8sapiv1.Probe_Grpc{ + Grpc: &k8sapiv1.GRPCAction{ + Service: "tmp", + }, + }, + InitialDelaySeconds: newInt32(20), + PeriodSeconds: newInt32(15), + }, + }, + }, + }) + assert.NoError(t, err) + }) +}