Use ConfigMap to store operator's config

This commit is contained in:
Murat Kabilov 2017-04-19 12:02:45 +02:00
parent 47e3e29a56
commit da438aab3a
16 changed files with 323 additions and 147 deletions

View File

@ -9,6 +9,7 @@ import (
"syscall"
"github.bus.zalan.do/acid/postgres-operator/pkg/controller"
"github.bus.zalan.do/acid/postgres-operator/pkg/spec"
"github.bus.zalan.do/acid/postgres-operator/pkg/util/config"
"github.bus.zalan.do/acid/postgres-operator/pkg/util/k8sutil"
)
@ -16,9 +17,9 @@ import (
var (
KubeConfigFile string
podNamespace string
configMapName spec.NamespacedName
OutOfCluster bool
version string
cfg *config.Config
)
func init() {
@ -27,11 +28,14 @@ func init() {
flag.Parse()
podNamespace = os.Getenv("MY_POD_NAMESPACE")
if len(podNamespace) == 0 {
if podNamespace == "" {
podNamespace = "default"
}
cfg = config.LoadFromEnv()
configMap := os.Getenv("CONFIG_MAP_NAME")
if configMap != "" {
configMapName.Decode(configMap)
}
}
func ControllerConfig() *controller.Config {
@ -48,16 +52,15 @@ func ControllerConfig() *controller.Config {
restClient, err := k8sutil.KubernetesRestClient(restConfig)
return &controller.Config{
PodNamespace: podNamespace, //TODO: move to config.Config
KubeClient: client,
RestClient: restClient,
KubeClient: client,
RestClient: restClient,
}
}
func main() {
configMapData := make(map[string]string)
log.SetOutput(os.Stdout)
log.Printf("Spilo operator %s\n", version)
log.Printf("Config: %s", cfg.MustMarshal())
sigs := make(chan os.Signal, 1)
stop := make(chan struct{})
@ -67,6 +70,23 @@ func main() {
controllerConfig := ControllerConfig()
if configMapName != (spec.NamespacedName{}) {
configMap, err := controllerConfig.KubeClient.ConfigMaps(configMapName.Namespace).Get(configMapName.Name)
if err != nil {
panic(err)
}
configMapData = configMap.Data
} else {
log.Printf("No ConfigMap specified. Loading default values")
}
if configMapData["namespace"] == "" { // Namespace in ConfigMap has priority over env var
configMapData["namespace"] = podNamespace
}
cfg := config.NewFromMap(configMapData)
log.Printf("Config: %s", cfg.MustMarshal())
c := controller.New(controllerConfig, cfg)
c.Run(stop, wg)

8
glide.lock generated
View File

@ -1,5 +1,5 @@
hash: 9cb22736d27cb74bb0f674c5e57954c8fd14e4b5cae0b2e22ead9f10728f91f8
updated: 2017-04-10T15:33:31.332520218+02:00
hash: de07f359cf295197b1663e28cb7a9652c1bb4b9ddca7e70e4e605410b43e4e5f
updated: 2017-04-19T11:22:12.486616201+02:00
imports:
- name: cloud.google.com/go
version: 3b1ae45394a234c385be014e9a488f2bb6eef821
@ -75,12 +75,10 @@ imports:
version: 2eee05ed794112d45db504eb05aa693efd2b8b09
- name: github.com/juju/ratelimit
version: 77ed1c8a01217656d2080ad51981f6e99adaa177
- name: github.com/kelseyhightower/envconfig
version: 8bf4bbfc795e2c7c8a5ea47b707453ed019e2ad4
- name: github.com/kr/text
version: 7cafcd837844e784b526369c9bce262804aebc60
- name: github.com/lib/pq
version: 0477eb88c5ca4009cb281f13c90633375b6a9987
version: 2704adc878c21e1329f46f6e56a1c387d788ff94
subpackages:
- oid
- name: github.com/mailru/easyjson

View File

@ -27,5 +27,4 @@ import:
- rest
- tools/cache
- tools/clientcmd
- package: github.com/kelseyhightower/envconfig
- package: github.com/motomux/pretty

29
manifests/configmap.yaml Normal file
View File

@ -0,0 +1,29 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-operator
data:
service_account_name: operator
cluster_labels: application:spilo
cluster_name_label: version
pod_role_label: spilo-role
db_hosted_zone: db.example.com
dns_name_format: '%s.%s.staging.%s'
docker_image: registry.opensource.zalan.do/acid/spilo-9.6:1.2-p12
etcd_host: etcd-client.default.svc.cluster.local:2379
infrastructure_roles_secret_name: postgresql-infrastructure-roles
oauth_token_secret_name: postgresql-operator
pam_configuration: |
https://info.example.com/oauth2/tokeninfo?access_token= uid realm=/employees
pam_role_name: zalandos
pod_deletion_wait_timeout: 10m
pod_label_wait_timeout: 10m
ready_wait_interval: 3s
ready_wait_timeout: 30s
replication_username: replication
resource_check_interval: 3s
resource_check_timeout: 10m
resync_period: 5m
resync_period_pod: 5m
super_username: postgres
teams_api_url: https://teams.example.com/api/

View File

@ -14,49 +14,9 @@ spec:
- name: postgres-operator
image: pierone.example.com/acid/postgres-operator:0.1
env:
- name: MY_POD_NAMESPACE #TODO: use PGOP_ prefix
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: PGOP_SERVICE_ACCOUNT_NAME
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: PGOP_READY_WAIT_INTERVAL
value: "3s"
- name: PGOP_READY_WAIT_TIMEOUT
value: "30s"
- name: PGOP_RESYNC_PERIOD
value: "5m"
- name: PGOP_RESYNC_PERIOD_POD
value: "5m"
- name: PGOP_RESOURCE_CHECK_INTERVAL
value: "3s"
- name: PGOP_RESOURCE_CHECK_TIMEOUT
value: "10m"
- name: PGOP_POD_LABEL_WAIT_TIMEOUT
value: "10m"
- name: PGOP_POD_DELETION_WAIT_TIMEOUT
value: "10m"
- name: PGOP_PAM_ROLE_NAME
value: "zalandos"
- name: PGOP_PAM_CONFIGURATION
value: "https://info.example.com/oauth2/tokeninfo?access_token= uid realm=/employees"
- name: PGOP_TEAMS_API_URL
value: "https://teams.example.com/api/"
- name: PGOP_OAUTH_TOKEN_SECRET_NAME
value: "postgresql-operator"
- name: PGOP_SUPER_USERNAME
value: "postgres"
- name: PGOP_REPLICATION_USERNAME
value: "replication"
- name: PGOP_ETCD_HOST
value: "etcd-client.default.svc.cluster.local:2379"
- name: PGOP_DOCKER_IMAGE
value: "registry.opensource.zalan.do/acid/spilo-9.6:1.2-p12"
- name: PGOP_DB_HOSTED_ZONE
value: "db.example.com"
- name: PGOP_DNS_NAME_FORMAT
value: "%s.%s.staging.%s"
- name: PGOP_INFRASTRUCTURE_ROLES_SECRET_NAME
value: "postgresql-infrastructure-roles"
- name: CONFIG_MAP_NAME
value: "postgres-operator"

View File

@ -2,7 +2,7 @@ apiVersion: "acid.zalan.do/v1"
kind: "Postgresql"
metadata:
name: testcluster
name: acid-testcluster
spec:
teamId: "ACID"
volume:

View File

@ -183,7 +183,7 @@ func (c *Cluster) recreatePods() error {
var masterPod v1.Pod
for _, pod := range pods.Items {
role := util.PodSpiloRole(&pod)
role := c.PodSpiloRole(&pod)
if role == constants.PodRoleMaster {
masterPod = pod

View File

@ -103,7 +103,7 @@ func (c *Cluster) waitForPodLabel(podEvents chan spec.PodEvent) error {
for {
select {
case podEvent := <-podEvents:
role := util.PodSpiloRole(podEvent.CurPod)
role := c.PodSpiloRole(podEvent.CurPod)
// We cannot assume any role of the newly created pod. Normally, for a multi-pod cluster
// we should observe the 'replica' value, but it could be that some pods are not allowed
// to promote, therefore, the new pod could be a master as well.
@ -156,10 +156,14 @@ func (c *Cluster) waitPodLabelsReady() error {
LabelSelector: ls.String(),
}
masterListOption := v1.ListOptions{
LabelSelector: labels.Merge(ls, labels.Set{constants.SpiloRoleLabel: constants.PodRoleMaster}).String(),
LabelSelector: labels.Merge(ls, labels.Set{
c.OpConfig.PodRoleLabel: constants.PodRoleMaster,
}).String(),
}
replicaListOption := v1.ListOptions{
LabelSelector: labels.Merge(ls, labels.Set{constants.SpiloRoleLabel: constants.PodRoleReplica}).String(),
LabelSelector: labels.Merge(ls, labels.Set{
c.OpConfig.PodRoleLabel: constants.PodRoleReplica,
}).String(),
}
pods, err := c.KubeClient.Pods(namespace).List(listOptions)
if err != nil {
@ -203,10 +207,10 @@ func (c *Cluster) waitStatefulsetPodsReady() error {
}
func (c *Cluster) labelsSet() labels.Set {
return labels.Set{
constants.ApplicationNameLabel: constants.ApplicationNameLabelValue,
constants.ClusterNameLabel: c.Metadata.Name,
}
lbls := c.OpConfig.ClusterLabels
lbls[c.OpConfig.ClusterNameLabel] = c.Metadata.Name
return labels.Set(lbls)
}
func (c *Cluster) dnsName() string {
@ -228,7 +232,7 @@ func (c *Cluster) credentialSecretName(username string) string {
}
func (c *Cluster) deleteEtcdKey() error {
etcdKey := fmt.Sprintf("/service/%s", c.Metadata.Name)
etcdKey := fmt.Sprintf("/%s/%s", c.OpConfig.EtcdScope, c.Metadata.Name)
//TODO: retry multiple times
resp, err := c.EtcdClient.Delete(context.Background(),
@ -245,3 +249,7 @@ func (c *Cluster) deleteEtcdKey() error {
return nil
}
func (c *Cluster) PodSpiloRole(pod *v1.Pod) string {
return pod.Labels[c.OpConfig.PodRoleLabel]
}

View File

@ -17,7 +17,6 @@ import (
)
type Config struct {
PodNamespace string
KubeClient *kubernetes.Clientset
RestClient *rest.RESTClient
EtcdClient etcdclient.KeysAPI
@ -63,7 +62,6 @@ func (c *Controller) Run(stopCh <-chan struct{}, wg *sync.WaitGroup) {
c.initController()
c.logger.Infof("'%s' namespace will be watched", c.PodNamespace)
go c.runInformers(stopCh)
c.logger.Info("Started working in background")

View File

@ -29,7 +29,7 @@ func (c *Controller) podListFunc(options api.ListOptions) (runtime.Object, error
TimeoutSeconds: options.TimeoutSeconds,
}
return c.KubeClient.CoreV1().Pods(c.PodNamespace).List(opts)
return c.KubeClient.CoreV1().Pods(c.opConfig.Namespace).List(opts)
}
func (c *Controller) podWatchFunc(options api.ListOptions) (watch.Interface, error) {
@ -52,7 +52,7 @@ func (c *Controller) podWatchFunc(options api.ListOptions) (watch.Interface, err
TimeoutSeconds: options.TimeoutSeconds,
}
return c.KubeClient.CoreV1Client.Pods(c.PodNamespace).Watch(opts)
return c.KubeClient.CoreV1Client.Pods(c.opConfig.Namespace).Watch(opts)
}
func (c *Controller) podAdd(obj interface{}) {
@ -62,7 +62,7 @@ func (c *Controller) podAdd(obj interface{}) {
}
podEvent := spec.PodEvent{
ClusterName: util.PodClusterName(pod),
ClusterName: c.PodClusterName(pod),
PodName: util.NameFromMeta(pod.ObjectMeta),
CurPod: pod,
EventType: spec.PodEventAdd,
@ -83,7 +83,7 @@ func (c *Controller) podUpdate(prev, cur interface{}) {
}
podEvent := spec.PodEvent{
ClusterName: util.PodClusterName(curPod),
ClusterName: c.PodClusterName(curPod),
PodName: util.NameFromMeta(curPod.ObjectMeta),
PrevPod: prevPod,
CurPod: curPod,
@ -100,7 +100,7 @@ func (c *Controller) podDelete(obj interface{}) {
}
podEvent := spec.PodEvent{
ClusterName: util.PodClusterName(pod),
ClusterName: c.PodClusterName(pod),
PodName: util.NameFromMeta(pod.ObjectMeta),
CurPod: pod,
EventType: spec.PodEventDelete,

View File

@ -19,7 +19,7 @@ import (
func (c *Controller) clusterListFunc(options api.ListOptions) (runtime.Object, error) {
c.logger.Info("Getting list of currently running clusters")
object, err := c.RestClient.Get().
Namespace(c.PodNamespace).
Namespace(c.opConfig.Namespace).
Resource(constants.ResourceName).
VersionedParams(&options, api.ParameterCodec).
FieldsSelectorParam(fields.Everything()).
@ -65,7 +65,7 @@ func (c *Controller) clusterListFunc(options api.ListOptions) (runtime.Object, e
func (c *Controller) clusterWatchFunc(options api.ListOptions) (watch.Interface, error) {
return c.RestClient.Get().
Prefix("watch").
Namespace(c.PodNamespace).
Namespace(c.opConfig.Namespace).
Resource(constants.ResourceName).
VersionedParams(&options, api.ParameterCodec).
FieldsSelectorParam(fields.Everything()).

View File

@ -72,7 +72,7 @@ func (c *Controller) createTPR() error {
restClient := c.RestClient
return k8sutil.WaitTPRReady(restClient, c.opConfig.TPR.ReadyWaitInterval, c.opConfig.TPR.ReadyWaitTimeout, c.PodNamespace)
return k8sutil.WaitTPRReady(restClient, c.opConfig.TPR.ReadyWaitInterval, c.opConfig.TPR.ReadyWaitTimeout, c.opConfig.Namespace)
}
func (c *Controller) getInfrastructureRoles() (result map[string]spec.PgUser, err error) {
@ -125,3 +125,14 @@ Users:
return result, nil
}
func (c *Controller) PodClusterName(pod *v1.Pod) spec.NamespacedName {
if name, ok := pod.Labels[c.opConfig.ClusterNameLabel]; ok {
return spec.NamespacedName{
Namespace: pod.Namespace,
Name: name,
}
}
return spec.NamespacedName{}
}

View File

@ -2,64 +2,53 @@ package config
import (
"encoding/json"
"fmt"
"strings"
"time"
"github.bus.zalan.do/acid/postgres-operator/pkg/spec"
"github.com/kelseyhightower/envconfig"
)
type TPR struct {
ReadyWaitInterval time.Duration `split_words:"true" default:"3s"`
ReadyWaitTimeout time.Duration `split_words:"true" default:"30s"`
ResyncPeriod time.Duration `split_words:"true" default:"5m"`
ReadyWaitInterval time.Duration `name:"ready_wait_interval" default:"4s"`
ReadyWaitTimeout time.Duration `name:"ready_wait_timeout" default:"30s"`
ResyncPeriod time.Duration `name:"resync_period" default:"5m"`
}
type Resources struct {
ResyncPeriodPod time.Duration `split_words:"true" default:"5m"`
ResourceCheckInterval time.Duration `split_words:"true" default:"3s"`
ResourceCheckTimeout time.Duration `split_words:"true" default:"10m"`
PodLabelWaitTimeout time.Duration `split_words:"true" default:"10m"`
PodDeletionWaitTimeout time.Duration `split_words:"true" default:"10m"`
ResyncPeriodPod time.Duration `name:"resync_period_pod" default:"5m"`
ResourceCheckInterval time.Duration `name:"resource_check_interval" default:"3s"`
ResourceCheckTimeout time.Duration `name:"resource_check_timeout" default:"10m"`
PodLabelWaitTimeout time.Duration `name:"pod_label_wait_timeout" default:"10m"`
PodDeletionWaitTimeout time.Duration `name:"pod_deletion_wait_timeout" default:"10m"`
ClusterLabels map[string]string `name:"cluster_labels" default:"application:spilo"`
ClusterNameLabel string `name:"cluster_name_label" default:"cluster-name"`
PodRoleLabel string `name:"pod_role_label" default:"spilo-role"`
}
type Auth struct {
PamRoleName string `split_words:"true" default:"zalandos"`
PamConfiguration string `split_words:"true" default:"https://info.example.com/oauth2/tokeninfo?access_token= uid realm=/employees"`
TeamsAPIUrl string `envconfig:"teams_api_url" default:"https://teams.example.com/api/"`
OAuthTokenSecretName spec.NamespacedName `envconfig:"oauth_token_secret_name" default:"postgresql-operator"`
InfrastructureRolesSecretName spec.NamespacedName `split_words:"true"`
SuperUsername string `split_words:"true" default:"postgres"`
ReplicationUsername string `split_words:"true" default:"replication"`
PamRoleName string `name:"pam_rol_name" default:"zalandos"`
PamConfiguration string `name:"pam_configuration" default:"https://info.example.com/oauth2/tokeninfo?access_token= uid realm=/employees"`
TeamsAPIUrl string `name:"teams_api_url" default:"https://teams.example.com/api/"`
OAuthTokenSecretName spec.NamespacedName `name:"oauth_token_secret_name" default:"postgresql-operator"`
InfrastructureRolesSecretName spec.NamespacedName `name:"infrastructure_roles_secret_name"`
SuperUsername string `name:"super_username" default:"postgres"`
ReplicationUsername string `name:"replication_username" default:"replication"`
}
type Config struct {
TPR
Resources
Auth
EtcdHost string `split_words:"true" default:"etcd-client.default.svc.cluster.local:2379"`
DockerImage string `split_words:"true" default:"registry.opensource.zalan.do/acid/spilo-9.6:1.2-p12"`
ServiceAccountName string `split_words:"true" default:"operator"`
DbHostedZone string `split_words:"true" default:"db.example.com"`
EtcdScope string `split_words:"true" default:"service"`
WALES3Bucket string `envconfig:"wal_s3_bucket"`
KubeIAMRole string `envconfig:"kube_iam_role"`
DebugLogging bool `split_words:"true" default:"false"`
DNSNameFormat string `envconfig:"dns_name_format" default:"%s.%s.%s"`
}
func LoadFromEnv() *Config {
//TODO: maybe we should use ConfigMaps( https://kubernetes.io/docs/tasks/configure-pod-container/configmap/ ) instead?
var cfg Config
err := envconfig.Process("PGOP", &cfg)
if err != nil {
panic(fmt.Errorf("Can't read config: %v", err))
}
cfg.EtcdScope = strings.Trim(cfg.EtcdScope, "/")
return &cfg
Namespace string `name:"namespace"`
EtcdHost string `name:"etcd_host" default:"etcd-client.default.svc.cluster.local:2379"`
DockerImage string `name:"docker_image" default:"registry.opensource.zalan.do/acid/spilo-9.6:1.2-p12"`
ServiceAccountName string `name:"service_account_name" default:"operator"`
DbHostedZone string `name:"db_hosted_zone" default:"db.example.com"`
EtcdScope string `name:"etcd_scope" default:"service"`
WALES3Bucket string `name:"wal_s3_bucket"`
KubeIAMRole string `name:"kube_iam_role"`
DebugLogging bool `name:"debug_logging" default:"false"`
DNSNameFormat string `name:"dns_name_format" default:"%s.%s.%s"`
}
func (c Config) MustMarshal() string {
@ -70,3 +59,23 @@ func (c Config) MustMarshal() string {
return string(b)
}
func NewFromMap(m map[string]string) *Config {
cfg := Config{}
fields, _ := structFields(&cfg)
for _, structField := range fields {
key := strings.ToLower(structField.Name)
value, ok := m[key]
if !ok && structField.Default != "" {
value = structField.Default
}
err := processField(value, structField.Field)
if err != nil {
panic(err)
}
}
return &cfg
}

164
pkg/util/config/util.go Normal file
View File

@ -0,0 +1,164 @@
package config
import (
"fmt"
"reflect"
"strconv"
"strings"
"time"
)
type Decoder interface {
Decode(value string) error
}
type fieldInfo struct {
Name string
Default string
Field reflect.Value
}
func decoderFrom(field reflect.Value) (d Decoder) {
// it may be impossible for a struct field to fail this check
if !field.CanInterface() {
return
}
d, ok := field.Interface().(Decoder)
if !ok && field.CanAddr() {
d, ok = field.Addr().Interface().(Decoder)
}
return d
}
// taken from github.com/kelseyhightower/envconfig
func structFields(spec interface{}) ([]fieldInfo, error) {
s := reflect.ValueOf(spec).Elem()
// over allocate an info array, we will extend if needed later
infos := make([]fieldInfo, 0, s.NumField())
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
ftype := s.Type().Field(i)
fieldName := ftype.Tag.Get("name")
if fieldName == "" {
fieldName = strings.ToLower(ftype.Name)
}
// Capture information about the config variable
info := fieldInfo{
Name: fieldName,
Field: f,
Default: ftype.Tag.Get("default"),
}
infos = append(infos, info)
if f.Kind() == reflect.Struct {
// honor Decode if present
if decoderFrom(f) == nil {
embeddedPtr := f.Addr().Interface()
embeddedInfos, err := structFields(embeddedPtr)
if err != nil {
return nil, err
}
infos = append(infos[:len(infos)-1], embeddedInfos...)
continue
}
}
}
return infos, nil
}
func processField(value string, field reflect.Value) error {
typ := field.Type()
decoder := decoderFrom(field)
if decoder != nil {
return decoder.Decode(value)
}
if typ.Kind() == reflect.Ptr {
typ = typ.Elem()
if field.IsNil() {
field.Set(reflect.New(typ))
}
field = field.Elem()
}
switch typ.Kind() {
case reflect.String:
field.SetString(value)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
var (
val int64
err error
)
if field.Kind() == reflect.Int64 && typ.PkgPath() == "time" && typ.Name() == "Duration" {
var d time.Duration
d, err = time.ParseDuration(value)
val = int64(d)
} else {
val, err = strconv.ParseInt(value, 0, typ.Bits())
}
if err != nil {
return err
}
field.SetInt(val)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
val, err := strconv.ParseUint(value, 0, typ.Bits())
if err != nil {
return err
}
field.SetUint(val)
case reflect.Bool:
val, err := strconv.ParseBool(value)
if err != nil {
return err
}
field.SetBool(val)
case reflect.Float32, reflect.Float64:
val, err := strconv.ParseFloat(value, typ.Bits())
if err != nil {
return err
}
field.SetFloat(val)
case reflect.Slice:
vals := strings.Split(value, ",")
sl := reflect.MakeSlice(typ, len(vals), len(vals))
for i, val := range vals {
err := processField(val, sl.Index(i))
if err != nil {
return err
}
}
field.Set(sl)
case reflect.Map:
pairs := strings.Split(value, ",")
mp := reflect.MakeMap(typ)
for _, pair := range pairs {
kvpair := strings.Split(pair, ":")
if len(kvpair) != 2 {
return fmt.Errorf("invalid map item: %q", pair)
}
k := reflect.New(typ.Key()).Elem()
err := processField(kvpair[0], k)
if err != nil {
return err
}
v := reflect.New(typ.Elem()).Elem()
err = processField(kvpair[1], v)
if err != nil {
return err
}
mp.SetMapIndex(k, v)
}
field.Set(mp)
}
return nil
}

View File

@ -2,20 +2,16 @@ package constants
const (
//Constants
TPRName = "postgresql"
TPRVendor = "acid.zalan.do"
TPRDescription = "Managed PostgreSQL clusters"
TPRApiVersion = "v1"
DataVolumeName = "pgdata"
PasswordLength = 64
UserSecretTemplate = "%s.%s.credentials.%s.%s" // Username, ClusterName, TPRName, TPRVendor
ZalandoDnsNameAnnotation = "zalando.org/dnsname"
KubeIAmAnnotation = "iam.amazonaws.com/role"
ResourceName = TPRName + "s"
PodRoleMaster = "master"
PodRoleReplica = "replica"
ApplicationNameLabel = "application"
ApplicationNameLabelValue = "spilo"
SpiloRoleLabel = "spilo-role"
ClusterNameLabel = "version"
TPRName = "postgresql"
TPRVendor = "acid.zalan.do"
TPRDescription = "Managed PostgreSQL clusters"
TPRApiVersion = "v1"
DataVolumeName = "pgdata"
PasswordLength = 64
UserSecretTemplate = "%s.%s.credentials.%s.%s" // Username, ClusterName, TPRName, TPRVendor
ZalandoDnsNameAnnotation = "zalando.org/dnsname"
KubeIAmAnnotation = "iam.amazonaws.com/role"
ResourceName = TPRName + "s"
PodRoleMaster = "master"
PodRoleReplica = "replica"
)

View File

@ -12,7 +12,6 @@ import (
"k8s.io/client-go/pkg/api/v1"
"github.bus.zalan.do/acid/postgres-operator/pkg/spec"
"github.bus.zalan.do/acid/postgres-operator/pkg/util/constants"
)
var passwordChars = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
@ -37,21 +36,6 @@ func NameFromMeta(meta v1.ObjectMeta) spec.NamespacedName {
}
}
func PodClusterName(pod *v1.Pod) spec.NamespacedName {
if name, ok := pod.Labels[constants.ClusterNameLabel]; ok {
return spec.NamespacedName{
Namespace: pod.Namespace,
Name: name,
}
}
return spec.NamespacedName{}
}
func PodSpiloRole(pod *v1.Pod) string {
return pod.Labels[constants.SpiloRoleLabel]
}
func PGUserPassword(user spec.PgUser) string {
s := md5.Sum([]byte(user.Password + user.Name))