From 08c0e3b6dd063a71374072405967dffb4378bb88 Mon Sep 17 00:00:00 2001 From: Murat Kabilov Date: Tue, 18 Apr 2017 11:54:45 +0200 Subject: [PATCH] Use unified type for the namespaced object names --- pkg/cluster/cluster.go | 11 ++++------- pkg/cluster/pod.go | 14 ++++---------- pkg/controller/controller.go | 8 ++++---- pkg/controller/pod.go | 13 +++---------- pkg/controller/postgresql.go | 21 ++++----------------- pkg/controller/util.go | 15 +++++++++++---- pkg/spec/postgresql.go | 10 +++++----- pkg/spec/types.go | 32 +++++++++++++++++++------------- pkg/util/config/config.go | 17 ++++++++++------- pkg/util/util.go | 13 +++++-------- 10 files changed, 69 insertions(+), 85 deletions(-) diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index 7eb5c920b..41e2918c8 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -59,7 +59,7 @@ type Cluster struct { logger *logrus.Entry pgUsers map[string]spec.PgUser podEvents chan spec.PodEvent - podSubscribers map[spec.PodName]chan spec.PodEvent + podSubscribers map[spec.NamespacedName]chan spec.PodEvent pgDb *sql.DB mu sync.Mutex } @@ -74,18 +74,15 @@ func New(cfg Config, pgSpec spec.Postgresql, logger *logrus.Logger) *Cluster { logger: lg, pgUsers: make(map[string]spec.PgUser), podEvents: make(chan spec.PodEvent), - podSubscribers: make(map[spec.PodName]chan spec.PodEvent), + podSubscribers: make(map[spec.NamespacedName]chan spec.PodEvent), kubeResources: kubeResources, } return cluster } -func (c *Cluster) ClusterName() spec.ClusterName { - return spec.ClusterName{ - Name: c.Metadata.Name, - Namespace: c.Metadata.Namespace, - } +func (c *Cluster) ClusterName() spec.NamespacedName { + return util.NameFromMeta(c.Metadata) } func (c *Cluster) TeamName() string { diff --git a/pkg/cluster/pod.go b/pkg/cluster/pod.go index 8b901a4ff..0e7bf4a55 100644 --- a/pkg/cluster/pod.go +++ b/pkg/cluster/pod.go @@ -84,10 +84,7 @@ func (c *Cluster) deletePersistenVolumeClaims() error { } func (c *Cluster) deletePod(pod *v1.Pod) error { - podName := spec.PodName{ - Namespace: pod.Namespace, - Name: pod.Name, - } + podName := util.NameFromMeta(pod.ObjectMeta) ch := make(chan spec.PodEvent) if _, ok := c.podSubscribers[podName]; ok { @@ -110,7 +107,7 @@ func (c *Cluster) deletePod(pod *v1.Pod) error { return nil } -func (c *Cluster) unregisterPodSubscriber(podName spec.PodName) { +func (c *Cluster) unregisterPodSubscriber(podName spec.NamespacedName) { if _, ok := c.podSubscribers[podName]; !ok { panic("Subscriber for Pod '" + podName.String() + "' is not found") } @@ -119,7 +116,7 @@ func (c *Cluster) unregisterPodSubscriber(podName spec.PodName) { delete(c.podSubscribers, podName) } -func (c *Cluster) registerPodSubscriber(podName spec.PodName) chan spec.PodEvent { +func (c *Cluster) registerPodSubscriber(podName spec.NamespacedName) chan spec.PodEvent { ch := make(chan spec.PodEvent) if _, ok := c.podSubscribers[podName]; ok { panic("Pod '" + podName.String() + "' is already subscribed") @@ -129,10 +126,7 @@ func (c *Cluster) registerPodSubscriber(podName spec.PodName) chan spec.PodEvent } func (c *Cluster) recreatePod(pod v1.Pod) error { - podName := spec.PodName{ - Namespace: pod.Namespace, - Name: pod.Name, - } + podName := util.NameFromMeta(pod.ObjectMeta) orphanDependents := false deleteOptions := &v1.DeleteOptions{ diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 83305e356..837508f4c 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -29,8 +29,8 @@ type Controller struct { Config opConfig *config.Config logger *logrus.Entry - clusters map[spec.ClusterName]*cluster.Cluster - stopChMap map[spec.ClusterName]chan struct{} + clusters map[spec.NamespacedName]*cluster.Cluster + stopChMap map[spec.NamespacedName]chan struct{} waitCluster sync.WaitGroup postgresqlInformer cache.SharedIndexInformer @@ -51,8 +51,8 @@ func New(controllerConfig *Config, operatorConfig *config.Config) *Controller { Config: *controllerConfig, opConfig: operatorConfig, logger: logger.WithField("pkg", "controller"), - clusters: make(map[spec.ClusterName]*cluster.Cluster), - stopChMap: make(map[spec.ClusterName]chan struct{}), + clusters: make(map[spec.NamespacedName]*cluster.Cluster), + stopChMap: make(map[spec.NamespacedName]chan struct{}), podCh: make(chan spec.PodEvent), } } diff --git a/pkg/controller/pod.go b/pkg/controller/pod.go index 4508097a5..f00dee70a 100644 --- a/pkg/controller/pod.go +++ b/pkg/controller/pod.go @@ -55,13 +55,6 @@ func (c *Controller) podWatchFunc(options api.ListOptions) (watch.Interface, err return c.KubeClient.CoreV1Client.Pods(c.PodNamespace).Watch(opts) } -func PodNameFromMeta(meta v1.ObjectMeta) spec.PodName { - return spec.PodName{ - Namespace: meta.Namespace, - Name: meta.Name, - } -} - func (c *Controller) podAdd(obj interface{}) { pod, ok := obj.(*v1.Pod) if !ok { @@ -70,7 +63,7 @@ func (c *Controller) podAdd(obj interface{}) { podEvent := spec.PodEvent{ ClusterName: util.PodClusterName(pod), - PodName: PodNameFromMeta(pod.ObjectMeta), + PodName: util.NameFromMeta(pod.ObjectMeta), CurPod: pod, EventType: spec.PodEventAdd, } @@ -91,7 +84,7 @@ func (c *Controller) podUpdate(prev, cur interface{}) { podEvent := spec.PodEvent{ ClusterName: util.PodClusterName(curPod), - PodName: PodNameFromMeta(curPod.ObjectMeta), + PodName: util.NameFromMeta(curPod.ObjectMeta), PrevPod: prevPod, CurPod: curPod, EventType: spec.PodEventUpdate, @@ -108,7 +101,7 @@ func (c *Controller) podDelete(obj interface{}) { podEvent := spec.PodEvent{ ClusterName: util.PodClusterName(pod), - PodName: PodNameFromMeta(pod.ObjectMeta), + PodName: util.NameFromMeta(pod.ObjectMeta), CurPod: pod, EventType: spec.PodEventDelete, } diff --git a/pkg/controller/postgresql.go b/pkg/controller/postgresql.go index 0a9f7d47e..5359005fd 100644 --- a/pkg/controller/postgresql.go +++ b/pkg/controller/postgresql.go @@ -41,11 +41,7 @@ func (c *Controller) clusterListFunc(options api.ListOptions) (runtime.Object, e if !ok { return nil, fmt.Errorf("Can't cast object to postgresql") } - clusterName := spec.ClusterName{ - Namespace: pg.Metadata.Namespace, - Name: pg.Metadata.Name, - } - + clusterName := util.NameFromMeta(pg.Metadata) cl := cluster.New(clusterConfig, *pg, c.logger.Logger) stopCh := make(chan struct{}) @@ -83,10 +79,7 @@ func (c *Controller) postgresqlAdd(obj interface{}) { return } - clusterName := spec.ClusterName{ - Namespace: pg.Metadata.Namespace, - Name: pg.Metadata.Name, - } + clusterName := util.NameFromMeta(pg.Metadata) _, ok = c.clusters[clusterName] if ok { @@ -123,10 +116,7 @@ func (c *Controller) postgresqlUpdate(prev, cur interface{}) { c.logger.Errorf("Can't cast to postgresql spec") } - clusterName := spec.ClusterName{ - Namespace: pgNew.Metadata.Namespace, - Name: pgNew.Metadata.Name, - } + clusterName := util.NameFromMeta(pgNew.Metadata) //TODO: Do not update cluster which is currently creating if pgPrev.Metadata.ResourceVersion == pgNew.Metadata.ResourceVersion { @@ -155,10 +145,7 @@ func (c *Controller) postgresqlDelete(obj interface{}) { c.logger.Errorf("Can't cast to postgresql spec") return } - clusterName := spec.ClusterName{ - Namespace: pgCur.Metadata.Namespace, - Name: pgCur.Metadata.Name, - } + clusterName := util.NameFromMeta(pgCur.Metadata) pgCluster, ok := c.clusters[clusterName] if !ok { c.logger.Errorf("Unknown cluster: %s", clusterName) diff --git a/pkg/controller/util.go b/pkg/controller/util.go index 70617fa34..b433e5024 100644 --- a/pkg/controller/util.go +++ b/pkg/controller/util.go @@ -3,7 +3,6 @@ package controller import ( "fmt" - "k8s.io/client-go/pkg/api" "k8s.io/client-go/pkg/api/v1" extv1beta "k8s.io/client-go/pkg/apis/extensions/v1beta1" @@ -26,7 +25,9 @@ func (c *Controller) makeClusterConfig() cluster.Config { func (c *Controller) getOAuthToken() (string, error) { // Temporary getting postgresql-operator secret from the NamespaceDefault - credentialsSecret, err := c.KubeClient.Secrets(api.NamespaceDefault).Get(c.opConfig.OAuthTokenSecretName) + credentialsSecret, err := c.KubeClient. + Secrets(c.opConfig.OAuthTokenSecretName.Namespace). + Get(c.opConfig.OAuthTokenSecretName.Name) if err != nil { c.logger.Debugf("Oauth token secret name: %s", c.opConfig.OAuthTokenSecretName) @@ -75,15 +76,19 @@ func (c *Controller) createTPR() error { } func (c *Controller) getInfrastructureRoles() (result map[string]spec.PgUser, err error) { - if c.opConfig.InfrastructureRolesSecretName == "" { + if c.opConfig.InfrastructureRolesSecretName == (spec.NamespacedName{}) { // we don't have infrastructure roles defined, bail out return nil, nil } - infraRolesSecret, err := c.KubeClient.Secrets(api.NamespaceDefault).Get(c.opConfig.InfrastructureRolesSecretName) + + infraRolesSecret, err := c.KubeClient. + Secrets(c.opConfig.InfrastructureRolesSecretName.Namespace). + Get(c.opConfig.InfrastructureRolesSecretName.Name) if err != nil { c.logger.Debugf("Infrastructure roles secret name: %s", c.opConfig.InfrastructureRolesSecretName) return nil, fmt.Errorf("Can't get infrastructure roles Secret: %s", err) } + data := infraRolesSecret.Data result = make(map[string]spec.PgUser) Users: @@ -112,9 +117,11 @@ Users: } } } + if t.Name != "" { result[t.Name] = t } } + return result, nil } diff --git a/pkg/spec/postgresql.go b/pkg/spec/postgresql.go index b5b7ef7b0..fc6148f26 100644 --- a/pkg/spec/postgresql.go +++ b/pkg/spec/postgresql.go @@ -52,11 +52,11 @@ type PostgresStatus string const ( ClusterStatusUnknown PostgresStatus = "" - ClusterStatusCreating = "Creating" - ClusterStatusUpdating = "Updating" - ClusterStatusUpdateFailed = "UpdateFailed" - ClusterStatusAddFailed = "CreateFailed" - ClusterStatusRunning = "Running" + ClusterStatusCreating PostgresStatus = "Creating" + ClusterStatusUpdating PostgresStatus = "Updating" + ClusterStatusUpdateFailed PostgresStatus = "UpdateFailed" + ClusterStatusAddFailed PostgresStatus = "CreateFailed" + ClusterStatusRunning PostgresStatus = "Running" ) // PostgreSQL Third Party (resource) Object diff --git a/pkg/spec/types.go b/pkg/spec/types.go index 59babbe23..23fc0ca64 100644 --- a/pkg/spec/types.go +++ b/pkg/spec/types.go @@ -7,7 +7,7 @@ import ( type PodEventType string -type PodName types.NamespacedName +type NamespacedName types.NamespacedName const ( PodEventAdd PodEventType = "ADD" @@ -16,26 +16,32 @@ const ( ) type PodEvent struct { - ClusterName ClusterName - PodName PodName + ClusterName NamespacedName + PodName NamespacedName PrevPod *v1.Pod CurPod *v1.Pod EventType PodEventType } -func (p PodName) String() string { - return types.NamespacedName(p).String() -} - -type ClusterName types.NamespacedName - -func (c ClusterName) String() string { - return types.NamespacedName(c).String() -} - type PgUser struct { Name string Password string Flags []string MemberOf string } + +func (p NamespacedName) String() string { + return types.NamespacedName(p).String() +} + +func (n *NamespacedName) Decode(value string) error { + name := types.NewNamespacedNameFromString(value) + if value != "" && name == (types.NamespacedName{}) { + name.Name = value + name.Namespace = v1.NamespaceDefault + } + + *n = NamespacedName(name) + + return nil +} diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index 90ca7c895..90ae21dc3 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -6,6 +6,7 @@ import ( "strings" "time" + "github.bus.zalan.do/acid/postgres-operator/pkg/spec" "github.com/kelseyhightower/envconfig" ) @@ -24,13 +25,13 @@ type Resources struct { } 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 string `envconfig:"oauth_token_secret_name" default:"postgresql-operator"` - InfrastructureRolesSecretName string `split_words:"true"` - SuperUsername string `split_words:"true" default:"postgres"` - ReplicationUsername string `split_words:"true" default:"replication"` + 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"` } type Config struct { @@ -49,6 +50,8 @@ type Config struct { } 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 { diff --git a/pkg/util/util.go b/pkg/util/util.go index c20d2b651..6d1a0c1e2 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -11,7 +11,6 @@ import ( "github.bus.zalan.do/acid/postgres-operator/pkg/spec" "k8s.io/client-go/pkg/api/v1" - "k8s.io/client-go/pkg/types" "strings" ) @@ -30,24 +29,22 @@ func RandomPassword(n int) string { return string(b) } -func NameFromMeta(meta v1.ObjectMeta) types.NamespacedName { - obj := types.NamespacedName{ +func NameFromMeta(meta v1.ObjectMeta) spec.NamespacedName { + return spec.NamespacedName{ Namespace: meta.Namespace, Name: meta.Name, } - - return obj } -func PodClusterName(pod *v1.Pod) spec.ClusterName { +func PodClusterName(pod *v1.Pod) spec.NamespacedName { if name, ok := pod.Labels["spilo-cluster"]; ok { - return spec.ClusterName{ + return spec.NamespacedName{ Namespace: pod.Namespace, Name: name, } } - return spec.ClusterName{} + return spec.NamespacedName{} } func PodSpiloRole(pod *v1.Pod) string {