Skip to content

Commit 9921d0d

Browse files
committed
Allow customization of serviceAccountName for pods
1 parent aa7e63e commit 9921d0d

File tree

6 files changed

+54
-12
lines changed

6 files changed

+54
-12
lines changed

pkg/apis/deployment/v1alpha/server_group_spec.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"k8s.io/apimachinery/pkg/api/resource"
2929

3030
"github.com/arangodb/kube-arangodb/pkg/util"
31+
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
3132
)
3233

3334
// ServerGroupSpec contains the specification for all servers in a specific group (e.g. all agents)
@@ -42,6 +43,8 @@ type ServerGroupSpec struct {
4243
Resources v1.ResourceRequirements `json:"resources,omitempty"`
4344
// Tolerations specifies the tolerations added to Pods in this group.
4445
Tolerations []v1.Toleration `json:"tolerations,omitempty"`
46+
// ServiceAccountName specifies the name of the service account used for Pods in this group.
47+
ServiceAccountName *string `json:"serviceAccountName,omitempty"`
4548
}
4649

4750
// GetCount returns the value of count.
@@ -64,6 +67,11 @@ func (s ServerGroupSpec) GetTolerations() []v1.Toleration {
6467
return s.Tolerations
6568
}
6669

70+
// GetServiceAccountName returns the value of serviceAccountName.
71+
func (s ServerGroupSpec) GetServiceAccountName() string {
72+
return util.StringOrDefault(s.ServiceAccountName)
73+
}
74+
6775
// Validate the given group spec
6876
func (s ServerGroupSpec) Validate(group ServerGroup, used bool, mode DeploymentMode, env Environment) error {
6977
if used {
@@ -86,6 +94,16 @@ func (s ServerGroupSpec) Validate(group ServerGroup, used bool, mode DeploymentM
8694
if s.GetCount() > 1 && group == ServerGroupSingle && mode == DeploymentModeSingle {
8795
return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected 1", s.GetCount()))
8896
}
97+
if name := s.GetServiceAccountName(); name != "" {
98+
if err := k8sutil.ValidateOptionalResourceName(name); err != nil {
99+
return maskAny(errors.Wrapf(ValidationError, "Invalid serviceAccountName: %s", err))
100+
}
101+
}
102+
if name := s.GetStorageClassName(); name != "" {
103+
if err := k8sutil.ValidateOptionalResourceName(name); err != nil {
104+
return maskAny(errors.Wrapf(ValidationError, "Invalid storageClassName: %s", err))
105+
}
106+
}
89107
} else if s.GetCount() != 0 {
90108
return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d for un-used group. Expected 0", s.GetCount()))
91109
}
@@ -143,6 +161,9 @@ func (s *ServerGroupSpec) SetDefaultsFrom(source ServerGroupSpec) {
143161
if s.Tolerations == nil {
144162
s.Tolerations = source.Tolerations
145163
}
164+
if s.ServiceAccountName == nil {
165+
s.ServiceAccountName = util.NewStringOrNil(source.ServiceAccountName)
166+
}
146167
setDefaultsFromResourceList(&s.Resources.Limits, source.Resources.Limits)
147168
setDefaultsFromResourceList(&s.Resources.Requests, source.Resources.Requests)
148169
}

pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,15 @@ func (in *ServerGroupSpec) DeepCopyInto(out *ServerGroupSpec) {
597597
(*in)[i].DeepCopyInto(&(*out)[i])
598598
}
599599
}
600+
if in.ServiceAccountName != nil {
601+
in, out := &in.ServiceAccountName, &out.ServiceAccountName
602+
if *in == nil {
603+
*out = nil
604+
} else {
605+
*out = new(string)
606+
**out = **in
607+
}
608+
}
600609
return
601610
}
602611

pkg/deployment/images.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,10 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, ima
176176
tolerations = k8sutil.AddTolerationIfNotFound(tolerations, k8sutil.NewNoExecuteToleration(k8sutil.TolerationKeyNodeNotReady, shortDur))
177177
tolerations = k8sutil.AddTolerationIfNotFound(tolerations, k8sutil.NewNoExecuteToleration(k8sutil.TolerationKeyNodeUnreachable, shortDur))
178178
tolerations = k8sutil.AddTolerationIfNotFound(tolerations, k8sutil.NewNoExecuteToleration(k8sutil.TolerationKeyNodeAlphaUnreachable, shortDur))
179+
serviceAccountName := ""
179180

180-
if err := k8sutil.CreateArangodPod(ib.KubeCli, true, ib.APIObject, role, id, podName, "", image, "", ib.Spec.GetImagePullPolicy(), "", false, terminationGracePeriod, args, nil, nil, nil, nil, tolerations, "", ""); err != nil {
181+
if err := k8sutil.CreateArangodPod(ib.KubeCli, true, ib.APIObject, role, id, podName, "", image, "", ib.Spec.GetImagePullPolicy(), "", false, terminationGracePeriod, args, nil, nil, nil, nil,
182+
tolerations, serviceAccountName, "", ""); err != nil {
181183
log.Debug().Err(err).Msg("Failed to create image ID pod")
182184
return true, maskAny(err)
183185
}

pkg/deployment/reconcile/plan_builder.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ func podNeedsUpgrading(p v1.Pod, spec api.DeploymentSpec, images api.ImageInfoLi
263263
// When true is returned, a reason for the rotation is already returned.
264264
func podNeedsRotation(p v1.Pod, apiObject metav1.Object, spec api.DeploymentSpec,
265265
group api.ServerGroup, agents api.MemberStatusList, id string) (bool, string) {
266+
groupSpec := spec.GetServerGroupSpec(group)
267+
266268
// Check image pull policy
267269
if c, found := k8sutil.GetContainerByName(&p, k8sutil.ServerContainerName); found {
268270
if c.ImagePullPolicy != spec.GetImagePullPolicy() {
@@ -271,6 +273,7 @@ func podNeedsRotation(p v1.Pod, apiObject metav1.Object, spec api.DeploymentSpec
271273
} else {
272274
return true, "Server container not found"
273275
}
276+
274277
// Check arguments
275278
/*expectedArgs := createArangodArgs(apiObject, spec, group, agents, id)
276279
if len(expectedArgs) != len(c.Args) {
@@ -282,6 +285,11 @@ func podNeedsRotation(p v1.Pod, apiObject metav1.Object, spec api.DeploymentSpec
282285
}
283286
}*/
284287

288+
// Check service account
289+
if p.Spec.ServiceAccountName != groupSpec.GetServiceAccountName() {
290+
return true, "ServiceAccountName changed"
291+
}
292+
285293
return false, ""
286294
}
287295

pkg/deployment/resources/pod_creator.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, group api.Server
438438
lifecycleImage := r.context.GetLifecycleImage()
439439
terminationGracePeriod := group.DefaultTerminationGracePeriod()
440440
tolerations := r.createPodTolerations(group, groupSpec)
441+
serviceAccountName := groupSpec.GetServiceAccountName()
441442

442443
// Update pod name
443444
role := group.AsRole()
@@ -500,7 +501,7 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, group api.Server
500501
requireUUID := group == api.ServerGroupDBServers && m.IsInitialized
501502
finalizers := r.createPodFinalizers(group)
502503
if err := k8sutil.CreateArangodPod(kubecli, spec.IsDevelopment(), apiObject, role, m.ID, m.PodName, m.PersistentVolumeClaimName, info.ImageID, lifecycleImage, spec.GetImagePullPolicy(),
503-
engine, requireUUID, terminationGracePeriod, args, env, finalizers, livenessProbe, readinessProbe, tolerations, tlsKeyfileSecretName, rocksdbEncryptionSecretName); err != nil {
504+
engine, requireUUID, terminationGracePeriod, args, env, finalizers, livenessProbe, readinessProbe, tolerations, serviceAccountName, tlsKeyfileSecretName, rocksdbEncryptionSecretName); err != nil {
504505
return maskAny(err)
505506
}
506507
log.Debug().Str("pod-name", m.PodName).Msg("Created pod")
@@ -571,7 +572,7 @@ func (r *Resources) createPodForMember(spec api.DeploymentSpec, group api.Server
571572
affinityWithRole = api.ServerGroupDBServers.AsRole()
572573
}
573574
if err := k8sutil.CreateArangoSyncPod(kubecli, spec.IsDevelopment(), apiObject, role, m.ID, m.PodName, info.ImageID, lifecycleImage, spec.Sync.GetImagePullPolicy(), terminationGracePeriod, args, env,
574-
livenessProbe, tolerations, tlsKeyfileSecretName, clientAuthCASecretName, masterJWTSecretName, clusterJWTSecretName, affinityWithRole); err != nil {
575+
livenessProbe, tolerations, serviceAccountName, tlsKeyfileSecretName, clientAuthCASecretName, masterJWTSecretName, clusterJWTSecretName, affinityWithRole); err != nil {
575576
return maskAny(err)
576577
}
577578
log.Debug().Str("pod-name", m.PodName).Msg("Created pod")

pkg/util/k8sutil/pods.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ func initLifecycleContainer(image string) (v1.Container, error) {
384384
}
385385

386386
// newPod creates a basic Pod for given settings.
387-
func newPod(deploymentName, ns, role, id, podName string, finalizers []string, tolerations []v1.Toleration) v1.Pod {
387+
func newPod(deploymentName, ns, role, id, podName string, finalizers []string, tolerations []v1.Toleration, serviceAccountName string) v1.Pod {
388388
hostname := CreatePodHostName(deploymentName, role, id)
389389
p := v1.Pod{
390390
ObjectMeta: metav1.ObjectMeta{
@@ -393,10 +393,11 @@ func newPod(deploymentName, ns, role, id, podName string, finalizers []string, t
393393
Finalizers: finalizers,
394394
},
395395
Spec: v1.PodSpec{
396-
Hostname: hostname,
397-
Subdomain: CreateHeadlessServiceName(deploymentName),
398-
RestartPolicy: v1.RestartPolicyNever,
399-
Tolerations: tolerations,
396+
Hostname: hostname,
397+
Subdomain: CreateHeadlessServiceName(deploymentName),
398+
RestartPolicy: v1.RestartPolicyNever,
399+
Tolerations: tolerations,
400+
ServiceAccountName: serviceAccountName,
400401
},
401402
}
402403
return p
@@ -409,10 +410,10 @@ func CreateArangodPod(kubecli kubernetes.Interface, developmentMode bool, deploy
409410
role, id, podName, pvcName, image, lifecycleImage string, imagePullPolicy v1.PullPolicy,
410411
engine string, requireUUID bool, terminationGracePeriod time.Duration,
411412
args []string, env map[string]EnvValue, finalizers []string,
412-
livenessProbe *HTTPProbeConfig, readinessProbe *HTTPProbeConfig, tolerations []v1.Toleration,
413+
livenessProbe *HTTPProbeConfig, readinessProbe *HTTPProbeConfig, tolerations []v1.Toleration, serviceAccountName string,
413414
tlsKeyfileSecretName, rocksdbEncryptionSecretName string) error {
414415
// Prepare basic pod
415-
p := newPod(deployment.GetName(), deployment.GetNamespace(), role, id, podName, finalizers, tolerations)
416+
p := newPod(deployment.GetName(), deployment.GetNamespace(), role, id, podName, finalizers, tolerations, serviceAccountName)
416417
terminationGracePeriodSeconds := int64(math.Ceil(terminationGracePeriod.Seconds()))
417418
p.Spec.TerminationGracePeriodSeconds = &terminationGracePeriodSeconds
418419

@@ -510,10 +511,10 @@ func CreateArangodPod(kubecli kubernetes.Interface, developmentMode bool, deploy
510511
// If the pod already exists, nil is returned.
511512
// If another error occurs, that error is returned.
512513
func CreateArangoSyncPod(kubecli kubernetes.Interface, developmentMode bool, deployment APIObject, role, id, podName, image, lifecycleImage string, imagePullPolicy v1.PullPolicy,
513-
terminationGracePeriod time.Duration, args []string, env map[string]EnvValue, livenessProbe *HTTPProbeConfig, tolerations []v1.Toleration,
514+
terminationGracePeriod time.Duration, args []string, env map[string]EnvValue, livenessProbe *HTTPProbeConfig, tolerations []v1.Toleration, serviceAccountName string,
514515
tlsKeyfileSecretName, clientAuthCASecretName, masterJWTSecretName, clusterJWTSecretName, affinityWithRole string) error {
515516
// Prepare basic pod
516-
p := newPod(deployment.GetName(), deployment.GetNamespace(), role, id, podName, nil, tolerations)
517+
p := newPod(deployment.GetName(), deployment.GetNamespace(), role, id, podName, nil, tolerations, serviceAccountName)
517518
terminationGracePeriodSeconds := int64(math.Ceil(terminationGracePeriod.Seconds()))
518519
p.Spec.TerminationGracePeriodSeconds = &terminationGracePeriodSeconds
519520

0 commit comments

Comments
 (0)