Turn ServiceAccount into struct value to avoid race conditon during account creation
This commit is contained in:
parent
a5a65e93f4
commit
bd51d2922b
|
|
@ -197,28 +197,30 @@ func (c *Cluster) initUsers() error {
|
||||||
/*
|
/*
|
||||||
Ensures the service account required by StatefulSets to create pods exists in a namespace before a PG cluster is created there so that a user does not have to deploy the account manually.
|
Ensures the service account required by StatefulSets to create pods exists in a namespace before a PG cluster is created there so that a user does not have to deploy the account manually.
|
||||||
|
|
||||||
The operator does not sync these accounts.
|
The operator does not sync these accounts after creation.
|
||||||
*/
|
*/
|
||||||
func (c *Cluster) createPodServiceAccounts() error {
|
func (c *Cluster) createPodServiceAccounts() error {
|
||||||
|
|
||||||
podServiceAccount := c.Config.OpConfig.PodServiceAccountName
|
podServiceAccountName := c.Config.OpConfig.PodServiceAccountName
|
||||||
c.setProcessName("creating pod service account in the watched namespaces")
|
c.setProcessName("creating pod service account in the watched namespaces")
|
||||||
|
|
||||||
_, err := c.KubeClient.ServiceAccounts(c.Namespace).Get(podServiceAccount, metav1.GetOptions{})
|
_, err := c.KubeClient.ServiceAccounts(c.Namespace).Get(podServiceAccountName, metav1.GetOptions{})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Warnf("the pod service account %q is absent from the namespace %q. Stateful sets in the namespace are unable to create pods.", podServiceAccount, c.Namespace)
|
c.logger.Warnf("the pod service account %q is absent from the namespace %q. Stateful sets in the namespace are unable to create pods.", podServiceAccountName, c.Namespace)
|
||||||
|
|
||||||
|
// when created, each Cluster struct gets a separate copy of OpConfig
|
||||||
|
// including the nested PodServiceAccount struct, so no race condition here
|
||||||
c.OpConfig.PodServiceAccount.SetNamespace(c.Namespace)
|
c.OpConfig.PodServiceAccount.SetNamespace(c.Namespace)
|
||||||
|
|
||||||
_, err = c.KubeClient.ServiceAccounts(c.Namespace).Create(c.OpConfig.PodServiceAccount)
|
_, err = c.KubeClient.ServiceAccounts(c.Namespace).Create(&c.OpConfig.PodServiceAccount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Warnf("cannot deploy the pod service account %q defined in the config map to the %q namespace: %v", podServiceAccount, c.Namespace, err)
|
c.logger.Warnf("cannot deploy the pod service account %q defined in the config map to the %q namespace: %v", podServiceAccountName, c.Namespace, err)
|
||||||
} else {
|
} else {
|
||||||
c.logger.Infof("successfully deployed the pod service account %q to the %q namespace", podServiceAccount, c.Namespace)
|
c.logger.Infof("successfully deployed the pod service account %q to the %q namespace", podServiceAccountName, c.Namespace)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.logger.Infof("successfully found the service account %q used to create pods to the namespace %q", podServiceAccount, c.Namespace)
|
c.logger.Infof("successfully found the service account %q used to create pods to the namespace %q", podServiceAccountName, c.Namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ func (c *Controller) initPodServiceAccount() {
|
||||||
case groupVersionKind.Kind != "ServiceAccount":
|
case groupVersionKind.Kind != "ServiceAccount":
|
||||||
panic(fmt.Errorf("pod service account definiton in the operator config map defines another type of resource: %v", groupVersionKind.Kind))
|
panic(fmt.Errorf("pod service account definiton in the operator config map defines another type of resource: %v", groupVersionKind.Kind))
|
||||||
default:
|
default:
|
||||||
c.opConfig.PodServiceAccount = obj.(*v1.ServiceAccount)
|
c.opConfig.PodServiceAccount = *obj.(*v1.ServiceAccount)
|
||||||
// ensure consistent naming of the account
|
// ensure consistent naming of the account
|
||||||
c.opConfig.PodServiceAccount.Name = c.opConfig.PodServiceAccountName
|
c.opConfig.PodServiceAccount.Name = c.opConfig.PodServiceAccountName
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,10 +68,10 @@ type Config struct {
|
||||||
Resources
|
Resources
|
||||||
Auth
|
Auth
|
||||||
Scalyr
|
Scalyr
|
||||||
PodServiceAccount *v1.ServiceAccount
|
PodServiceAccount v1.ServiceAccount // has to be struct value, not a pointer
|
||||||
WatchedNamespace string `name:"watched_namespace"` // special values: "*" means 'watch all namespaces', the empty string "" means 'watch a namespace where operator is deployed to'
|
WatchedNamespace string `name:"watched_namespace"` // special values: "*" means 'watch all namespaces', the empty string "" means 'watch a namespace where operator is deployed to'
|
||||||
EtcdHost string `name:"etcd_host" default:"etcd-client.default.svc.cluster.local:2379"`
|
EtcdHost string `name:"etcd_host" default:"etcd-client.default.svc.cluster.local:2379"`
|
||||||
DockerImage string `name:"docker_image" default:"registry.opensource.zalan.do/acid/spiloprivate-9.6:1.2-p4"`
|
DockerImage string `name:"docker_image" default:"registry.opensource.zalan.do/acid/spiloprivate-9.6:1.2-p4"`
|
||||||
// re-use one account for both Spilo pods and the operator; this grants extra privileges to pods
|
// re-use one account for both Spilo pods and the operator; this grants extra privileges to pods
|
||||||
ServiceAccountName string `name:"service_account_name" default:"operator"`
|
ServiceAccountName string `name:"service_account_name" default:"operator"`
|
||||||
PodServiceAccountName string `name:"pod_service_account_name" default:"operator"`
|
PodServiceAccountName string `name:"pod_service_account_name" default:"operator"`
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue