Add pod_environment_secret secrets to be injected to all clusters.
A potential mechanism to provide secrets to custom sidecars. Right now it is WIP and only provid secrets to Spilo Pods.
This commit is contained in:
parent
16a710a99a
commit
5cef7a5b45
|
|
@ -15,6 +15,7 @@ import (
|
||||||
|
|
||||||
"github.com/zalando-incubator/postgres-operator/pkg/spec"
|
"github.com/zalando-incubator/postgres-operator/pkg/spec"
|
||||||
"github.com/zalando-incubator/postgres-operator/pkg/util/constants"
|
"github.com/zalando-incubator/postgres-operator/pkg/util/constants"
|
||||||
|
"github.com/zalando-incubator/postgres-operator/pkg/util/k8sutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -319,6 +320,7 @@ func (c *Cluster) generatePodTemplate(
|
||||||
cloneDescription *spec.CloneDescription,
|
cloneDescription *spec.CloneDescription,
|
||||||
dockerImage *string,
|
dockerImage *string,
|
||||||
customPodEnvVars map[string]string,
|
customPodEnvVars map[string]string,
|
||||||
|
customPodSecrets map[string][]byte,
|
||||||
) *v1.PodTemplateSpec {
|
) *v1.PodTemplateSpec {
|
||||||
spiloConfiguration := c.generateSpiloJSONConfiguration(pgParameters, patroniParameters)
|
spiloConfiguration := c.generateSpiloJSONConfiguration(pgParameters, patroniParameters)
|
||||||
|
|
||||||
|
|
@ -426,11 +428,43 @@ func (c *Cluster) generatePodTemplate(
|
||||||
name, c.OpConfig.PodEnvironmentConfigMap)
|
name, c.OpConfig.PodEnvironmentConfigMap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(names)
|
sort.Strings(names)
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
envVars = append(envVars, v1.EnvVar{Name: name, Value: customPodEnvVars[name]})
|
envVars = append(envVars, v1.EnvVar{Name: name, Value: customPodEnvVars[name]})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: move the variable comparing and sorting code to a sepatate function
|
||||||
|
var secretVarNames []string
|
||||||
|
// include references to the secrets provided in the operator configuration.
|
||||||
|
// TODO: what happens with the secrets located in a different namespace?
|
||||||
|
if c.OpConfig.PodEnvironmentSecret != "" {
|
||||||
|
for secretVarName := range customPodSecrets {
|
||||||
|
// environment variable names have scricter rules than secrets
|
||||||
|
if !k8sutil.EnvironmentVariableNameIsValid(secretVarName) {
|
||||||
|
c.logger.Warningf("Secret key %s cannot be a name of an environment variable")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := envVarsMap[secretVarName]; !ok {
|
||||||
|
secretVarNames = append(secretVarNames, secretVarName)
|
||||||
|
} else {
|
||||||
|
c.logger.Warningf("variable %q value from %q is ignored: conflict with the definition from the operator",
|
||||||
|
secretVarNames, c.OpConfig.PodEnvironmentConfigMap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(secretVarNames)
|
||||||
|
for _, name := range secretVarNames {
|
||||||
|
envVars = append(envVars, v1.EnvVar{Name: name, ValueFrom: &v1.EnvVarSource{
|
||||||
|
SecretKeyRef: &v1.SecretKeySelector{
|
||||||
|
LocalObjectReference: v1.LocalObjectReference{
|
||||||
|
Name: c.OpConfig.PodEnvironmentSecret,
|
||||||
|
},
|
||||||
|
Key: name,
|
||||||
|
},
|
||||||
|
}})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
privilegedMode := true
|
privilegedMode := true
|
||||||
containerImage := c.OpConfig.DockerImage
|
containerImage := c.OpConfig.DockerImage
|
||||||
if dockerImage != nil && *dockerImage != "" {
|
if dockerImage != nil && *dockerImage != "" {
|
||||||
|
|
@ -575,7 +609,11 @@ func (c *Cluster) generateStatefulSet(spec *spec.PostgresSpec) (*v1beta1.Statefu
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not generate Scalyr sidecar resource requirements: %v", err)
|
return nil, fmt.Errorf("could not generate Scalyr sidecar resource requirements: %v", err)
|
||||||
}
|
}
|
||||||
var customPodEnvVars map[string]string
|
var (
|
||||||
|
customPodEnvVars map[string]string
|
||||||
|
customPodSecrets map[string][]byte
|
||||||
|
)
|
||||||
|
// TODO: pod environment configmaps are read from the cluster namespace
|
||||||
if c.OpConfig.PodEnvironmentConfigMap != "" {
|
if c.OpConfig.PodEnvironmentConfigMap != "" {
|
||||||
if cm, err := c.KubeClient.ConfigMaps(c.Namespace).Get(c.OpConfig.PodEnvironmentConfigMap, metav1.GetOptions{}); err != nil {
|
if cm, err := c.KubeClient.ConfigMaps(c.Namespace).Get(c.OpConfig.PodEnvironmentConfigMap, metav1.GetOptions{}); err != nil {
|
||||||
return nil, fmt.Errorf("could not read PodEnvironmentConfigMap: %v", err)
|
return nil, fmt.Errorf("could not read PodEnvironmentConfigMap: %v", err)
|
||||||
|
|
@ -583,7 +621,24 @@ func (c *Cluster) generateStatefulSet(spec *spec.PostgresSpec) (*v1beta1.Statefu
|
||||||
customPodEnvVars = cm.Data
|
customPodEnvVars = cm.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
podTemplate := c.generatePodTemplate(c.Postgresql.GetUID(), resourceRequirements, resourceRequirementsScalyrSidecar, &spec.Tolerations, &spec.PostgresqlParam, &spec.Patroni, &spec.Clone, &spec.DockerImage, customPodEnvVars)
|
// TODO: pod environment secrets are read from the cluster namespace
|
||||||
|
if c.OpConfig.PodEnvironmentSecret != "" {
|
||||||
|
if secret, err := c.KubeClient.Secrets(c.Namespace).Get(c.OpConfig.PodEnvironmentSecret, metav1.GetOptions{}); err != nil {
|
||||||
|
return nil, fmt.Errorf("could not read PodEnvironmentSecret secrets", err)
|
||||||
|
} else {
|
||||||
|
customPodSecrets = secret.Data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
podTemplate := c.generatePodTemplate(c.Postgresql.GetUID(),
|
||||||
|
resourceRequirements,
|
||||||
|
resourceRequirementsScalyrSidecar,
|
||||||
|
&spec.Tolerations,
|
||||||
|
&spec.PostgresqlParam,
|
||||||
|
&spec.Patroni,
|
||||||
|
&spec.Clone,
|
||||||
|
&spec.DockerImage,
|
||||||
|
customPodEnvVars,
|
||||||
|
customPodSecrets)
|
||||||
volumeClaimTemplate, err := generatePersistentVolumeClaimTemplate(spec.Volume.Size, spec.Volume.StorageClass)
|
volumeClaimTemplate, err := generatePersistentVolumeClaimTemplate(spec.Volume.Size, spec.Volume.StorageClass)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not generate volume claim template: %v", err)
|
return nil, fmt.Errorf("could not generate volume claim template: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ type Resources struct {
|
||||||
DefaultCPULimit string `name:"default_cpu_limit" default:"3"`
|
DefaultCPULimit string `name:"default_cpu_limit" default:"3"`
|
||||||
DefaultMemoryLimit string `name:"default_memory_limit" default:"1Gi"`
|
DefaultMemoryLimit string `name:"default_memory_limit" default:"1Gi"`
|
||||||
PodEnvironmentConfigMap string `name:"pod_environment_configmap" default:""`
|
PodEnvironmentConfigMap string `name:"pod_environment_configmap" default:""`
|
||||||
|
PodEnvironmentSecret string `name:"pod_environment_secret" default:""`
|
||||||
NodeReadinessLabel map[string]string `name:"node_readiness_label" default:""`
|
NodeReadinessLabel map[string]string `name:"node_readiness_label" default:""`
|
||||||
MaxInstances int32 `name:"max_instances" default:"-1"`
|
MaxInstances int32 `name:"max_instances" default:"-1"`
|
||||||
MinInstances int32 `name:"min_instances" default:"-1"`
|
MinInstances int32 `name:"min_instances" default:"-1"`
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package k8sutil
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
apiextclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
apiextclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||||
apiextbeta1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1"
|
apiextbeta1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1"
|
||||||
|
|
@ -22,6 +23,14 @@ import (
|
||||||
"github.com/zalando-incubator/postgres-operator/pkg/util/constants"
|
"github.com/zalando-incubator/postgres-operator/pkg/util/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
EnvironmentNameRegexpString = "[-._a-zA-Z][-._a-zA-Z0-9]*"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
environmentNameRegexp = regexp.MustCompile(EnvironmentNameRegexpString)
|
||||||
|
)
|
||||||
|
|
||||||
// KubernetesClient describes getters for Kubernetes objects
|
// KubernetesClient describes getters for Kubernetes objects
|
||||||
type KubernetesClient struct {
|
type KubernetesClient struct {
|
||||||
v1core.SecretsGetter
|
v1core.SecretsGetter
|
||||||
|
|
@ -153,3 +162,7 @@ func SamePDB(cur, new *policybeta1.PodDisruptionBudget) (match bool, reason stri
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EnvironmentVariableNameIsValid(name string) bool {
|
||||||
|
return environmentNameRegexp.MatchString(name)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue