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
4 changes: 2 additions & 2 deletions pkg/splunk/enterprise/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ func getSplunkStatefulSet(client splcommon.ControllerClient, cr splcommon.MetaOb
}

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

// make Splunk Enterprise object the owner
statefulSet.SetOwnerReferences(append(statefulSet.GetOwnerReferences(), splcommon.AsOwner(cr, true)))
Expand All @@ -434,7 +434,7 @@ func getSplunkStatefulSet(client splcommon.ControllerClient, cr splcommon.MetaOb
}

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

// Add custom ports to splunk containers
if spec.ServiceTemplate.Spec.Ports != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/splunk/enterprise/finalizers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,15 @@ func splunkDeletionTester(t *testing.T, cr splcommon.MetaObject, delete func(spl
{MetaName: "*v1.Service-test-splunk-test-monitoring-console-headless"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Deployment-test-splunk-test-monitoring-console"},
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
}
mockCalls["Create"] = []spltest.MockFuncCall{
{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.Deployment-test-splunk-test-monitoring-console"},
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
}
} else {
mockCalls["Update"] = []spltest.MockFuncCall{
Expand Down
3 changes: 2 additions & 1 deletion pkg/splunk/enterprise/licensemaster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestApplyLicenseMaster(t *testing.T) {
{MetaName: "*v1.Service-test-splunk-test-monitoring-console-headless"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Deployment-test-splunk-test-monitoring-console"},
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Service-test-splunk-stack1-license-master-service"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
{MetaName: "*v1.Secret-test-splunk-stack1-license-master-secret-v1"},
Expand All @@ -54,6 +54,7 @@ func TestApplyLicenseMaster(t *testing.T) {
}
listmockCall := []spltest.MockFuncCall{
{ListOpts: listOpts}}

createCalls := map[string][]spltest.MockFuncCall{"Get": funcCalls, "Create": {funcCalls[0], funcCalls[3], funcCalls[4], funcCalls[5], funcCalls[6], funcCalls[8], funcCalls[9], funcCalls[11], funcCalls[12]}, "List": {listmockCall[0], listmockCall[0]}, "Update": {funcCalls[0]}}
updateCalls := map[string][]spltest.MockFuncCall{"Get": {funcCalls[0], funcCalls[2], funcCalls[3], funcCalls[4], funcCalls[5], funcCalls[6], funcCalls[7], funcCalls[8], funcCalls[9], funcCalls[10], funcCalls[11], funcCalls[12]}, "Update": {funcCalls[8], funcCalls[12]}, "List": {listmockCall[0], listmockCall[0]}}
current := enterprisev1.LicenseMaster{
Expand Down
110 changes: 34 additions & 76 deletions pkg/splunk/enterprise/monitoringconsole.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,7 @@
package enterprise

import (
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"reflect"
"sort"
"strings"
Expand All @@ -35,12 +30,9 @@ import (
"k8s.io/apimachinery/pkg/types"
)

// ApplyMonitoringConsole creates the deployment for monitoring console deployment of Splunk Enterprise.
// ApplyMonitoringConsole creates the statefulset for monitoring console statefulset of Splunk Enterprise.
func ApplyMonitoringConsole(client splcommon.ControllerClient, cr splcommon.MetaObject, spec enterprisev1.CommonSplunkSpec, extraEnv []corev1.EnvVar) error {
var secrets *corev1.Secret
var err error

secrets, err = splutil.GetLatestVersionedSecret(client, cr, cr.GetNamespace(), GetSplunkMonitoringConsoleDeploymentName(SplunkMonitoringConsole, cr.GetNamespace()))
secrets, err := splutil.GetLatestVersionedSecret(client, cr, cr.GetNamespace(), GetSplunkStatefulsetName(SplunkMonitoringConsole, cr.GetNamespace()))
if err != nil {
return err
}
Expand Down Expand Up @@ -74,29 +66,22 @@ func ApplyMonitoringConsole(client splcommon.ControllerClient, cr splcommon.Meta
return err
}

//configMapHash to trigger the configMap change in monitoring console deployment
configMapHash, err := getConfigMapHash(client, cr.GetNamespace())
statefulsetMC, err := getMonitoringConsoleStatefulSet(client, cr, &spec, SplunkMonitoringConsole, secretName)
if err != nil {
return err
}

//configMapHash should never be nil, just adding extra check
if configMapHash == "" {
return err
}

deploymentMC, err := getMonitoringConsoleDeployment(cr, &spec, SplunkMonitoringConsole, configMapHash, secretName)
mgr := splctrl.DefaultStatefulSetPodManager{}
_, err = mgr.Update(client, statefulsetMC, 1)
if err != nil {
return err
}

_, err = splctrl.ApplyDeployment(client, deploymentMC)

return err
}

// GetMonitoringConsoleDeployment returns a Kubernetes Deployment object for Splunk Enterprise monitoring console instance.
func getMonitoringConsoleDeployment(cr splcommon.MetaObject, spec *enterprisev1.CommonSplunkSpec, instanceType InstanceType, configMapHash string, secretName string) (*appsv1.Deployment, error) {
// 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) (*appsv1.StatefulSet, error) {
var partOfIdentifier string
// there will be always 1 replica of monitoring console
replicas := int32(1)
Expand All @@ -113,21 +98,26 @@ func getMonitoringConsoleDeployment(cr splcommon.MetaObject, spec *enterprisev1.
labels[k] = v
}

//create deployment configuration
deploymentMC := &appsv1.Deployment{
//create statefulset configuration
statefulSet := &appsv1.StatefulSet{
TypeMeta: metav1.TypeMeta{
Kind: "Deployment",
Kind: "StatefulSet",
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: GetSplunkMonitoringConsoleDeploymentName(instanceType, cr.GetNamespace()),
Name: GetSplunkStatefulsetName(instanceType, cr.GetNamespace()),
Namespace: cr.GetNamespace(),
},
Spec: appsv1.DeploymentSpec{
Spec: appsv1.StatefulSetSpec{
Selector: &metav1.LabelSelector{
MatchLabels: selectLabels,
},
Replicas: &replicas,
ServiceName: GetSplunkServiceName(instanceType, cr.GetNamespace(), true),
Replicas: &replicas,
PodManagementPolicy: appsv1.ParallelPodManagement,
UpdateStrategy: appsv1.StatefulSetUpdateStrategy{
Type: appsv1.OnDeleteStatefulSetStrategyType,
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: labels,
Expand Down Expand Up @@ -159,18 +149,26 @@ func getMonitoringConsoleDeployment(cr splcommon.MetaObject, spec *enterprisev1.
},
}

env := []corev1.EnvVar{
{Name: "SPLUNK_CONFIGMAP_HASH",
Value: configMapHash,
},
}
env := []corev1.EnvVar{}

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

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

return deploymentMC, nil
//update podTemplate annotation with configMap resource version
var monitoringConsoleConfigMap *corev1.ConfigMap
if cr.GetObjectMeta().GetDeletionTimestamp() != nil {
monitoringConsoleConfigMap, _ = ApplyMonitoringConsoleEnvConfigMap(client, cr.GetNamespace(), cr.GetName(), env, false)
} else {
monitoringConsoleConfigMap, _ = ApplyMonitoringConsoleEnvConfigMap(client, cr.GetNamespace(), cr.GetName(), env, true)
}
statefulSet.Spec.Template.ObjectMeta.Annotations[monitoringConsoleConfigRev] = monitoringConsoleConfigMap.ResourceVersion

statefulSet.SetOwnerReferences(append(statefulSet.GetOwnerReferences(), splcommon.AsOwner(cr, false)))

return statefulSet, nil
}

//ApplyMonitoringConsoleEnvConfigMap creates or updates a Kubernetes ConfigMap for extra env for monitoring console pod
Expand Down Expand Up @@ -298,43 +296,3 @@ func DeleteURLsConfigMap(revised *corev1.ConfigMap, crName string, newURLs []cor
}
}
}

func getConfigMapHash(client splcommon.ControllerClient, namespace string) (string, error) {

namespacedName := types.NamespacedName{Namespace: namespace, Name: GetSplunkMonitoringconsoleConfigMapName(namespace, SplunkMonitoringConsole)}
var current corev1.ConfigMap

err := client.Get(context.TODO(), namespacedName, &current)
// if configMap doens't exist and we try to get configMap hash just return with empty string
if err != nil {
return "", err
}

contents := current.Data

hash := md5.New()
b := new(bytes.Buffer)

//check key sorting. Collect keys in array and sort. Then use that sorted keys to append
var keys []string

for k := range contents {
keys = append(keys, k)
}

//sort keys here
sort.Strings(keys)

//now iterate through the map in sorted order
for _, k := range keys {
fmt.Fprintf(b, "%s=\"%s\"\n", k, contents[k])
}

if _, err := io.Copy(hash, b); err != nil {
return "", err
}

hashInBytes := hash.Sum(nil)[:16]
returnMD5String := hex.EncodeToString(hashInBytes)
return returnMD5String, nil
}
4 changes: 2 additions & 2 deletions pkg/splunk/enterprise/monitoringconsole_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestApplyMonitoringConsole(t *testing.T) {
{MetaName: "*v1.Service-test-splunk-test-monitoring-console-headless"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Deployment-test-splunk-test-monitoring-console"},
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
}
labels := map[string]string{
"app.kubernetes.io/component": "versionedSecrets",
Expand All @@ -57,7 +57,7 @@ func TestApplyMonitoringConsole(t *testing.T) {
listmockCall := []spltest.MockFuncCall{
{ListOpts: listOpts}}

createCalls := map[string][]spltest.MockFuncCall{"Get": funcCalls, "Create": {funcCalls[1], funcCalls[2], funcCalls[3], funcCalls[4], funcCalls[6]}, "List": {listmockCall[0]}}
createCalls := map[string][]spltest.MockFuncCall{"Get": funcCalls, "Create": {funcCalls[1], funcCalls[2], funcCalls[3], funcCalls[5], funcCalls[6]}, "List": {listmockCall[0]}}
updateCalls := map[string][]spltest.MockFuncCall{"Get": funcCalls, "Update": {funcCalls[6]}, "List": {listmockCall[0]}}
c := spltest.NewMockClient()

Expand Down
10 changes: 4 additions & 6 deletions pkg/splunk/enterprise/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ const (

// identifier used for S3 secret key
s3SecretKey = "s3_secret_key"

//identifier for monitoring console configMap revision
monitoringConsoleConfigRev = "monitoringConsoleConfigRev"
)

// GetSplunkDeploymentName uses a template to name a Kubernetes Deployment for Splunk instances.
Expand All @@ -61,11 +64,6 @@ func GetSplunkStatefulsetName(instanceType InstanceType, identifier string) stri
return fmt.Sprintf(statefulSetTemplateStr, identifier, instanceType)
}

// GetSplunkMonitoringConsoleDeploymentName uses a template to name a Kubernetes Deployment for Splunk MC instance.
func GetSplunkMonitoringConsoleDeploymentName(instanceType InstanceType, identifier string) string {
return fmt.Sprintf(deploymentTemplateStr, identifier, instanceType)
}

// GetSplunkStatefulsetPodName uses a template to name a specific pod within a Kubernetes StatefulSet for Splunk instances.
func GetSplunkStatefulsetPodName(instanceType InstanceType, identifier string, index int32) string {
return fmt.Sprintf(statefulSetPodTemplateStr, identifier, instanceType, index)
Expand All @@ -91,7 +89,7 @@ func GetSplunkDefaultsName(identifier string, instanceType InstanceType) string

// GetSplunkMonitoringconsoleConfigMapName uses a template to name a Kubernetes ConfigMap for a SplunkEnterprise resource.
func GetSplunkMonitoringconsoleConfigMapName(identifier string, instanceType InstanceType) string {
return fmt.Sprintf(deploymentTemplateStr, identifier, instanceType.ToKind())
return fmt.Sprintf(statefulSetTemplateStr, identifier, instanceType.ToKind())
}

// GetSplunkSmartstoreConfigMapName uses a template to name a Kubernetes ConfigMap for a SplunkEnterprise resource.
Expand Down
8 changes: 0 additions & 8 deletions pkg/splunk/enterprise/names_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,6 @@ func TestGetSplunkStatefulsetName(t *testing.T) {
}
}

func TestGetSplunkMonitoringConsoleDeploymentName(t *testing.T) {
got := GetSplunkMonitoringConsoleDeploymentName(SplunkMonitoringConsole, "t2")
want := "splunk-t2-monitoring-console"
if got != want {
t.Errorf("GetSplunkMonitoringConsoleDeploymentName(\"%s\",\"%s\") = %s; want %s", SplunkMonitoringConsole.ToString(), "t2", got, want)
}
}

func TestGetSplunkStatefulsetPodName(t *testing.T) {
got := GetSplunkStatefulsetPodName(SplunkSearchHead, "t3", 2)
want := "splunk-t3-search-head-2"
Expand Down
2 changes: 1 addition & 1 deletion pkg/splunk/enterprise/searchheadcluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestApplySearchHeadCluster(t *testing.T) {
{MetaName: "*v1.Service-test-splunk-test-monitoring-console-headless"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Deployment-test-splunk-test-monitoring-console"},
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Service-test-splunk-stack1-search-head-headless"},
{MetaName: "*v1.Service-test-splunk-stack1-search-head-service"},
{MetaName: "*v1.Service-test-splunk-stack1-deployer-service"},
Expand Down
4 changes: 2 additions & 2 deletions pkg/splunk/enterprise/standalone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestApplyStandalone(t *testing.T) {
{MetaName: "*v1.Service-test-splunk-test-monitoring-console-headless"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Deployment-test-splunk-test-monitoring-console"},
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Service-test-splunk-stack1-standalone-headless"},
{MetaName: "*v1.Service-test-splunk-stack1-standalone-service"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
Expand Down Expand Up @@ -100,7 +100,7 @@ func TestApplyStandaloneWithSmartstore(t *testing.T) {
{MetaName: "*v1.Service-test-splunk-test-monitoring-console-headless"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Deployment-test-splunk-test-monitoring-console"},
{MetaName: "*v1.StatefulSet-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Service-test-splunk-stack1-standalone-headless"},
{MetaName: "*v1.Service-test-splunk-stack1-standalone-service"},
{MetaName: "*v1.Secret-test-splunk-test-secret"},
Expand Down