Skip to content

Commit 86ecdaa

Browse files
author
Patryk Wasielewski
committed
add support for admin-managed-pv annotation
1 parent 4f03ca8 commit 86ecdaa

File tree

2 files changed

+94
-28
lines changed

2 files changed

+94
-28
lines changed

docs/CustomResources.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,45 @@ spec:
403403
replicas: 1
404404
```
405405
406+
#### admin-managed-pv Annotations
407+
The admin-managed-pv annotation in the splunk-operator's Custom Resource allows the admin to control whether Persistent Volumes (PVs) are dynamically created for the StatefulSet associated with the CR. If set to `true`, no PVs will be created, and the Persistent Volume Claim templates in the StatefulSet manifest will include a selector block to match `app.kubernetes.io/instance` and `app.kubernetes.io/name` labels for pre-created PVs. This means that `/opt/splunk/etc` and `/opt/splunk/var` related PVCs will contain code block like below
408+
409+
```
410+
apiVersion: v1
411+
kind: PersistentVolumeClaim
412+
...
413+
selector:
414+
matchLabels:
415+
app.kubernetes.io/instance: splunk-cm-cluster-manager
416+
app.kubernetes.io/name: cluster-manager
417+
```
418+
419+
To match selector definition like this, Persistent Volume must set labels accordingly
420+
421+
```
422+
apiVersion: v1
423+
kind: PersistentVolume
424+
metadata:
425+
name: pv-example-etc
426+
labels:
427+
app.kubernetes.io/instance: splunk-cm-cluster-manager
428+
app.kubernetes.io/name: cluster-manager
429+
```
430+
431+
When admin-managed-pv is set to `false`, PVs will be dynamically created as usual, providing dedicated persistent storage for the StatefulSet.
432+
433+
Here is an example of a Standalone with the admin-managed-pv annotation set. After
434+
```
435+
apiVersion: enterprise.splunk.com/v4
436+
kind: Standalone
437+
metadata:
438+
name: single
439+
finalizers:
440+
- enterprise.splunk.com/delete-pvc
441+
annotations:
442+
enterprise.splunk.com/admin-managed-pv: "true"
443+
```
444+
406445
#### Container Logs
407446
The Splunk Enterprise CRDs deploy Splunkd in Kubernetes pods running [docker-splunk](https://github.com/splunk/docker-splunk) container images. Adding a couple of environment variables to the CR spec as follows produces `detailed container logs`:
408447

pkg/splunk/enterprise/configuration.go

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"path/filepath"
2424
"reflect"
2525
"strconv"
26+
"strings"
2627

2728
orderedmap "github.com/wk8/go-ordered-map/v2"
2829
appsv1 "k8s.io/api/apps/v1"
@@ -98,52 +99,69 @@ func getSplunkLabels(instanceIdentifier string, instanceType InstanceType, partO
9899
}
99100

100101
// getSplunkVolumeClaims returns a standard collection of Kubernetes volume claims.
101-
func getSplunkVolumeClaims(cr splcommon.MetaObject, spec *enterpriseApi.CommonSplunkSpec, labels map[string]string, volumeType string) (corev1.PersistentVolumeClaim, error) {
102+
func getSplunkVolumeClaims(cr splcommon.MetaObject, spec *enterpriseApi.CommonSplunkSpec, labels map[string]string, volumeType string, adminManagedPV bool) (corev1.PersistentVolumeClaim, error) {
102103
var storageCapacity resource.Quantity
103104
var err error
104-
105-
storageClassName := ""
105+
var storageClassName string
106+
var volumeClaim corev1.PersistentVolumeClaim
106107

107108
// Depending on the volume type, determine storage capacity and storage class name(if configured)
108109
if volumeType == splcommon.EtcVolumeStorage {
109110
storageCapacity, err = splcommon.ParseResourceQuantity(spec.EtcVolumeStorageConfig.StorageCapacity, splcommon.DefaultEtcVolumeStorageCapacity)
110111
if err != nil {
111112
return corev1.PersistentVolumeClaim{}, fmt.Errorf("%s: %s", "etcStorage", err)
112113
}
113-
if spec.EtcVolumeStorageConfig.StorageClassName != "" {
114-
storageClassName = spec.EtcVolumeStorageConfig.StorageClassName
115-
}
114+
storageClassName = spec.EtcVolumeStorageConfig.StorageClassName
116115
} else if volumeType == splcommon.VarVolumeStorage {
117116
storageCapacity, err = splcommon.ParseResourceQuantity(spec.VarVolumeStorageConfig.StorageCapacity, splcommon.DefaultVarVolumeStorageCapacity)
118117
if err != nil {
119118
return corev1.PersistentVolumeClaim{}, fmt.Errorf("%s: %s", "varStorage", err)
120119
}
121-
if spec.VarVolumeStorageConfig.StorageClassName != "" {
122-
storageClassName = spec.VarVolumeStorageConfig.StorageClassName
123-
}
120+
storageClassName = spec.VarVolumeStorageConfig.StorageClassName
124121
}
125122

126-
// Create a persistent volume claim
127-
volumeClaim := corev1.PersistentVolumeClaim{
128-
ObjectMeta: metav1.ObjectMeta{
129-
Name: fmt.Sprintf(splcommon.PvcNamePrefix, volumeType),
130-
Namespace: cr.GetNamespace(),
131-
Labels: labels,
132-
},
133-
Spec: corev1.PersistentVolumeClaimSpec{
134-
AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"},
135-
Resources: corev1.ResourceRequirements{
136-
Requests: corev1.ResourceList{
137-
corev1.ResourceStorage: storageCapacity,
123+
volumeClaim.Spec.StorageClassName = &storageClassName
124+
125+
if adminManagedPV {
126+
volumeClaim = corev1.PersistentVolumeClaim{
127+
ObjectMeta: metav1.ObjectMeta{
128+
Name: fmt.Sprintf(splcommon.PvcNamePrefix, volumeType),
129+
Namespace: cr.GetNamespace(),
130+
Labels: labels,
131+
},
132+
Spec: corev1.PersistentVolumeClaimSpec{
133+
AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"},
134+
Resources: corev1.ResourceRequirements{
135+
Requests: corev1.ResourceList{
136+
corev1.ResourceStorage: storageCapacity,
137+
},
138+
},
139+
Selector: &metav1.LabelSelector{
140+
MatchLabels: map[string]string{
141+
"app.kubernetes.io/name": labels["app.kubernetes.io/name"],
142+
"app.kubernetes.io/instance": labels["app.kubernetes.io/instance"],
143+
},
138144
},
139145
},
140-
},
141-
}
142-
143-
// Assign storage class name if specified
144-
if storageClassName != "" {
145-
volumeClaim.Spec.StorageClassName = &storageClassName
146+
}
147+
} else {
148+
volumeClaim = corev1.PersistentVolumeClaim{
149+
ObjectMeta: metav1.ObjectMeta{
150+
Name: fmt.Sprintf(splcommon.PvcNamePrefix, volumeType),
151+
Namespace: cr.GetNamespace(),
152+
Labels: labels,
153+
},
154+
Spec: corev1.PersistentVolumeClaimSpec{
155+
AccessModes: []corev1.PersistentVolumeAccessMode{"ReadWriteOnce"},
156+
Resources: corev1.ResourceRequirements{
157+
Requests: corev1.ResourceList{
158+
corev1.ResourceStorage: storageCapacity,
159+
},
160+
},
161+
},
162+
}
146163
}
164+
147165
return volumeClaim, nil
148166
}
149167

@@ -483,7 +501,16 @@ func addSplunkVolumeToTemplate(podTemplateSpec *corev1.PodTemplateSpec, name str
483501
func addPVCVolumes(cr splcommon.MetaObject, spec *enterpriseApi.CommonSplunkSpec, statefulSet *appsv1.StatefulSet, labels map[string]string, volumeType string) error {
484502
// prepare and append persistent volume claims if storage is not ephemeral
485503
var err error
486-
volumeClaimTemplate, err := getSplunkVolumeClaims(cr, spec, labels, volumeType)
504+
var adminManagedPV bool
505+
506+
annotations := cr.GetAnnotations()
507+
508+
// determine if CR's PVs are managed by an admin
509+
if value, ok := annotations["enterprise.splunk.com/admin-managed-pv"]; ok && strings.ToLower(value) == "true" {
510+
adminManagedPV = true
511+
}
512+
513+
volumeClaimTemplate, err := getSplunkVolumeClaims(cr, spec, labels, volumeType, adminManagedPV)
487514
if err != nil {
488515
return err
489516
}

0 commit comments

Comments
 (0)