125 lines
2.9 KiB
Go
125 lines
2.9 KiB
Go
package cluster
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/zalando-incubator/postgres-operator/pkg/spec"
|
|
"github.com/zalando-incubator/postgres-operator/pkg/util"
|
|
"k8s.io/api/core/v1"
|
|
)
|
|
|
|
var NoActions []Action = []Action{}
|
|
|
|
type Plan = []Action
|
|
|
|
type MetaData struct {
|
|
cluster *Cluster
|
|
}
|
|
|
|
type CreateSecret struct {
|
|
ActionSecret
|
|
}
|
|
|
|
func NewCreateSecret(username string, secret *v1.Secret, cluster *Cluster) CreateSecret {
|
|
return CreateSecret{ActionSecret{
|
|
meta: MetaData{
|
|
cluster: cluster,
|
|
},
|
|
secretUsername: username,
|
|
secret: secret,
|
|
}}
|
|
}
|
|
|
|
func NewUpdateSecret(username string, secret *v1.Secret, cluster *Cluster) UpdateSecret {
|
|
return UpdateSecret{ActionSecret{
|
|
meta: MetaData{
|
|
cluster: cluster,
|
|
},
|
|
secretUsername: username,
|
|
secret: secret,
|
|
}}
|
|
}
|
|
|
|
type UpdateSecret struct {
|
|
ActionSecret
|
|
}
|
|
|
|
type ActionSecret struct {
|
|
meta MetaData
|
|
secretUsername string
|
|
secret *v1.Secret
|
|
}
|
|
|
|
type Action interface {
|
|
Name() string
|
|
Validate() error
|
|
Apply() error
|
|
}
|
|
|
|
func (action CreateSecret) Apply() error {
|
|
cluster := action.meta.cluster
|
|
secret, err := cluster.KubeClient.
|
|
Secrets(action.secret.Namespace).
|
|
Create(action.secret)
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("Cannot apply action %s: %v", action.Name(), err)
|
|
}
|
|
|
|
cluster.Secrets[secret.UID] = secret
|
|
cluster.logger.Debugf(
|
|
"created new secret %q, uid: %q",
|
|
util.NameFromMeta(secret.ObjectMeta),
|
|
secret.UID)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (action ActionSecret) Validate() error {
|
|
if action.secret.Data["username"] == nil {
|
|
return fmt.Errorf("Field 'username' is empty for %v", action.secret)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (action CreateSecret) Name() string {
|
|
return fmt.Sprintf("Create secret %v", action.secret)
|
|
}
|
|
|
|
func (action UpdateSecret) Apply() error {
|
|
cluster := action.meta.cluster
|
|
user := cluster.getSecretUser(action.secretUsername)
|
|
|
|
// if this secret belongs to the infrastructure role and the password has
|
|
// changed, we need to replace it in the secret. Otherwise synchronize the
|
|
// information what we've got in the memory with the data from the secret
|
|
updateSecret := (user.Password != string(action.secret.Data["password"]) &&
|
|
user.Origin == spec.RoleOriginInfrastructure)
|
|
|
|
if updateSecret {
|
|
msg := "Updating the secret %q from the infrastructure roles"
|
|
name := util.NameFromMeta(action.secret.ObjectMeta)
|
|
cluster.logger.Debugf(msg, name)
|
|
|
|
_, err := cluster.KubeClient.
|
|
Secrets(action.secret.Namespace).
|
|
Update(action.secret)
|
|
|
|
if err != nil {
|
|
msg = "Could not update infrastructure role secret for role %q: %v"
|
|
return fmt.Errorf(msg, action.secretUsername, err)
|
|
}
|
|
} else {
|
|
// for non-infrastructure role - sync the in-memory data. For that we
|
|
// need to update password for the role with the value from the secret
|
|
user.Password = string(action.secret.Data["password"])
|
|
cluster.setSecretUser(action.secretUsername, user)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (action UpdateSecret) Name() string {
|
|
return fmt.Sprintf("Update secret %v", action.secret)
|
|
}
|