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
9 changes: 9 additions & 0 deletions pkg/splunk/controller/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,15 @@ 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: 5 additions & 0 deletions pkg/splunk/controller/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ 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
11 changes: 9 additions & 2 deletions pkg/splunk/enterprise/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ func getSplunkService(cr splcommon.MetaObject, spec *enterprisev1.CommonSplunkSp
service.ObjectMeta.Namespace = cr.GetNamespace()
instanceIdentifier := cr.GetName()
var partOfIdentifier string
if instanceType == SplunkMonitoringConsole {
service.ObjectMeta.Name = GetSplunkServiceName(instanceType, cr.GetNamespace(), isHeadless)
instanceIdentifier = cr.GetNamespace()
}
if instanceType == SplunkIndexer {
if len(spec.IndexerClusterRef.Name) == 0 {
// Do not specify the instance label in the selector of IndexerCluster services, so that the services of the main part
Expand Down Expand Up @@ -260,6 +264,9 @@ func getSplunkPorts(instanceType InstanceType) map[string]int {
}

switch instanceType {
case SplunkMonitoringConsole:
result["hec"] = 8088
result["s2s"] = 9997
case SplunkStandalone:
result["dfccontrol"] = 17000
result["datareceive"] = 19000
Expand Down Expand Up @@ -483,8 +490,8 @@ func updateSplunkPodTemplateWithConfig(podTemplateSpec *corev1.PodTemplateSpec,
// Explicitly set the default value here so we can compare for changes correctly with current statefulset.
configMapVolDefaultMode := int32(corev1.ConfigMapVolumeSourceDefaultMode)

// add inline defaults to all splunk containers
if spec.Defaults != "" {
// add inline defaults to all splunk containers other than MC(where CR spec defaults are not needed)
if spec.Defaults != "" && instanceType != SplunkMonitoringConsole {
addSplunkVolumeToTemplate(podTemplateSpec, "defaults", corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Expand Down
35 changes: 32 additions & 3 deletions pkg/splunk/enterprise/finalizers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ func splunkDeletionTester(t *testing.T, cr splcommon.MetaObject, delete func(spl
labels := map[string]string{
"app.kubernetes.io/part-of": fmt.Sprintf("splunk-%s-%s", cr.GetName(), component),
}
listOpts := []client.ListOption{
listOptsA := []client.ListOption{
client.InNamespace("test"),
}
listOptsB := []client.ListOption{
client.InNamespace(cr.GetNamespace()),
client.MatchingLabels(labels),
}
Expand All @@ -69,12 +72,38 @@ func splunkDeletionTester(t *testing.T, cr splcommon.MetaObject, delete func(spl
mockCalls["Update"] = []spltest.MockFuncCall{
{MetaName: fmt.Sprintf("*%s.%s-%s-%s", apiVersion.Version, cr.GetObjectKind().GroupVersionKind().Kind, cr.GetNamespace(), cr.GetName())},
}
if component != "" {
if component != "indexer" {
mockCalls["Delete"] = []spltest.MockFuncCall{
{MetaName: "*v1.PersistentVolumeClaim-test-splunk-pvc-stack1-var"},
}
mockCalls["List"] = []spltest.MockFuncCall{
{ListOpts: listOptsA},
{ListOpts: listOptsB},
}
mockCalls["Get"] = []spltest.MockFuncCall{
{MetaName: "*v1.Secret-test-splunk-test-secret"},
{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.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Deployment-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"},
}
} else if component == "indexer" {
mockCalls["Delete"] = []spltest.MockFuncCall{
{MetaName: "*v1.PersistentVolumeClaim-test-splunk-pvc-stack1-var"},
}
mockCalls["List"] = []spltest.MockFuncCall{
{ListOpts: listOpts},
{ListOpts: listOptsB},
}
}
}
Expand Down
39 changes: 33 additions & 6 deletions pkg/splunk/enterprise/licensemaster.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ func ApplyLicenseMaster(client splcommon.ControllerClient, cr *enterprisev1.Lice
client.Status().Update(context.TODO(), cr)
}()

// create or update general config resources
_, err = ApplySplunkConfig(client, cr, cr.Spec.CommonSplunkSpec, SplunkLicenseMaster)
if err != nil {
return result, err
}

err = ApplyMonitoringConsole(client, cr, cr.Spec.CommonSplunkSpec, getLicenseMasterURL(cr, &cr.Spec.CommonSplunkSpec))
if err != nil {
return result, err
}

// check if deletion has been requested
if cr.ObjectMeta.DeletionTimestamp != nil {
terminating, err := splctrl.CheckForDeletion(cr, client)
Expand All @@ -59,12 +70,6 @@ func ApplyLicenseMaster(client splcommon.ControllerClient, cr *enterprisev1.Lice
return result, err
}

// create or update general config resources
_, err = ApplySplunkConfig(client, cr, cr.Spec.CommonSplunkSpec, SplunkLicenseMaster)
if err != nil {
return result, err
}

// create or update a service
err = splctrl.ApplyService(client, getSplunkService(cr, &cr.Spec.CommonSplunkSpec, SplunkLicenseMaster, false))
if err != nil {
Expand Down Expand Up @@ -99,3 +104,25 @@ func getLicenseMasterStatefulSet(client splcommon.ControllerClient, cr *enterpri
func validateLicenseMasterSpec(spec *enterprisev1.LicenseMasterSpec) error {
return validateCommonSplunkSpec(&spec.CommonSplunkSpec)
}

// getLicenseMasterURL returns URL of license master
func getLicenseMasterURL(cr splcommon.MetaObject, spec *enterprisev1.CommonSplunkSpec) []corev1.EnvVar {
if spec.LicenseMasterRef.Name != "" {
licenseMasterURL := GetSplunkServiceName(SplunkLicenseMaster, spec.LicenseMasterRef.Name, false)
if spec.LicenseMasterRef.Namespace != "" {
licenseMasterURL = splcommon.GetServiceFQDN(spec.LicenseMasterRef.Namespace, licenseMasterURL)
}
return []corev1.EnvVar{
{
Name: "SPLUNK_LICENSE_MASTER_URL",
Value: licenseMasterURL,
},
}
}
return []corev1.EnvVar{
{
Name: "SPLUNK_LICENSE_MASTER_URL",
Value: GetSplunkServiceName(SplunkLicenseMaster, cr.GetName(), false),
},
}
}
50 changes: 48 additions & 2 deletions pkg/splunk/enterprise/licensemaster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"testing"
"time"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

Expand All @@ -29,6 +30,13 @@ import (
func TestApplyLicenseMaster(t *testing.T) {
funcCalls := []spltest.MockFuncCall{
{MetaName: "*v1.Secret-test-splunk-test-secret"},
{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.ConfigMap-test-splunk-test-monitoring-console"},
{MetaName: "*v1.Deployment-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 @@ -40,8 +48,8 @@ func TestApplyLicenseMaster(t *testing.T) {
}
listmockCall := []spltest.MockFuncCall{
{ListOpts: listOpts}}
createCalls := map[string][]spltest.MockFuncCall{"Get": funcCalls, "Create": {funcCalls[0], funcCalls[1], funcCalls[3], funcCalls[4]}, "List": {listmockCall[0]}}
updateCalls := map[string][]spltest.MockFuncCall{"Get": funcCalls, "Update": {funcCalls[4]}, "List": {listmockCall[0]}}
createCalls := map[string][]spltest.MockFuncCall{"Get": funcCalls, "Create": {funcCalls[0], funcCalls[2], funcCalls[3], funcCalls[4], funcCalls[5], funcCalls[7], funcCalls[8], funcCalls[10], funcCalls[11]}, "List": {listmockCall[0], listmockCall[0]}}
updateCalls := map[string][]spltest.MockFuncCall{"Get": funcCalls, "Update": {funcCalls[7], funcCalls[11]}, "List": {listmockCall[0], listmockCall[0]}}
current := enterprisev1.LicenseMaster{
TypeMeta: metav1.TypeMeta{
Kind: "LicenseMaster",
Expand Down Expand Up @@ -99,3 +107,41 @@ func TestGetLicenseMasterStatefulSet(t *testing.T) {
cr.Spec.LicenseURL = "/mnt/splunk.lic"
test(`{"kind":"StatefulSet","apiVersion":"apps/v1","metadata":{"name":"splunk-stack1-license-master","namespace":"test","creationTimestamp":null,"ownerReferences":[{"apiVersion":"","kind":"","name":"stack1","uid":"","controller":true}]},"spec":{"replicas":1,"selector":{"matchLabels":{"app.kubernetes.io/component":"license-master","app.kubernetes.io/instance":"splunk-stack1-license-master","app.kubernetes.io/managed-by":"splunk-operator","app.kubernetes.io/name":"license-master","app.kubernetes.io/part-of":"splunk-stack1-license-master"}},"template":{"metadata":{"creationTimestamp":null,"labels":{"app.kubernetes.io/component":"license-master","app.kubernetes.io/instance":"splunk-stack1-license-master","app.kubernetes.io/managed-by":"splunk-operator","app.kubernetes.io/name":"license-master","app.kubernetes.io/part-of":"splunk-stack1-license-master"},"annotations":{"traffic.sidecar.istio.io/excludeOutboundPorts":"8089,8191,9997,7777,9000,17000,17500,19000","traffic.sidecar.istio.io/includeInboundPorts":"8000"}},"spec":{"volumes":[{"name":"mnt-splunk-secrets","secret":{"secretName":"splunk-stack1-license-master-secret-v1","defaultMode":420}}],"containers":[{"name":"splunk","image":"splunk/splunk","ports":[{"name":"splunkweb","containerPort":8000,"protocol":"TCP"},{"name":"splunkd","containerPort":8089,"protocol":"TCP"}],"env":[{"name":"SPLUNK_HOME","value":"/opt/splunk"},{"name":"SPLUNK_START_ARGS","value":"--accept-license"},{"name":"SPLUNK_DEFAULTS_URL","value":"/mnt/splunk-secrets/default.yml"},{"name":"SPLUNK_HOME_OWNERSHIP_ENFORCEMENT","value":"false"},{"name":"SPLUNK_ROLE","value":"splunk_license_master"},{"name":"SPLUNK_DECLARATIVE_ADMIN_PASSWORD","value":"true"},{"name":"SPLUNK_LICENSE_URI","value":"/mnt/splunk.lic"}],"resources":{"limits":{"cpu":"4","memory":"8Gi"},"requests":{"cpu":"100m","memory":"512Mi"}},"volumeMounts":[{"name":"pvc-etc","mountPath":"/opt/splunk/etc"},{"name":"pvc-var","mountPath":"/opt/splunk/var"},{"name":"mnt-splunk-secrets","mountPath":"/mnt/splunk-secrets"}],"livenessProbe":{"exec":{"command":["/sbin/checkstate.sh"]},"initialDelaySeconds":300,"timeoutSeconds":30,"periodSeconds":30},"readinessProbe":{"exec":{"command":["/bin/grep","started","/opt/container_artifact/splunk-container.state"]},"initialDelaySeconds":10,"timeoutSeconds":5,"periodSeconds":5},"imagePullPolicy":"IfNotPresent"}],"securityContext":{"runAsUser":41812,"fsGroup":41812},"affinity":{"podAntiAffinity":{"preferredDuringSchedulingIgnoredDuringExecution":[{"weight":100,"podAffinityTerm":{"labelSelector":{"matchExpressions":[{"key":"app.kubernetes.io/instance","operator":"In","values":["splunk-stack1-license-master"]}]},"topologyKey":"kubernetes.io/hostname"}}]}},"schedulerName":"default-scheduler"}},"volumeClaimTemplates":[{"metadata":{"name":"pvc-etc","namespace":"test","creationTimestamp":null,"labels":{"app.kubernetes.io/component":"license-master","app.kubernetes.io/instance":"splunk-stack1-license-master","app.kubernetes.io/managed-by":"splunk-operator","app.kubernetes.io/name":"license-master","app.kubernetes.io/part-of":"splunk-stack1-license-master"}},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"10Gi"}}},"status":{}},{"metadata":{"name":"pvc-var","namespace":"test","creationTimestamp":null,"labels":{"app.kubernetes.io/component":"license-master","app.kubernetes.io/instance":"splunk-stack1-license-master","app.kubernetes.io/managed-by":"splunk-operator","app.kubernetes.io/name":"license-master","app.kubernetes.io/part-of":"splunk-stack1-license-master"}},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"100Gi"}}},"status":{}}],"serviceName":"splunk-stack1-license-master-headless","podManagementPolicy":"Parallel","updateStrategy":{"type":"OnDelete"}},"status":{"replicas":0}}`)
}

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

cr.Spec.LicenseMasterRef.Name = "stack1"
got := getLicenseMasterURL(&cr, &cr.Spec.CommonSplunkSpec)
want := []corev1.EnvVar{
{
Name: "SPLUNK_LICENSE_MASTER_URL",
Value: "splunk-stack1-license-master-service",
},
}
result := splcommon.CompareEnvs(got, want)
//if differ then CompareEnvs returns true
if result == true {
t.Errorf("getLicenseMasterURL(\"%s\") = %s; want %s", SplunkLicenseMaster, got, want)
}

cr.Spec.LicenseMasterRef.Namespace = "test"
got = getLicenseMasterURL(&cr, &cr.Spec.CommonSplunkSpec)
want = []corev1.EnvVar{
{
Name: "SPLUNK_LICENSE_MASTER_URL",
Value: "splunk-stack1-license-master-service.test.svc.cluster.local",
},
}

result = splcommon.CompareEnvs(got, want)
//if differ then CompareEnvs returns true
if result == true {
t.Errorf("getLicenseMasterURL(\"%s\") = %s; want %s", SplunkLicenseMaster, got, want)
}
}
Loading