Repository: m3db/m3db-operator
Pull request #253 (2020-12-04 21:09:37)

Add support for adding sidecar containers
This commit adds support to the operator for adding sidecar containers to the pods that run the M3DB nodes.

codecov[bot]: # [Codecov](https://codecov.io/gh/m3db/m3db-operator/pull/253?src=pr&el=h1) Report
> Merging [#253](https://codecov.io/gh/m3db/m3db-operator/pull/253?src=pr&el=desc) (d2f26e6) into [master](https://codecov.io/gh/m3db/m3db-operator/commit/32f88b426d3356c23df8ce39c230862b0949e4ef?el=desc) (32f88b4) will **decrease** coverage by `0.06%`.
> The diff coverage is `50.00%`.


[![Impacted file tree graph](https://codecov.io/gh/m3db/m3db-operator/pull/253/graphs/tree.svg?width=650&height=150&src=pr&token=jtHDyWhsto)](https://codecov.io/gh/m3db/m3db-operator/pull/253?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #253      +/-   ##
==========================================
- Coverage   76.16%   76.09%   -0.07%     
==========================================
  Files          30       30              
  Lines        2240     2246       +6     
==========================================
+ Hits         1706     1709       +3     
- Misses        393      395       +2     
- Partials      141      142       +1     
```


------

[Continue to review full report at Codecov](https://codecov.io/gh/m3db/m3db-operator/pull/253?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/m3db/m3db-operator/pull/253?src=pr&el=footer). Last update [32f88b4...d2f26e6](https://codecov.io/gh/m3db/m3db-operator/pull/253?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/docs/api.md b/docs/api.md
index 8a060e6..73045cc 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -74,6 +74,8 @@ ClusterSpec defines the desired state for a M3 cluster to be converge to.
 | parallelPodManagement | ParallelPodManagement sets StatefulSets created by the operator to have Parallel pod management instead of OrderedReady. If nil, this will default to true. | *bool | true |
 | serviceAccountName | To use a non-default service account, specify the name here otherwise the service account \"default\" will be used. This is useful for advanced use-cases such as pod security policies. The service account must exist. This operator will not create it. | string | false |
 | frozen | Frozen is used to stop the operator from taking any further actions on a cluster. This is useful when troubleshooting as it guarantees the operator won't make any changes to the cluster. | bool | false |
+| sidecarContainers | SidecarContainers is used to add sidecar containers to the pods that run the cluster's nodes. If any storage volumes are needed by the sidecar containers, see SidecarVolumes below. | []corev1.Container | false |
+| sidecarVolumes | SidecarVolumes is used to add any volumes that are required by sidecar containers. | []corev1.Volume | false |
 
 [Back to TOC](#table-of-contents)
 
diff --git a/pkg/apis/m3dboperator/v1alpha1/cluster.go b/pkg/apis/m3dboperator/v1alpha1/cluster.go
index 123b35a..4455f14 100644
--- a/pkg/apis/m3dboperator/v1alpha1/cluster.go
+++ b/pkg/apis/m3dboperator/v1alpha1/cluster.go
@@ -310,6 +310,15 @@ type ClusterSpec struct {
 	// won't make any changes to the cluster.
 	// +optional
 	Frozen bool `json:"frozen,omitempty"`
+
+	// SidecarContainers is used to add sidecar containers to the pods that run
+	// the cluster's nodes. If any storage volumes are needed by the sidecar
+	// containers, see SidecarVolumes below.
+	SidecarContainers []corev1.Container `json:"sidecarContainers,omitempty"`
+
+	// SidecarVolumes is used to add any volumes that are required by sidecar
+	// containers.
+	SidecarVolumes []corev1.Volume `json:"sidecarVolumes,omitempty"`
 }
 
 // ExternalCoordinatorConfig defines parameters for using an external
diff --git a/pkg/apis/m3dboperator/v1alpha1/openapi_generated.go b/pkg/apis/m3dboperator/v1alpha1/openapi_generated.go
index 3644778..d7f4cb6 100644
--- a/pkg/apis/m3dboperator/v1alpha1/openapi_generated.go
+++ b/pkg/apis/m3dboperator/v1alpha1/openapi_generated.go
@@ -624,6 +624,32 @@ func schema_pkg_apis_m3dboperator_v1alpha1_ClusterSpec(ref common.ReferenceCallb
 							Format:      "",
 						},
 					},
+					"sidecarContainers": {
+						SchemaProps: spec.SchemaProps{
+							Description: "SidecarContainers is used to add sidecar containers to the pods that run the cluster's nodes. If any storage volumes are needed by the sidecar containers, see SidecarVolumes below.",
+							Type:        []string{"array"},
+							Items: &spec.SchemaOrArray{
+								Schema: &spec.Schema{
+									SchemaProps: spec.SchemaProps{
+										Ref: ref("k8s.io/api/core/v1.Container"),
+									},
+								},
+							},
+						},
+					},
+					"sidecarVolumes": {
+						SchemaProps: spec.SchemaProps{
+							Description: "SidecarVolumes is used to add any volumes that are required by sidecar containers.",
+							Type:        []string{"array"},
+							Items: &spec.SchemaOrArray{
+								Schema: &spec.Schema{
+									SchemaProps: spec.SchemaProps{
+										Ref: ref("k8s.io/api/core/v1.Volume"),
+									},
+								},
+							},
+						},
+					},
 				},
 				Required: []string{"parallelPodManagement"},
 			},
diff --git a/pkg/apis/m3dboperator/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/m3dboperator/v1alpha1/zz_generated.deepcopy.go
index 645ead7..95c91b8 100644
--- a/pkg/apis/m3dboperator/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/m3dboperator/v1alpha1/zz_generated.deepcopy.go
@@ -217,6 +217,20 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
 		*out = new(bool)
 		**out = **in
 	}
+	if in.SidecarContainers != nil {
+		in, out := &in.SidecarContainers, &out.SidecarContainers
+		*out = make([]v1.Container, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+	if in.SidecarVolumes != nil {
+		in, out := &in.SidecarVolumes, &out.SidecarVolumes
+		*out = make([]v1.Volume, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
 	return
 }
 
diff --git a/pkg/k8sops/m3db/generators.go b/pkg/k8sops/m3db/generators.go
index 3e3bd06..0b00aa0 100644
--- a/pkg/k8sops/m3db/generators.go
+++ b/pkg/k8sops/m3db/generators.go
@@ -205,6 +205,16 @@ func GenerateStatefulSet(
 		statefulSet.Spec.Template.Spec.Volumes = append(statefulSet.Spec.Template.Spec.Volumes, cluster.Spec.InitVolumes...)
 	}
 
+	if cluster.Spec.SidecarContainers != nil && len(cluster.Spec.SidecarContainers) > 0 {
+		cluster := cluster.DeepCopy()
+		statefulSet.Spec.Template.Spec.Containers = append(statefulSet.Spec.Template.Spec.Containers, cluster.Spec.SidecarContainers...)
+	}
+
+	if cluster.Spec.SidecarVolumes != nil && len(cluster.Spec.SidecarVolumes) > 0 {
+		cluster := cluster.DeepCopy()
+		statefulSet.Spec.Template.Spec.Volumes = append(statefulSet.Spec.Template.Spec.Volumes, cluster.Spec.SidecarVolumes...)
+	}
+
 	return statefulSet, nil
 }
 


Test patch:
diff --git a/pkg/k8sops/m3db/generators_test.go b/pkg/k8sops/m3db/generators_test.go
index 4adfcf1..77160d2 100644
--- a/pkg/k8sops/m3db/generators_test.go
+++ b/pkg/k8sops/m3db/generators_test.go
@@ -505,6 +505,36 @@ func TestGenerateStatefulSet(t *testing.T) {
 		t.Log(diff)
 		t.Log(fixture.Spec.ParallelPodManagement)
 	}
+
+	// Test sidecar containers and volumes.
+	fixture = getFixture("testM3DBCluster.yaml", t)
+	fixture.Spec.SidecarContainers = []v1.Container{
+		{
+			Name: "sidecar0",
+		},
+	}
+	fixture.Spec.SidecarVolumes = []v1.Volume{
+		{
+			Name: "sidecar0",
+		},
+	}
+
+	ss = baseSS.DeepCopy()
+
+	var (
+		sidecar = v1.Container{Name: "sidecar0"}
+		volume  = v1.Volume{Name: "sidecar0"}
+	)
+	ss.Spec.Template.Spec.Containers = append(ss.Spec.Template.Spec.Containers, sidecar)
+	ss.Spec.Template.Spec.Volumes = append(ss.Spec.Template.Spec.Volumes, volume)
+
+	newSS, err = GenerateStatefulSet(fixture, isolationGroup, *instanceAmount)
+	assert.NoError(t, err)
+	assert.NotNil(t, newSS)
+	if !assert.Equal(t, ss, newSS) {
+		diff, _ := messagediff.PrettyDiff(ss, newSS)
+		t.Log(diff)
+	}
 }
 
 func TestGenerateM3DBService(t *testing.T) {