Skip to content

[Draft] CSPL-3354: Add Lifecycle Hooks and Configurable Termination Grace Period to Splunk Operator #1424

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: feature/CSPL-3344
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions api/v4/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ type Spec struct {

// TopologySpreadConstraint https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/
TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`

TerminationGracePeriodSeconds int64 `json:"terminationGracePeriodSeconds"`
}

// Phase is used to represent the current phase of a custom resource
Expand Down
74 changes: 69 additions & 5 deletions config/crd/bases/enterprise.splunk.com_clustermanagers.yaml

Large diffs are not rendered by default.

74 changes: 69 additions & 5 deletions config/crd/bases/enterprise.splunk.com_clustermasters.yaml

Large diffs are not rendered by default.

146 changes: 137 additions & 9 deletions config/crd/bases/enterprise.splunk.com_indexerclusters.yaml

Large diffs are not rendered by default.

74 changes: 69 additions & 5 deletions config/crd/bases/enterprise.splunk.com_licensemanagers.yaml

Large diffs are not rendered by default.

74 changes: 69 additions & 5 deletions config/crd/bases/enterprise.splunk.com_licensemasters.yaml

Large diffs are not rendered by default.

146 changes: 137 additions & 9 deletions config/crd/bases/enterprise.splunk.com_monitoringconsoles.yaml

Large diffs are not rendered by default.

148 changes: 139 additions & 9 deletions config/crd/bases/enterprise.splunk.com_searchheadclusters.yaml

Large diffs are not rendered by default.

146 changes: 137 additions & 9 deletions config/crd/bases/enterprise.splunk.com_standalones.yaml

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions pkg/splunk/controller/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@ func MergePodSpecUpdates(ctx context.Context, current *corev1.PodSpec, revised *
}
}
}
if current.TerminationGracePeriodSeconds != revised.TerminationGracePeriodSeconds {
scopedLog.Info("Pod TerminationGracePeriodSeconds differs",
"current", current.TerminationGracePeriodSeconds,
"revised", revised.TerminationGracePeriodSeconds)
current.TerminationGracePeriodSeconds = revised.TerminationGracePeriodSeconds
result = true
}

// check for changes in container images; assume that the ordering is same for pods with > 1 container
if len(current.Containers) != len(revised.Containers) {
Expand Down Expand Up @@ -244,12 +251,24 @@ func MergePodSpecUpdates(ctx context.Context, current *corev1.PodSpec, revised *
current.Containers[idx].StartupProbe = revised.Containers[idx].StartupProbe
result = true
}
setPreStopLifecycleHandler(current, idx)
}
}

return result
}

// set the PreStop lifecycle handler for the specified container index
func setPreStopLifecycleHandler(podSpec *corev1.PodSpec, idx int) {
podSpec.Containers[idx].Lifecycle = &corev1.Lifecycle{
PreStop: &corev1.LifecycleHandler{
Exec: &corev1.ExecAction{
Command: []string{"/bin/sh", "-c", "/opt/splunk/bin/splunk offline && /opt/splunk/bin/splunk stop"},
},
},
}
}

// SortStatefulSetSlices sorts required slices in a statefulSet
func SortStatefulSetSlices(ctx context.Context, current *corev1.PodSpec, name string) error {
reqLogger := log.FromContext(ctx)
Expand Down
14 changes: 14 additions & 0 deletions pkg/splunk/controller/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ func TestMergePodUpdates(t *testing.T) {
matcher = func() bool { return reflect.DeepEqual(current.Spec.InitContainers, revised.Spec.InitContainers) }
podUpdateTester("InitContainer image changed")

// check Termination Grace Period updated
terminationGracePeriodSeconds := int64(60)
revised.Spec.TerminationGracePeriodSeconds = &terminationGracePeriodSeconds
matcher = func() bool {
return reflect.DeepEqual(current.Spec.TerminationGracePeriodSeconds, revised.Spec.TerminationGracePeriodSeconds)
}
podUpdateTester("TerminationGracePeriod updated")

// check new container added
revised.Spec.Containers = []corev1.Container{{Image: "splunk/splunk"}}
matcher = func() bool { return reflect.DeepEqual(current.Spec.Containers, revised.Spec.Containers) }
Expand Down Expand Up @@ -206,6 +214,12 @@ func TestMergePodUpdates(t *testing.T) {
}
podUpdateTester("Pod TopologySpreadConstraints changed")

// check Pre Stop Lifecycle Handler updated
idx := 0
setPreStopLifecycleHandler(&revised.Spec, idx)
matcher = func() bool { return reflect.DeepEqual(current.Spec.Containers, revised.Spec.Containers) }
podUpdateTester("PreStopLifecycleHandler updated")

// check container removed
revised.Spec.Containers = []corev1.Container{}
matcher = func() bool { return reflect.DeepEqual(current.Spec.Containers, revised.Spec.Containers) }
Expand Down
22 changes: 15 additions & 7 deletions pkg/splunk/enterprise/clustermanager_test.go

Large diffs are not rendered by default.

19 changes: 13 additions & 6 deletions pkg/splunk/enterprise/clustermaster_test.go

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions pkg/splunk/enterprise/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,17 @@ func getSmartstoreConfigMap(ctx context.Context, client splcommon.ControllerClie
return configMap
}

// set the PreStop lifecycle handler for the specified container index
func setPreStopLifecycleHandler(podTemplateSpec *corev1.PodTemplateSpec, idx int) {
podTemplateSpec.Spec.Containers[idx].Lifecycle = &corev1.Lifecycle{
PreStop: &corev1.LifecycleHandler{
Exec: &corev1.ExecAction{
Command: []string{"/bin/sh", "-c", "/opt/splunk/bin/splunk", "offline", "&&", "/opt/splunk/bin/splunk", "stop"},
},
},
}
}

// updateSplunkPodTemplateWithConfig modifies the podTemplateSpec object based on configuration of the Splunk Enterprise resource.
func updateSplunkPodTemplateWithConfig(ctx context.Context, client splcommon.ControllerClient, podTemplateSpec *corev1.PodTemplateSpec, cr splcommon.MetaObject, spec *enterpriseApi.CommonSplunkSpec, instanceType InstanceType, extraEnv []corev1.EnvVar, secretToMount string) {

Expand Down Expand Up @@ -1036,7 +1047,12 @@ func updateSplunkPodTemplateWithConfig(ctx context.Context, client splcommon.Con
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
}

// Use the helper function to set the lifecycle handler
setPreStopLifecycleHandler(podTemplateSpec, idx)
}

podTemplateSpec.Spec.TerminationGracePeriodSeconds = &spec.TerminationGracePeriodSeconds
}

func removeDuplicateEnvVars(sliceList []corev1.EnvVar) []corev1.EnvVar {
Expand Down
38 changes: 38 additions & 0 deletions pkg/splunk/enterprise/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"os"
"strings"
"testing"
"reflect"

enterpriseApi "github.com/splunk/splunk-operator/api/v4"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -1759,3 +1760,40 @@ func TestValidateLivenessProbe(t *testing.T) {
t.Errorf("Unexpected error when less than deault values passed for livenessProbe InitialDelaySeconds %d, TimeoutSeconds %d, PeriodSeconds %d. Error %s", livenessProbe.InitialDelaySeconds, livenessProbe.TimeoutSeconds, livenessProbe.PeriodSeconds, err)
}
}

func TestSetPreStopLifecycleHandler(t *testing.T) {
// Create a pod template spec with a single container
podTemplateSpec := corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{Name: "splunk"},
},
},
}

// Index of the container to apply the lifecycle handler
idx := 0

// Set the lifecycle handler
setPreStopLifecycleHandler(&podTemplateSpec, idx)

t.Run("test lifecycle pre-stop handler", func(t *testing.T) {
// Verify that the lifecycle handler was set correctly
if podTemplateSpec.Spec.Containers[idx].Lifecycle == nil {
t.Error("Expected Lifecycle to be set, but it was nil")
}

if podTemplateSpec.Spec.Containers[idx].Lifecycle.PreStop == nil {
t.Error("Expected PreStop to be set, but it was nil")
}

if podTemplateSpec.Spec.Containers[idx].Lifecycle.PreStop.Exec == nil {
t.Error("Expected Exec to be set, but it was nil")
}

expectedCommand := []string{"/bin/sh", "-c", "/opt/splunk/bin/splunk offline && /opt/splunk/bin/splunk stop"}
if !reflect.DeepEqual(podTemplateSpec.Spec.Containers[idx].Lifecycle.PreStop.Exec.Command, expectedCommand) {
t.Errorf("Expected command to be %v, but got %v", expectedCommand, podTemplateSpec.Spec.Containers[idx].Lifecycle.PreStop.Exec.Command)
}
})
}
Loading
Loading