Skip to content
Merged
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
42 changes: 42 additions & 0 deletions pkg/splunk/controller/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package controller
import (
"context"
"fmt"
"reflect"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -230,3 +231,44 @@ func UpdateStatefulSetPods(c splcommon.ControllerClient, statefulSet *appsv1.Sta
scopedLog.Info("All pods are ready")
return splcommon.PhaseReady, nil
}

// SetStatefulSetOwnerRef sets owner references for statefulset
func SetStatefulSetOwnerRef(client splcommon.ControllerClient, cr splcommon.MetaObject, namespacedName types.NamespacedName) error {

statefulset, err := GetStatefulSetByName(client, namespacedName)
if err != nil {
return err
}

currentOwnerRef := statefulset.GetOwnerReferences()
// Check if owner ref exists
for i := 0; i < len(currentOwnerRef); i++ {
if reflect.DeepEqual(currentOwnerRef[i], splcommon.AsOwner(cr, false)) {
return nil
}
}

// Owner ref doesn't exist, update statefulset with owner references
statefulset.SetOwnerReferences(append(statefulset.GetOwnerReferences(), splcommon.AsOwner(cr, false)))

// Update owner reference if needed
err = splutil.UpdateResource(client, statefulset)
if err != nil {
return err
}

return nil
}

// GetStatefulSetByName retrieves current statefulset
func GetStatefulSetByName(c splcommon.ControllerClient, namespacedName types.NamespacedName) (*appsv1.StatefulSet, error) {
var statefulset appsv1.StatefulSet

err := c.Get(context.TODO(), namespacedName, &statefulset)
if err != nil {
// Didn't find it
return nil, err
}

return &statefulset, nil
}
67 changes: 67 additions & 0 deletions pkg/splunk/controller/statefulset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,12 @@ import (

appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"

spltest "github.com/splunk/splunk-operator/pkg/splunk/test"
splutil "github.com/splunk/splunk-operator/pkg/splunk/util"

enterprisev1 "github.com/splunk/splunk-operator/pkg/apis/enterprise/v1beta1"
)

func TestApplyStatefulSet(t *testing.T) {
Expand Down Expand Up @@ -52,3 +56,66 @@ func TestDefaultStatefulSetPodManager(t *testing.T) {
method := "DefaultStatefulSetPodManager.Update"
spltest.PodManagerTester(t, method, &mgr)
}

func TestSetStatefulSetOwnerRef(t *testing.T) {
cr := enterprisev1.Standalone{
ObjectMeta: metav1.ObjectMeta{
Name: "stack1",
Namespace: "test",
},
}

c := spltest.NewMockClient()
current := appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: "splunk-test-monitoring-console",
Namespace: "test",
},
}
namespacedName := types.NamespacedName{Namespace: "test", Name: "splunk-test-monitoring-console"}

err := SetStatefulSetOwnerRef(c, &cr, namespacedName)
if err.Error() != "NotFound" {
t.Errorf("Couldn't detect resource %s", current.GetName())
}

// Create statefulset
err = splutil.CreateResource(c, &current)
if err != nil {
t.Errorf("Failed to create owner reference %s", current.GetName())
}

// Test existing owner reference
err = SetStatefulSetOwnerRef(c, &cr, namespacedName)
if err != nil {
t.Errorf("Couldn't set owner ref for resource %s", current.GetName())
}

// Try adding same owner again
err = SetStatefulSetOwnerRef(c, &cr, namespacedName)
if err != nil {
t.Errorf("Couldn't set owner ref for statefulset %s", current.GetName())
}
}

func TestGetStatefulSetByName(t *testing.T) {
c := spltest.NewMockClient()

current := appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: "splunk-test-monitoring-console",
Namespace: "test",
},
}

_, err := ApplyStatefulSet(c, &current)
if err != nil {
return
}

namespacedName := types.NamespacedName{Namespace: "test", Name: "splunk-test-monitoring-console"}
_, err = GetStatefulSetByName(c, namespacedName)
if err != nil {
t.Errorf(err.Error())
}
}
9 changes: 0 additions & 9 deletions pkg/splunk/controller/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,6 @@ func MergePodSpecUpdates(current *corev1.PodSpec, revised *corev1.PodSpec, name
result = true
}

// check Env
if splcommon.CompareEnvs(current.Containers[idx].Env, revised.Containers[idx].Env) {
scopedLog.Info("Pod Container Env differ",
"current", current.Containers[idx].Env,
"revised", revised.Containers[idx].Env)
current.Containers[idx].Env = revised.Containers[idx].Env
result = true
}

// check VolumeMounts
if splcommon.CompareVolumeMounts(current.Containers[idx].VolumeMounts, revised.Containers[idx].VolumeMounts) {
scopedLog.Info("Pod Container VolumeMounts differ",
Expand Down
5 changes: 0 additions & 5 deletions pkg/splunk/controller/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,6 @@ func TestMergePodUpdates(t *testing.T) {
matcher = func() bool { return reflect.DeepEqual(current.Spec.Containers, revised.Spec.Containers) }
podUpdateTester("Container Ports")

// check container different Env
revised.Spec.Containers[0].Env = []corev1.EnvVar{{Name: "A", Value: "ab"}}
matcher = func() bool { return reflect.DeepEqual(current.Spec.Containers, revised.Spec.Containers) }
podUpdateTester("Container Env")

// check container different VolumeMounts
revised.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{{Name: "mnt-spark"}}
matcher = func() bool { return reflect.DeepEqual(current.Spec.Containers, revised.Spec.Containers) }
Expand Down
20 changes: 19 additions & 1 deletion pkg/splunk/enterprise/finalizers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"testing"
"time"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
Expand Down Expand Up @@ -80,6 +81,8 @@ func splunkDeletionTester(t *testing.T, cr splcommon.MetaObject, delete func(spl
if cr.GetObjectKind().GroupVersionKind().Kind != "IndexerCluster" {
mockCalls["Update"] = []spltest.MockFuncCall{
{MetaName: "*v1.Secret-test-splunk-test-secret"},
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
{MetaName: fmt.Sprintf("*%s.%s-%s-%s", apiVersion.Version, cr.GetObjectKind().GroupVersionKind().Kind, cr.GetNamespace(), cr.GetName())},
}
Expand All @@ -91,6 +94,7 @@ func splunkDeletionTester(t *testing.T, cr splcommon.MetaObject, delete func(spl
{ListOpts: listOptsB},
}
mockCalls["Get"] = []spltest.MockFuncCall{
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
Expand All @@ -100,15 +104,16 @@ func splunkDeletionTester(t *testing.T, cr splcommon.MetaObject, delete func(spl
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
}
mockCalls["Create"] = []spltest.MockFuncCall{
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
{MetaName: "*v1.Secret-test-splunk-test-monitoring-console-secret-v1"},
{MetaName: "*v1.Service-test-splunk-test-monitoring-console-service"},
{MetaName: "*v1.Service-test-splunk-test-monitoring-console-headless"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
}
} else {
mockCalls["Update"] = []spltest.MockFuncCall{
Expand All @@ -124,10 +129,12 @@ func splunkDeletionTester(t *testing.T, cr splcommon.MetaObject, delete func(spl
{ListOpts: listOptsB},
}
mockCalls["Create"] = []spltest.MockFuncCall{
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
{MetaName: "*v1.Secret-test-splunk-test-monitoring-console-secret-v1"},
}
mockCalls["Get"] = []spltest.MockFuncCall{
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
Expand All @@ -139,6 +146,17 @@ func splunkDeletionTester(t *testing.T, cr splcommon.MetaObject, delete func(spl

c := spltest.NewMockClient()
c.ListObj = &pvclist
statefulset := appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: "splunk-test-monitoring-console",
Namespace: "test",
},
}
_, err := splctrl.ApplyStatefulSet(c, &statefulset)
if err != nil {
return
}

deleted, err := delete(cr, c)
if deleted != wantDeleted || err != nil {
t.Errorf("splctrl.CheckForDeletion() returned %t, %v; want %t, nil", deleted, err, wantDeleted)
Expand Down
48 changes: 25 additions & 23 deletions pkg/splunk/enterprise/monitoringconsole.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,6 @@ func ApplyMonitoringConsole(client splcommon.ControllerClient, cr splcommon.Meta
addNewURLs = false
}

_, err = ApplyMonitoringConsoleEnvConfigMap(client, cr.GetNamespace(), cr.GetName(), extraEnv, addNewURLs)
if err != nil {
return err
}

//by default set multisite to false
multiSite := "false"

//get cluster info from cluster master
if cr.GetObjectKind().GroupVersionKind().Kind == "ClusterMaster" && !spec.Mock {
mgr := monitoringConsolePodManager{cr: &cr, spec: &spec, secrets: secrets, newSplunkClient: splclient.NewSplunkClient}
Expand All @@ -87,10 +79,18 @@ func ApplyMonitoringConsole(client splcommon.ControllerClient, cr splcommon.Meta
if err != nil {
return err
}
multiSite = clusterInfo.MultiSite
multiSite := clusterInfo.MultiSite
if multiSite == "true" {
extraEnv = append(extraEnv, corev1.EnvVar{Name: "SPLUNK_SITE", Value: "site0"}, corev1.EnvVar{Name: "SPLUNK_MULTISITE_MASTER", Value: GetSplunkServiceName(SplunkClusterMaster, cr.GetName(), false)})
}
}

_, err = ApplyMonitoringConsoleEnvConfigMap(client, cr.GetNamespace(), cr.GetName(), extraEnv, addNewURLs)
if err != nil {
return err
}

statefulset, err := getMonitoringConsoleStatefulSet(client, cr, &spec, SplunkMonitoringConsole, secretName, multiSite)
statefulset, err := getMonitoringConsoleStatefulSet(client, cr, &spec, SplunkMonitoringConsole, secretName)
if err != nil {
return err
}
Expand Down Expand Up @@ -122,10 +122,9 @@ type monitoringConsolePodManager struct {
}

// getMonitoringConsoleStatefulSet returns a Kubernetes Statefulset object for Splunk Enterprise monitoring console instance.
func getMonitoringConsoleStatefulSet(client splcommon.ControllerClient, cr splcommon.MetaObject, spec *enterprisev1.CommonSplunkSpec, instanceType InstanceType, secretName string, MultiSite string) (*appsv1.StatefulSet, error) {
func getMonitoringConsoleStatefulSet(client splcommon.ControllerClient, cr splcommon.MetaObject, spec *enterprisev1.CommonSplunkSpec, instanceType InstanceType, secretName string) (*appsv1.StatefulSet, error) {
var partOfIdentifier string
var monitoringConsoleConfigMap *corev1.ConfigMap
var emptyEnv []corev1.EnvVar
// there will be always 1 replica of monitoring console
replicas := int32(1)
ports := splcommon.SortContainerPorts(getSplunkContainerPorts(SplunkMonitoringConsole))
Expand Down Expand Up @@ -194,27 +193,26 @@ func getMonitoringConsoleStatefulSet(client splcommon.ControllerClient, cr splco

env := []corev1.EnvVar{}

if MultiSite == "true" {
env = append(env, corev1.EnvVar{Name: "SPLUNK_SITE", Value: "site0"}, corev1.EnvVar{Name: "SPLUNK_MULTISITE_MASTER", Value: GetSplunkServiceName(SplunkClusterMaster, cr.GetName(), false)})
}

// append labels and annotations from parent
splcommon.AppendParentMeta(statefulSet.Spec.Template.GetObjectMeta(), cr.GetObjectMeta())

// update statefulset's pod template with common splunk pod config
updateSplunkPodTemplateWithConfig(client, &statefulSet.Spec.Template, cr, spec, instanceType, env, secretName)

//update podTemplate annotation with configMap resource version
//use emptyEnv here to avoid adding site amd multisite_master info in configMap
//TODO: Update this configMap retrieval by API from PR #134
if cr.GetObjectMeta().GetDeletionTimestamp() != nil {
monitoringConsoleConfigMap, _ = ApplyMonitoringConsoleEnvConfigMap(client, cr.GetNamespace(), cr.GetName(), emptyEnv, false)
} else {
monitoringConsoleConfigMap, _ = ApplyMonitoringConsoleEnvConfigMap(client, cr.GetNamespace(), cr.GetName(), emptyEnv, true)
namespacedName := types.NamespacedName{Namespace: cr.GetNamespace(), Name: configMap}
monitoringConsoleConfigMap, err := splctrl.GetConfigMap(client, namespacedName)
if err != nil {
return nil, err
}
statefulSet.Spec.Template.ObjectMeta.Annotations[monitoringConsoleConfigRev] = monitoringConsoleConfigMap.ResourceVersion

statefulSet.SetOwnerReferences(append(statefulSet.GetOwnerReferences(), splcommon.AsOwner(cr, false)))
//set owner reference for splunk monitoring console statefulset
namespacedName = types.NamespacedName{Namespace: cr.GetNamespace(), Name: GetSplunkStatefulsetName(SplunkMonitoringConsole, cr.GetNamespace())}
err = splctrl.SetStatefulSetOwnerRef(client, cr, namespacedName)
if err != nil {
return nil, err
}

return statefulSet, nil
}
Expand Down Expand Up @@ -326,6 +324,10 @@ func DeleteURLsConfigMap(revised *corev1.ConfigMap, crName string, newURLs []cor
} else if strings.Contains(curr, crName) && deleteCR {
revised.Data[url.Name] = strings.ReplaceAll(revised.Data[url.Name], url.Value, "")
}
//if deleting "SPLUNK_MULTISITE_MASTER" delete "SPLUNK_SITE"
if url.Name == "SPLUNK_SITE" && deleteCR {
delete(revised.Data, "SPLUNK_SITE")
}
if strings.HasPrefix(revised.Data[url.Name], ",") {
str := revised.Data[url.Name]
revised.Data[url.Name] = strings.TrimPrefix(str, ",")
Expand Down
Loading