From 24e8adfb00b0bfb419474785901c86a2cfdae7d8 Mon Sep 17 00:00:00 2001 From: Veronika Fisarova Date: Fri, 29 Sep 2023 12:39:50 +0200 Subject: [PATCH] General HTTP/HTTPS probes support Introduce a new package to handle liveness and readiness probes. Allow user configuration for port and toggle between HTTP/HTTPS. Signed-off-by: Veronika Fisarova --- modules/common/probes/probes.go | 81 ++++++++++++++++++++++++++++ modules/common/probes/probes_test.go | 78 +++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 modules/common/probes/probes.go create mode 100644 modules/common/probes/probes_test.go diff --git a/modules/common/probes/probes.go b/modules/common/probes/probes.go new file mode 100644 index 00000000..7928864a --- /dev/null +++ b/modules/common/probes/probes.go @@ -0,0 +1,81 @@ +/* +Copyright 2023 Red Hat + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package probes + +import ( + "fmt" + + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +// ProbeConfig - the configuration for liveness and readiness probes +// LivenessPath - Endpoint path for the liveness probe +// ReadinessPath - Endpoint path for the readiness probe +// InitialDelaySeconds - Number of seconds after the container starts before liveness/readiness probes are initiated +// TimeoutSeconds - Number of seconds after which the probe times out +// PeriodSeconds - How often (in seconds) to perform the probe +type ProbeConfig struct { + LivenessPath string + ReadinessPath string + InitialDelaySeconds int32 + TimeoutSeconds int32 + PeriodSeconds int32 +} + +// SetProbes - configures and returns liveness and readiness probes based on the provided settings +func SetProbes(port int, disableNonTLSListeners bool, config ProbeConfig) (*v1.Probe, *v1.Probe, error) { + + if port < 1 || port > 65535 { + return nil, nil, fmt.Errorf("invalid port: %d", port) + } + + var scheme v1.URIScheme + if disableNonTLSListeners { + scheme = v1.URISchemeHTTPS + } else { + scheme = v1.URISchemeHTTP + } + + livenessProbe := &v1.Probe{ + ProbeHandler: v1.ProbeHandler{ + HTTPGet: &v1.HTTPGetAction{ + Path: config.LivenessPath, + Port: intstr.FromInt(port), + Scheme: scheme, + }, + }, + InitialDelaySeconds: config.InitialDelaySeconds, + TimeoutSeconds: config.TimeoutSeconds, + PeriodSeconds: config.PeriodSeconds, + } + + readinessProbe := &v1.Probe{ + ProbeHandler: v1.ProbeHandler{ + HTTPGet: &v1.HTTPGetAction{ + Path: config.ReadinessPath, + Port: intstr.FromInt(port), + Scheme: scheme, + }, + }, + InitialDelaySeconds: config.InitialDelaySeconds, + TimeoutSeconds: config.TimeoutSeconds, + PeriodSeconds: config.PeriodSeconds, + } + + return livenessProbe, readinessProbe, nil +} diff --git a/modules/common/probes/probes_test.go b/modules/common/probes/probes_test.go new file mode 100644 index 00000000..ccf41b97 --- /dev/null +++ b/modules/common/probes/probes_test.go @@ -0,0 +1,78 @@ +/* +Copyright 2023 Red Hat + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package probes + +import ( + "testing" + + v1 "k8s.io/api/core/v1" +) + +func TestSetProbes(t *testing.T) { + tests := []struct { + name string + port int + disable bool + wantURI v1.URIScheme + wantErr bool + }{ + { + name: "Disable NonTLS Listeners", + port: 8080, + disable: true, + wantURI: v1.URISchemeHTTPS, + }, + { + name: "Enable NonTLS Listeners", + port: 8080, + disable: false, + wantURI: v1.URISchemeHTTP, + }, + { + name: "Negative Port", + port: -8080, + disable: false, + wantErr: true, + }, + { + name: "Port Larger than 65535", + port: 70000, + disable: false, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + liveness, _, err := SetProbes(tt.port, tt.disable, ProbeConfig{}) + + if tt.wantErr { + if err == nil { + t.Errorf("SetProbes() expected error but got none") + } + return + } else if err != nil { + t.Errorf("SetProbes() unexpected error: %v", err) + return + } + // Only check the liveness probe if there was no error + if liveness.HTTPGet.Scheme != tt.wantURI { + t.Errorf("SetProbes() got = %v, want %v", liveness.HTTPGet.Scheme, tt.wantURI) + } + }) + } +}