Repository: m3db/m3db-operator
Pull request #225 (2020-07-13 14:24:35)

[api] Support custom svc account for M3DB pods
Add ServiceAccountName to the ClusterSpec for cases where the user does not want to run with the default service account such as pods running under pod security policies.

codecov[bot]: # [Codecov](https://codecov.io/gh/m3db/m3db-operator/pull/225?src=pr&el=h1) Report
> Merging [#225](https://codecov.io/gh/m3db/m3db-operator/pull/225?src=pr&el=desc) into [master](https://codecov.io/gh/m3db/m3db-operator/commit/b0c67de952de8bca884260c17045cd9272b00f32&el=desc) will **decrease** coverage by `0.08%`.
> The diff coverage is `100.00%`.


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

```diff
@@            Coverage Diff             @@
##           master     #225      +/-   ##
==========================================
- Coverage   75.62%   75.54%   -0.09%     
==========================================
  Files          30       30              
  Lines        2113     2114       +1     
==========================================
- Hits         1598     1597       -1     
- Misses        390      391       +1     
- Partials      125      126       +1     
```


------

[Continue to review full report at Codecov](https://codecov.io/gh/m3db/m3db-operator/pull/225?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/225?src=pr&el=footer). Last update [b0c67de...8c5a0de](https://codecov.io/gh/m3db/m3db-operator/pull/225?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 2581edf..8cbe22d 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -68,6 +68,7 @@ ClusterSpec defines the desired state for a M3 cluster to be converge to.
 | initVolumes | If the InitContainers require any storage volumes Provide the complete specification for the required Volumes here | []corev1.Volume | false |
 | podMetadata | PodMetadata is for any Metadata that is unique to the pods, and does not belong on any other objects, such as Prometheus scrape tags | [metav1.ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/#objectmeta-v1-meta) | false |
 | parallelPodManagement | ParallelPodManagement sets StatefulSets created by the operator to have Parallel pod management instead of OrderedReady. This is an EXPERIMENTAL flag and subject to deprecation in a future release. This has not been tested in production and users should not depend on it without validating it for their own use case. | 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 |
 
 [Back to TOC](#table-of-contents)
 
diff --git a/go.sum b/go.sum
index b4ef31c..a932539 100644
--- a/go.sum
+++ b/go.sum
@@ -839,6 +839,7 @@ k8s.io/apiextensions-apiserver v0.17.2 h1:cP579D2hSZNuO/rZj9XFRzwJNYb41DbNANJb6K
 k8s.io/apiextensions-apiserver v0.17.2/go.mod h1:4KdMpjkEjjDI2pPfBA15OscyNldHWdBCfsWMDWAmSTs=
 k8s.io/apimachinery v0.17.2 h1:hwDQQFbdRlpnnsR64Asdi55GyCaIP/3WQpMmbNBeWr4=
 k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg=
+k8s.io/apimachinery v0.18.5 h1:Lh6tgsM9FMkC12K5T5QjRm7rDs6aQN5JHkA0JomULDM=
 k8s.io/apiserver v0.17.2/go.mod h1:lBmw/TtQdtxvrTk0e2cgtOxHizXI+d0mmGQURIHQZlo=
 k8s.io/client-go v0.17.2 h1:ndIfkfXEGrNhLIgkr0+qhRguSD3u6DCmonepn1O6NYc=
 k8s.io/client-go v0.17.2/go.mod h1:QAzRgsa0C2xl4/eVpeVAZMvikCn8Nm81yqVx3Kk9XYI=
diff --git a/pkg/apis/m3dboperator/v1alpha1/cluster.go b/pkg/apis/m3dboperator/v1alpha1/cluster.go
index 2344e56..d76b3d5 100644
--- a/pkg/apis/m3dboperator/v1alpha1/cluster.go
+++ b/pkg/apis/m3dboperator/v1alpha1/cluster.go
@@ -300,6 +300,12 @@ type ClusterSpec struct {
 	// tested in production and users should not depend on it without validating
 	// it for their own use case.
 	ParallelPodManagement bool `json:"parallelPodManagement,omitEmpty"`
+
+	// 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.
+	ServiceAccountName string `json:"serviceAccountName,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 93f3a2d..5b012de 100644
--- a/pkg/apis/m3dboperator/v1alpha1/openapi_generated.go
+++ b/pkg/apis/m3dboperator/v1alpha1/openapi_generated.go
@@ -610,6 +610,13 @@ func schema_pkg_apis_m3dboperator_v1alpha1_ClusterSpec(ref common.ReferenceCallb
 							Format:      "",
 						},
 					},
+					"serviceAccountName": {
+						SchemaProps: spec.SchemaProps{
+							Description: "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.",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
 				},
 				Required: []string{"parallelPodManagement"},
 			},
diff --git a/pkg/k8sops/m3db/statefulset.go b/pkg/k8sops/m3db/statefulset.go
index efdb106..8a2c5b3 100644
--- a/pkg/k8sops/m3db/statefulset.go
+++ b/pkg/k8sops/m3db/statefulset.go
@@ -174,6 +174,7 @@ func NewBaseStatefulSet(ssName, isolationGroup string, cluster *myspec.M3DBClust
 					},
 					generateDownwardAPIVolume(),
 				},
+				ServiceAccountName: cluster.Spec.ServiceAccountName,
 			},
 		},
 	}


Test patch:
diff --git a/pkg/k8sops/m3db/fixtures/testM3DBCluster.yaml b/pkg/k8sops/m3db/fixtures/testM3DBCluster.yaml
index a44a065..f7ba65b 100644
--- a/pkg/k8sops/m3db/fixtures/testM3DBCluster.yaml
+++ b/pkg/k8sops/m3db/fixtures/testM3DBCluster.yaml
@@ -9,6 +9,7 @@ spec:
   replicationFactor: 3
   numberOfShards: 8
   enableCarbonIngester: true
+  serviceAccountName: "m3db-account1"
   imagePullSecrets:
   - name: secret1
   isolationGroups:
diff --git a/pkg/k8sops/m3db/generators_test.go b/pkg/k8sops/m3db/generators_test.go
index bdb26b9..06f598f 100644
--- a/pkg/k8sops/m3db/generators_test.go
+++ b/pkg/k8sops/m3db/generators_test.go
@@ -270,6 +270,7 @@ func TestGenerateStatefulSet(t *testing.T) {
 							Operator: "Exists",
 						},
 					},
+					ServiceAccountName: "m3db-account1",
 				},
 			},
 			VolumeClaimTemplates: []v1.PersistentVolumeClaim{
diff --git a/pkg/k8sops/m3db/statefulset_test.go b/pkg/k8sops/m3db/statefulset_test.go
index 207ee76..d345fc2 100644
--- a/pkg/k8sops/m3db/statefulset_test.go
+++ b/pkg/k8sops/m3db/statefulset_test.go
@@ -38,6 +38,8 @@ func TestStatefulSet(t *testing.T) {
 
 	ssName := StatefulSetName(fixture.GetName(), 0)
 	require.Equal(t, "m3db-cluster-rep0", ssName)
+
+	require.Equal(t, "m3db-account1", fixture.Spec.ServiceAccountName)
 }
 
 func TestGenerateDownwardAPIVolume(t *testing.T) {