Use one secret per user
This commit is contained in:
parent
abb1173035
commit
7e4d0410c2
|
|
@ -15,7 +15,7 @@ import (
|
|||
"github.bus.zalan.do/acid/postgres-operator/pkg/util/constants"
|
||||
)
|
||||
|
||||
var patroniUsers = []string{"superuser", "replication", "admin"}
|
||||
var patroniUsers = []string{"superuser", "replication"}
|
||||
|
||||
//TODO: remove struct duplication
|
||||
type Config struct {
|
||||
|
|
@ -34,8 +34,7 @@ type Cluster struct {
|
|||
}
|
||||
|
||||
type pgUser struct {
|
||||
username string
|
||||
secretKey string
|
||||
username []byte
|
||||
password []byte
|
||||
flags []string
|
||||
}
|
||||
|
|
@ -58,15 +57,26 @@ func New(cfg Config, spec *spec.Postgresql) *Cluster {
|
|||
return cluster
|
||||
}
|
||||
|
||||
func secretUserKey(userName string) string {
|
||||
return fmt.Sprintf("%s-password", userName)
|
||||
func (c *Cluster) labels() map[string]string {
|
||||
return map[string]string{
|
||||
"application": "spilo",
|
||||
"spilo-cluster": (*c.cluster).Metadata.Name,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cluster) credentialSecretName(userName string) string {
|
||||
return fmt.Sprintf(
|
||||
"%s.%s.credentials.%s.%s",
|
||||
userName,
|
||||
(*c.cluster).Metadata.Name,
|
||||
constants.TPRName,
|
||||
constants.TPRVendor)
|
||||
}
|
||||
|
||||
func (c *Cluster) init() {
|
||||
for _, userName := range patroniUsers {
|
||||
user := pgUser{
|
||||
username: userName,
|
||||
secretKey: secretUserKey(userName),
|
||||
username: []byte(userName),
|
||||
password: util.RandomPasswordBytes(constants.PasswordLength),
|
||||
}
|
||||
c.pgUsers = append(c.pgUsers, user)
|
||||
|
|
@ -74,8 +84,7 @@ func (c *Cluster) init() {
|
|||
|
||||
for userName, userFlags := range (*c.cluster.Spec).Users {
|
||||
user := pgUser{
|
||||
username: userName,
|
||||
secretKey: secretUserKey(userName),
|
||||
username: []byte(userName),
|
||||
password: util.RandomPasswordBytes(constants.PasswordLength),
|
||||
flags: userFlags,
|
||||
}
|
||||
|
|
@ -145,9 +154,19 @@ func (c *Cluster) Delete() error {
|
|||
c.logger.Infof("Service %s.%s has been deleted\n", service.Namespace, service.Name)
|
||||
}
|
||||
|
||||
err = kubeClient.Secrets(nameSpace).Delete(clusterName, deleteOptions)
|
||||
secretsList, err := kubeClient.Secrets(nameSpace).List(listOptions)
|
||||
if err != nil {
|
||||
c.logger.Errorf("Error while deleting Secret %s: %+v", clusterName, err)
|
||||
return err
|
||||
}
|
||||
for _, secret := range secretsList.Items {
|
||||
err = kubeClient.Secrets(nameSpace).Delete(secret.Name, deleteOptions)
|
||||
if err != nil {
|
||||
c.logger.Errorf("Error while deleting Secret %s: %+v", secret.Name, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
c.logger.Infof("Secret %s.%s has been deleted\n", secret.Namespace, secret.Name)
|
||||
}
|
||||
|
||||
//TODO: delete key from etcd
|
||||
|
|
|
|||
|
|
@ -48,20 +48,9 @@ func (c *Cluster) createStatefulSet() {
|
|||
ValueFrom: &v1.EnvVarSource{
|
||||
SecretKeyRef: &v1.SecretKeySelector{
|
||||
LocalObjectReference: v1.LocalObjectReference{
|
||||
Name: clusterName,
|
||||
Name: c.credentialSecretName("superuser"),
|
||||
},
|
||||
Key: secretUserKey("superuser"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "PGPASSWORD_ADMIN",
|
||||
ValueFrom: &v1.EnvVarSource{
|
||||
SecretKeyRef: &v1.SecretKeySelector{
|
||||
LocalObjectReference: v1.LocalObjectReference{
|
||||
Name: clusterName,
|
||||
},
|
||||
Key: secretUserKey("admin"),
|
||||
Key: "password",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -70,9 +59,9 @@ func (c *Cluster) createStatefulSet() {
|
|||
ValueFrom: &v1.EnvVarSource{
|
||||
SecretKeyRef: &v1.SecretKeySelector{
|
||||
LocalObjectReference: v1.LocalObjectReference{
|
||||
Name: clusterName,
|
||||
Name: c.credentialSecretName("replication"),
|
||||
},
|
||||
Key: secretUserKey("replication"),
|
||||
Key: "password",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -129,10 +118,7 @@ func (c *Cluster) createStatefulSet() {
|
|||
|
||||
template := v1.PodTemplateSpec{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"application": "spilo",
|
||||
"spilo-cluster": clusterName,
|
||||
},
|
||||
Labels: c.labels(),
|
||||
Annotations: map[string]string{"pod.alpha.kubernetes.io/initialized": "true"},
|
||||
},
|
||||
Spec: podSpec,
|
||||
|
|
@ -141,10 +127,7 @@ func (c *Cluster) createStatefulSet() {
|
|||
statefulSet := &v1beta1.StatefulSet{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: clusterName,
|
||||
Labels: map[string]string{
|
||||
"application": "spilo",
|
||||
"spilo-cluster": clusterName,
|
||||
},
|
||||
Labels: c.labels(),
|
||||
},
|
||||
Spec: v1beta1.StatefulSetSpec{
|
||||
Replicas: &c.cluster.Spec.NumberOfInstances,
|
||||
|
|
@ -157,38 +140,35 @@ func (c *Cluster) createStatefulSet() {
|
|||
}
|
||||
|
||||
func (c *Cluster) applySecrets() {
|
||||
clusterName := (*c.cluster).Metadata.Name
|
||||
secrets := make(map[string][]byte, len(c.pgUsers))
|
||||
var err error
|
||||
for _, user := range c.pgUsers {
|
||||
secrets[user.secretKey] = user.password
|
||||
}
|
||||
|
||||
secret := v1.Secret{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: clusterName,
|
||||
Labels: map[string]string{
|
||||
"application": "spilo",
|
||||
"spilo-cluster": clusterName,
|
||||
},
|
||||
Name: c.credentialSecretName(string(user.username)),
|
||||
Labels: c.labels(),
|
||||
},
|
||||
Type: v1.SecretTypeOpaque,
|
||||
Data: secrets,
|
||||
Data: map[string][]byte{
|
||||
"username": user.username,
|
||||
"password": user.password,
|
||||
},
|
||||
}
|
||||
|
||||
_, err := c.config.KubeClient.Secrets(c.config.Namespace).Get(clusterName)
|
||||
|
||||
//TODO: possible race condition (as well as while creating the other objects)
|
||||
if !k8sutil.ResourceNotFound(err) {
|
||||
_, err = c.config.KubeClient.Secrets(c.config.Namespace).Update(&secret)
|
||||
} else {
|
||||
_, err = c.config.KubeClient.Secrets(c.config.Namespace).Create(&secret)
|
||||
}
|
||||
|
||||
if k8sutil.IsKubernetesResourceAlreadyExistError(err) {
|
||||
_, err = c.config.KubeClient.Secrets(c.config.Namespace).Update(&secret)
|
||||
if err != nil {
|
||||
c.logger.Errorf("Error while creating or updating secret: %+v", err)
|
||||
c.logger.Errorf("Error while updating secret: %+v", err)
|
||||
} else {
|
||||
c.logger.Infof("Secret updated: %+v", secret)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
c.logger.Errorf("Error while creating secret: %+v", err)
|
||||
} else {
|
||||
c.logger.Infof("Secret created: %+v", secret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: remove secrets of the deleted users
|
||||
}
|
||||
|
|
@ -205,10 +185,7 @@ func (c *Cluster) createService() {
|
|||
service := v1.Service{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: clusterName,
|
||||
Labels: map[string]string{
|
||||
"application": "spilo",
|
||||
"spilo-cluster": clusterName,
|
||||
},
|
||||
Labels: c.labels(),
|
||||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
Type: v1.ServiceTypeClusterIP,
|
||||
|
|
@ -236,10 +213,7 @@ func (c *Cluster) createEndPoint() {
|
|||
endPoint := v1.Endpoints{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: clusterName,
|
||||
Labels: map[string]string{
|
||||
"application": "spilo",
|
||||
"spilo-cluster": clusterName,
|
||||
},
|
||||
Labels: c.labels(),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
var passwordChars = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*=")
|
||||
var passwordChars = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$^&*=")
|
||||
|
||||
func init() {
|
||||
rand.Seed(int64(time.Now().Unix()))
|
||||
|
|
|
|||
Loading…
Reference in New Issue