Skip to content

Commit

Permalink
replace k8s types with radix, add pointers where optional
Browse files Browse the repository at this point in the history
  • Loading branch information
Richard87 committed Dec 4, 2024
1 parent b117b4b commit d22b56c
Show file tree
Hide file tree
Showing 15 changed files with 940 additions and 600 deletions.
414 changes: 177 additions & 237 deletions charts/radix-operator/templates/radixapplication.yaml

Large diffs are not rendered by default.

204 changes: 84 additions & 120 deletions charts/radix-operator/templates/radixdeployment.yaml

Large diffs are not rendered by default.

354 changes: 174 additions & 180 deletions json-schema/radixapplication.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions pkg/apis/deployment/kubedeployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,9 @@ func (deploy *Deployment) setDesiredDeploymentProperties(ctx context.Context, de
desiredDeployment.Spec.Template.Spec.Containers[0].VolumeMounts = volumeMounts

if hc := deployComponent.GetHealthChecks(); hc != nil {
desiredDeployment.Spec.Template.Spec.Containers[0].ReadinessProbe = hc.ReadinessProbe
desiredDeployment.Spec.Template.Spec.Containers[0].LivenessProbe = hc.LivenessProbe
desiredDeployment.Spec.Template.Spec.Containers[0].StartupProbe = hc.StartupProbe
desiredDeployment.Spec.Template.Spec.Containers[0].ReadinessProbe = hc.ReadinessProbe.MapToCoreProbe()
desiredDeployment.Spec.Template.Spec.Containers[0].LivenessProbe = hc.LivenessProbe.MapToCoreProbe()
desiredDeployment.Spec.Template.Spec.Containers[0].StartupProbe = hc.StartupProbe.MapToCoreProbe()
} else {
readinessProbe, err := getDefaultReadinessProbeForComponent(deployComponent)
if err != nil {
Expand Down
30 changes: 14 additions & 16 deletions pkg/apis/deployment/kubedeployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import (
"github.com/equinor/radix-operator/pkg/apis/utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)

func teardownReadinessProbe() {
Expand Down Expand Up @@ -56,26 +54,26 @@ func TestComponentWithoutCustomHealthChecks(t *testing.T) {
}
func TestComponentWithCustomHealthChecks(t *testing.T) {
tu, client, kubeUtil, radixclient, kedaClient, prometheusclient, _, certClient := SetupTest(t)
createProbe := func(handler corev1.ProbeHandler, seconds int32) *corev1.Probe {
return &corev1.Probe{
ProbeHandler: handler,
InitialDelaySeconds: seconds,
TimeoutSeconds: seconds + 1,
PeriodSeconds: seconds + 2,
SuccessThreshold: seconds + 3,
FailureThreshold: seconds + 4,
TerminationGracePeriodSeconds: pointers.Ptr(int64(seconds + 5)),
createProbe := func(handler v1.RadixProbeHandler, seconds int32) *v1.RadixProbe {
return &v1.RadixProbe{
RadixProbeHandler: handler,
InitialDelaySeconds: pointers.Ptr(seconds),
TimeoutSeconds: pointers.Ptr(seconds + 1),
PeriodSeconds: pointers.Ptr(seconds + 2),
SuccessThreshold: pointers.Ptr(seconds + 3),
FailureThreshold: pointers.Ptr(seconds + 4),
// TerminationGracePeriodSeconds: pointers.Ptr(int64(seconds + 5)),
}
}

readynessProbe := createProbe(corev1.ProbeHandler{HTTPGet: &corev1.HTTPGetAction{
Port: intstr.IntOrString{IntVal: 5000},
readynessProbe := createProbe(v1.RadixProbeHandler{HTTPGet: &v1.RadixProbeHTTPGetAction{
Port: pointers.Ptr[int32](5000),
}}, 10)

livenessProbe := createProbe(corev1.ProbeHandler{TCPSocket: &corev1.TCPSocketAction{
Port: intstr.IntOrString{IntVal: 5000},
livenessProbe := createProbe(v1.RadixProbeHandler{TCPSocket: &v1.RadixProbeTCPSocketAction{
Port: pointers.Ptr[int32](5000),
}}, 20)
startuProbe := createProbe(corev1.ProbeHandler{Exec: &corev1.ExecAction{
startuProbe := createProbe(v1.RadixProbeHandler{Exec: &v1.RadixProbeExecAction{
Command: []string{"echo", "hello"},
}}, 30)

Expand Down
25 changes: 12 additions & 13 deletions pkg/apis/deployment/radixcomponent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
storagev1 "k8s.io/api/storage/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)

type scenarioDef struct {
Expand Down Expand Up @@ -1050,21 +1049,21 @@ func Test_GetRadixComponents_Monitoring(t *testing.T) {
}

func Test_GetRadixComponents_CustomHealthChecks(t *testing.T) {
createProbe := func(handler corev1.ProbeHandler, seconds int32) *corev1.Probe {
return &corev1.Probe{
ProbeHandler: handler,
InitialDelaySeconds: seconds,
TimeoutSeconds: seconds + 1,
PeriodSeconds: seconds + 2,
SuccessThreshold: seconds + 3,
FailureThreshold: seconds + 4,
TerminationGracePeriodSeconds: pointers.Ptr(int64(seconds + 5)),
createProbe := func(handler radixv1.RadixProbeHandler, seconds int32) *radixv1.RadixProbe {
return &radixv1.RadixProbe{
RadixProbeHandler: handler,
InitialDelaySeconds: &seconds,
TimeoutSeconds: pointers.Ptr(seconds + 1),
PeriodSeconds: pointers.Ptr(seconds + 2),
SuccessThreshold: pointers.Ptr(seconds + 3),
FailureThreshold: pointers.Ptr(seconds + 4),
// TerminationGracePeriodSeconds: pointers.Ptr(int64(seconds + 5)),
}
}

httpProbe := corev1.ProbeHandler{HTTPGet: &corev1.HTTPGetAction{Port: intstr.FromInt32(5000), Path: "/healthz", Scheme: "http"}}
execProbe := corev1.ProbeHandler{Exec: &corev1.ExecAction{Command: []string{"/bin/sh", "-c", "/healthz /healthz"}}}
tcpProbe := corev1.ProbeHandler{TCPSocket: &corev1.TCPSocketAction{Port: intstr.FromInt32(8000)}}
httpProbe := radixv1.RadixProbeHandler{HTTPGet: &radixv1.RadixProbeHTTPGetAction{Port: pointers.Ptr[int32](5000), Path: pointers.Ptr("/healthz"), Scheme: pointers.Ptr(corev1.URISchemeHTTP)}}
execProbe := radixv1.RadixProbeHandler{Exec: &radixv1.RadixProbeExecAction{Command: []string{"/bin/sh", "-c", "/healthz /healthz"}}}
tcpProbe := radixv1.RadixProbeHandler{TCPSocket: &radixv1.RadixProbeTCPSocketAction{Port: pointers.Ptr[int32](8000)}}

testCases := []struct {
description string
Expand Down
7 changes: 3 additions & 4 deletions pkg/apis/radix/v1/radixapptypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"strings"

commonUtils "github.com/equinor/radix-common/utils"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
Expand Down Expand Up @@ -821,21 +820,21 @@ type RadixHealthChecks struct {
// Container will be restarted if the probe fails.
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
// +optional
LivenessProbe *v1.Probe `json:"livenessProbe,omitempty"`
LivenessProbe *RadixProbe `json:"livenessProbe,omitempty"`
// Periodic probe of container service readiness.
// Container will be removed from service endpoints if the probe fails.
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
// Defaults to TCP Probe against the first listed port
// +optional
ReadinessProbe *v1.Probe `json:"readinessProbe,omitempty"`
ReadinessProbe *RadixProbe `json:"readinessProbe,omitempty"`
// StartupProbe indicates that the Pod has successfully initialized.
// If specified, no other probes are executed until this completes successfully.
// If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
// This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
// when it might take a long time to load data or warm a cache, than during steady-state operation.
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
// +optional
StartupProbe *v1.Probe `json:"startupProbe,omitempty"`
StartupProbe *RadixProbe `json:"startupProbe,omitempty"`
}

// PrivateImageHubEntries defines authentication information for private image registries.
Expand Down
209 changes: 209 additions & 0 deletions pkg/apis/radix/v1/radixhealthchecktypes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
package v1

import (
"github.com/equinor/radix-common/utils/pointers"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)

// RadixProbe describes a health check to be performed against a container to determine whether it is
// alive or ready to receive traffic.
type RadixProbe struct {
// The action taken to determine the health of a container
RadixProbeHandler `json:",inline"`
// Number of seconds after the container has started before liveness probes are initiated.
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
// +optional
InitialDelaySeconds *int32 `json:"initialDelaySeconds,omitempty"`
// Number of seconds after which the probe times out.
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
// +kubebuilder:validation:Minimum=1
// +default=1
// +optional
TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"`
// How often (in seconds) to perform the probe.
// +kubebuilder:validation:Minimum=1
// +default=10
// +optional
PeriodSeconds *int32 `json:"periodSeconds,omitempty"`
// Minimum consecutive successes for the probe to be considered successful after having failed.
// Must be 1 for liveness and startup.
// +kubebuilder:validation:Minimum=1
// +default=1
// +optional
SuccessThreshold *int32 `json:"successThreshold,omitempty"`
// Minimum consecutive failures for the probe to be considered failed after having succeeded.
// +kubebuilder:validation:Minimum=1
// +default=3
// +optional
FailureThreshold *int32 `json:"failureThreshold,omitempty"`

// // Optional duration in seconds the pod needs to terminate gracefully upon probe failure.
// // The grace period is the duration in seconds after the processes running in the pod are sent
// // a termination signal and the time when the processes are forcibly halted with a kill signal.
// // Set this value longer than the expected cleanup time for your process.
// // If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this
// // value overrides the value provided by the pod spec.
// // Value must be non-negative integer. The value zero indicates stop immediately via
// // the kill signal (no opportunity to shut down).
// // This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate.
// // +kubebuilder:validation:Minimum=1
// // +default=30
// // +optional
// TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
}

func (rp *RadixProbe) MapToCoreProbe() *corev1.Probe {
if rp == nil {
return nil
}

return &corev1.Probe{
ProbeHandler: rp.RadixProbeHandler.MapToCoreProbe(),
InitialDelaySeconds: pointers.Val(rp.InitialDelaySeconds),
TimeoutSeconds: pointers.Val(rp.TimeoutSeconds),
PeriodSeconds: pointers.Val(rp.PeriodSeconds),
SuccessThreshold: pointers.Val(rp.SuccessThreshold),
FailureThreshold: pointers.Val(rp.FailureThreshold),
// TerminationGracePeriodSeconds: rp.TerminationGracePeriodSeconds,
}
}

// RadixProbeHandler defines a specific action that should be taken in a probe.
// One and only one of the fields must be specified.
type RadixProbeHandler struct {
// Exec specifies the action to take.
Exec *RadixProbeExecAction `json:"exec,omitempty"`
// HTTPGet specifies the http request to perform.
HTTPGet *RadixProbeHTTPGetAction `json:"httpGet,omitempty"`
// TCPSocket specifies an action involving a TCP port.
TCPSocket *RadixProbeTCPSocketAction `json:"tcpSocket,omitempty"`
// GRPC specifies an action involving a GRPC port.
GRPC *RadixProbeGRPCAction `json:"grpc,omitempty"`
}

func (p RadixProbeHandler) MapToCoreProbe() corev1.ProbeHandler {
return corev1.ProbeHandler{
Exec: p.Exec.MapToCoreProbe(),
HTTPGet: p.HTTPGet.MapToCoreProbe(),
TCPSocket: p.TCPSocket.MapToCoreProbe(),
GRPC: p.GRPC.MapToCoreProbe(),
}
}

// RadixProbeHTTPGetAction describes an action based on HTTP Get requests.
type RadixProbeHTTPGetAction struct {
// Path to access on the HTTP server.
// +optional
Path *string `json:"path,omitempty"`
// port number to access on the container.
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=65535
Port *int32 `json:"port"`
// Host name to connect to, defaults to the pod IP. You probably want to set
// "Host" in httpHeaders instead.
// +optional
Host *string `json:"host,omitempty"`
// Scheme to use for connecting to the host.
// Defaults to HTTP.
// +optional
// +kubebuilder:validation:Enum=HTTPS;HTTP
Scheme *corev1.URIScheme `json:"scheme,omitempty"`
// Custom headers to set in the request. HTTP allows repeated headers.
// +optional
// +listType=atomic
HTTPHeaders []corev1.HTTPHeader `json:"httpHeaders,omitempty"`
}

func (a *RadixProbeHTTPGetAction) MapToCoreProbe() *corev1.HTTPGetAction {
if a == nil {
return nil
}

var port intstr.IntOrString
if a.Port != nil {
port = intstr.FromInt32(*a.Port)
}

return &corev1.HTTPGetAction{
Path: pointers.Val(a.Path),
Port: port,
Host: pointers.Val(a.Host),
Scheme: pointers.Val(a.Scheme),
HTTPHeaders: a.HTTPHeaders,
}
}

// RadixProbeExecAction describes a "run in container" action.
type RadixProbeExecAction struct {
// Command is the command line to execute inside the container, the working directory for the
// command is root ('/') in the container's filesystem. The command is simply exec'd, it is
// not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use
// a shell, you need to explicitly call out to that shell.
// Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
// +optional
// +listType=atomic
Command []string `json:"command,omitempty"`
}

func (a *RadixProbeExecAction) MapToCoreProbe() *corev1.ExecAction {
if a == nil {
return nil
}

return &corev1.ExecAction{
Command: a.Command,
}
}

// RadixProbeTCPSocketAction describes an action based on opening a socket
type RadixProbeTCPSocketAction struct {
// port number to access on the container.
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=65535
Port *int32 `json:"port"`
// Optional: Host name to connect to, defaults to the pod IP.
// +optional
Host *string `json:"host,omitempty"`
}

func (a *RadixProbeTCPSocketAction) MapToCoreProbe() *corev1.TCPSocketAction {
if a == nil {
return nil
}
var port intstr.IntOrString
if a.Port != nil {
port = intstr.FromInt32(*a.Port)
}

return &corev1.TCPSocketAction{
Port: port,
Host: pointers.Val(a.Host),
}
}

type RadixProbeGRPCAction struct {
// Port number of the gRPC service.
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=65535
Port int32 `json:"port"`

// Service is the name of the service to place in the gRPC HealthCheckRequest
// (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
//
// If this is not specified, the default behavior is defined by gRPC.
// +optional
// +default=""
Service *string `json:"service"`
}

func (a *RadixProbeGRPCAction) MapToCoreProbe() *corev1.GRPCAction {
if a == nil {
return nil
}

return &corev1.GRPCAction{
Port: a.Port,
Service: a.Service,
}
}
Loading

0 comments on commit d22b56c

Please sign in to comment.