move types from spec into separate package

This commit is contained in:
Murat Kabilov 2017-06-09 17:31:45 +02:00
parent 685e0c533e
commit 8f8d3d5148
20 changed files with 182 additions and 168 deletions

View File

@ -9,7 +9,7 @@ import (
"syscall" "syscall"
"github.com/zalando-incubator/postgres-operator/pkg/controller" "github.com/zalando-incubator/postgres-operator/pkg/controller"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util/config" "github.com/zalando-incubator/postgres-operator/pkg/util/config"
"github.com/zalando-incubator/postgres-operator/pkg/util/k8sutil" "github.com/zalando-incubator/postgres-operator/pkg/util/k8sutil"
) )
@ -17,7 +17,7 @@ import (
var ( var (
KubeConfigFile string KubeConfigFile string
podNamespace string podNamespace string
configMapName spec.NamespacedName configMapName types.NamespacedName
OutOfCluster bool OutOfCluster bool
noTeamsAPI bool noTeamsAPI bool
noDatabaseAccess bool noDatabaseAccess bool
@ -78,7 +78,7 @@ func main() {
controllerConfig := ControllerConfig() controllerConfig := ControllerConfig()
if configMapName != (spec.NamespacedName{}) { if configMapName != (types.NamespacedName{}) {
configMap, err := controllerConfig.KubeClient.ConfigMaps(configMapName.Namespace).Get(configMapName.Name) configMap, err := controllerConfig.KubeClient.ConfigMaps(configMapName.Namespace).Get(configMapName.Name)
if err != nil { if err != nil {
panic(err) panic(err)

View File

@ -14,11 +14,12 @@ import (
"k8s.io/client-go/pkg/api" "k8s.io/client-go/pkg/api"
"k8s.io/client-go/pkg/api/v1" "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/pkg/apis/apps/v1beta1" "k8s.io/client-go/pkg/apis/apps/v1beta1"
"k8s.io/client-go/pkg/types" ktypes "k8s.io/client-go/pkg/types"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/spec"
"github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util" "github.com/zalando-incubator/postgres-operator/pkg/util"
"github.com/zalando-incubator/postgres-operator/pkg/util/config" "github.com/zalando-incubator/postgres-operator/pkg/util/config"
"github.com/zalando-incubator/postgres-operator/pkg/util/constants" "github.com/zalando-incubator/postgres-operator/pkg/util/constants"
@ -28,17 +29,6 @@ import (
"github.com/zalando-incubator/postgres-operator/pkg/util/volumes" "github.com/zalando-incubator/postgres-operator/pkg/util/volumes"
) )
type Interface interface {
Create() error
Delete() error
ExecCommand(podName *spec.NamespacedName, command ...string) (string, error)
ReceivePodEvent(event spec.PodEvent)
Run(stopCh <-chan struct{})
Sync() error
Update(newSpec *spec.Postgresql) error
SetFailed(err error)
}
type PostgresRole string type PostgresRole string
const ( const (
@ -53,13 +43,13 @@ type Config struct {
RestConfig *rest.Config RestConfig *rest.Config
TeamsAPIClient *teams.API TeamsAPIClient *teams.API
OpConfig config.Config OpConfig config.Config
InfrastructureRoles map[string]spec.PgUser // inherited from the controller InfrastructureRoles map[string]types.PgUser // inherited from the controller
} }
type kubeResources struct { type kubeResources struct {
Service map[PostgresRole]*v1.Service Service map[PostgresRole]*v1.Service
Endpoint *v1.Endpoints Endpoint *v1.Endpoints
Secrets map[types.UID]*v1.Secret Secrets map[ktypes.UID]*v1.Secret
Statefulset *v1beta1.StatefulSet Statefulset *v1beta1.StatefulSet
//Pods are treated separately //Pods are treated separately
//PVCs are treated separately //PVCs are treated separately
@ -70,14 +60,14 @@ type Cluster struct {
spec.Postgresql spec.Postgresql
Config Config
logger *logrus.Entry logger *logrus.Entry
pgUsers map[string]spec.PgUser pgUsers map[string]types.PgUser
systemUsers map[string]spec.PgUser systemUsers map[string]types.PgUser
podSubscribers map[spec.NamespacedName]chan spec.PodEvent podSubscribers map[types.NamespacedName]chan types.PodEvent
podSubscribersMu sync.RWMutex podSubscribersMu sync.RWMutex
pgDb *sql.DB pgDb *sql.DB
mu sync.Mutex mu sync.Mutex
masterLess bool masterLess bool
userSyncStrategy spec.UserSyncer userSyncStrategy types.UserSyncer
deleteOptions *v1.DeleteOptions deleteOptions *v1.DeleteOptions
podEventsQueue *cache.FIFO podEventsQueue *cache.FIFO
} }
@ -92,11 +82,11 @@ type compareStatefulsetResult struct {
// New creates a new cluster. This function should be called from a controller. // New creates a new cluster. This function should be called from a controller.
func New(cfg Config, pgSpec spec.Postgresql, logger *logrus.Entry) *Cluster { func New(cfg Config, pgSpec spec.Postgresql, logger *logrus.Entry) *Cluster {
lg := logger.WithField("pkg", "cluster").WithField("cluster-name", pgSpec.Metadata.Name) lg := logger.WithField("pkg", "cluster").WithField("cluster-name", pgSpec.Metadata.Name)
kubeResources := kubeResources{Secrets: make(map[types.UID]*v1.Secret), Service: make(map[PostgresRole]*v1.Service)} kubeResources := kubeResources{Secrets: make(map[ktypes.UID]*v1.Secret), Service: make(map[PostgresRole]*v1.Service)}
orphanDependents := true orphanDependents := true
podEventsQueue := cache.NewFIFO(func(obj interface{}) (string, error) { podEventsQueue := cache.NewFIFO(func(obj interface{}) (string, error) {
e, ok := obj.(spec.PodEvent) e, ok := obj.(types.PodEvent)
if !ok { if !ok {
return "", fmt.Errorf("could not cast to PodEvent") return "", fmt.Errorf("could not cast to PodEvent")
} }
@ -108,9 +98,9 @@ func New(cfg Config, pgSpec spec.Postgresql, logger *logrus.Entry) *Cluster {
Config: cfg, Config: cfg,
Postgresql: pgSpec, Postgresql: pgSpec,
logger: lg, logger: lg,
pgUsers: make(map[string]spec.PgUser), pgUsers: make(map[string]types.PgUser),
systemUsers: make(map[string]spec.PgUser), systemUsers: make(map[string]types.PgUser),
podSubscribers: make(map[spec.NamespacedName]chan spec.PodEvent), podSubscribers: make(map[types.NamespacedName]chan types.PodEvent),
kubeResources: kubeResources, kubeResources: kubeResources,
masterLess: false, masterLess: false,
userSyncStrategy: users.DefaultUserSyncStrategy{}, userSyncStrategy: users.DefaultUserSyncStrategy{},
@ -121,7 +111,7 @@ func New(cfg Config, pgSpec spec.Postgresql, logger *logrus.Entry) *Cluster {
return cluster return cluster
} }
func (c *Cluster) clusterName() spec.NamespacedName { func (c *Cluster) clusterName() types.NamespacedName {
return util.NameFromMeta(c.Metadata) return util.NameFromMeta(c.Metadata)
} }
@ -543,14 +533,14 @@ func (c *Cluster) Delete() error {
} }
// ReceivePodEvent is called back by the controller in order to add the cluster's pod event to the queue. // ReceivePodEvent is called back by the controller in order to add the cluster's pod event to the queue.
func (c *Cluster) ReceivePodEvent(event spec.PodEvent) { func (c *Cluster) ReceivePodEvent(event types.PodEvent) {
if err := c.podEventsQueue.Add(event); err != nil { if err := c.podEventsQueue.Add(event); err != nil {
c.logger.Errorf("error when receiving pod events: %v", err) c.logger.Errorf("error when receiving pod events: %v", err)
} }
} }
func (c *Cluster) processPodEvent(obj interface{}) error { func (c *Cluster) processPodEvent(obj interface{}) error {
event, ok := obj.(spec.PodEvent) event, ok := obj.(types.PodEvent)
if !ok { if !ok {
return fmt.Errorf("could not cast to PodEvent") return fmt.Errorf("could not cast to PodEvent")
} }
@ -588,11 +578,11 @@ func (c *Cluster) initSystemUsers() {
// task to Patroni. Those definitions are only used to create // task to Patroni. Those definitions are only used to create
// secrets, therefore, setting flags like SUPERUSER or REPLICATION // secrets, therefore, setting flags like SUPERUSER or REPLICATION
// is not necessary here // is not necessary here
c.systemUsers[constants.SuperuserKeyName] = spec.PgUser{ c.systemUsers[constants.SuperuserKeyName] = types.PgUser{
Name: c.OpConfig.SuperUsername, Name: c.OpConfig.SuperUsername,
Password: util.RandomPassword(constants.PasswordLength), Password: util.RandomPassword(constants.PasswordLength),
} }
c.systemUsers[constants.ReplicationUserKeyName] = spec.PgUser{ c.systemUsers[constants.ReplicationUserKeyName] = types.PgUser{
Name: c.OpConfig.ReplicationUsername, Name: c.OpConfig.ReplicationUsername,
Password: util.RandomPassword(constants.PasswordLength), Password: util.RandomPassword(constants.PasswordLength),
} }
@ -609,7 +599,7 @@ func (c *Cluster) initRobotUsers() error {
return fmt.Errorf("invalid flags for user '%v': %v", username, err) return fmt.Errorf("invalid flags for user '%v': %v", username, err)
} }
c.pgUsers[username] = spec.PgUser{ c.pgUsers[username] = types.PgUser{
Name: username, Name: username,
Password: util.RandomPassword(constants.PasswordLength), Password: util.RandomPassword(constants.PasswordLength),
Flags: flags, Flags: flags,
@ -627,7 +617,7 @@ func (c *Cluster) initHumanUsers() error {
for _, username := range teamMembers { for _, username := range teamMembers {
flags := []string{constants.RoleFlagLogin, constants.RoleFlagSuperuser} flags := []string{constants.RoleFlagLogin, constants.RoleFlagSuperuser}
memberOf := []string{c.OpConfig.PamRoleName} memberOf := []string{c.OpConfig.PamRoleName}
c.pgUsers[username] = spec.PgUser{Name: username, Flags: flags, MemberOf: memberOf} c.pgUsers[username] = types.PgUser{Name: username, Flags: flags, MemberOf: memberOf}
} }
return nil return nil

View File

@ -4,12 +4,12 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/types"
"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/filesystems" "github.com/zalando-incubator/postgres-operator/pkg/util/filesystems"
) )
func (c *Cluster) getPostgresFilesystemInfo(podName *spec.NamespacedName) (device, fstype string, err error) { func (c *Cluster) getPostgresFilesystemInfo(podName *types.NamespacedName) (device, fstype string, err error) {
out, err := c.ExecCommand(podName, "bash", "-c", fmt.Sprintf("df -T %s|tail -1", constants.PostgresDataMount)) out, err := c.ExecCommand(podName, "bash", "-c", fmt.Sprintf("df -T %s|tail -1", constants.PostgresDataMount))
if err != nil { if err != nil {
return "", "", err return "", "", err
@ -22,7 +22,7 @@ func (c *Cluster) getPostgresFilesystemInfo(podName *spec.NamespacedName) (devic
return fields[0], fields[1], nil return fields[0], fields[1], nil
} }
func (c *Cluster) resizePostgresFilesystem(podName *spec.NamespacedName, resizers []filesystems.FilesystemResizer) error { func (c *Cluster) resizePostgresFilesystem(podName *types.NamespacedName, resizers []filesystems.FilesystemResizer) error {
// resize2fs always writes to stderr, and ExecCommand considers a non-empty stderr an error // resize2fs always writes to stderr, and ExecCommand considers a non-empty stderr an error
// first, determine the device and the filesystem // first, determine the device and the filesystem
deviceName, fsType, err := c.getPostgresFilesystemInfo(podName) deviceName, fsType, err := c.getPostgresFilesystemInfo(podName)

View File

@ -11,6 +11,7 @@ import (
"k8s.io/client-go/pkg/util/intstr" "k8s.io/client-go/pkg/util/intstr"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/spec"
"github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util/constants" "github.com/zalando-incubator/postgres-operator/pkg/util/constants"
) )
@ -404,7 +405,7 @@ func (c *Cluster) genUserSecrets() (secrets map[string]*v1.Secret) {
return return
} }
func (c *Cluster) genSingleUserSecret(namespace string, pgUser spec.PgUser) *v1.Secret { func (c *Cluster) genSingleUserSecret(namespace string, pgUser types.PgUser) *v1.Secret {
//Skip users with no password i.e. human users (they'll be authenticated using pam) //Skip users with no password i.e. human users (they'll be authenticated using pam)
if pgUser.Password == "" { if pgUser.Password == "" {
return nil return nil

View File

@ -7,7 +7,7 @@ import (
"github.com/lib/pq" "github.com/lib/pq"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util/constants" "github.com/zalando-incubator/postgres-operator/pkg/util/constants"
) )
@ -60,9 +60,9 @@ func (c *Cluster) initDbConn() (err error) {
return nil return nil
} }
func (c *Cluster) readPgUsersFromDatabase(userNames []string) (users spec.PgUserMap, err error) { func (c *Cluster) readPgUsersFromDatabase(userNames []string) (users types.PgUserMap, err error) {
var rows *sql.Rows var rows *sql.Rows
users = make(spec.PgUserMap) users = make(types.PgUserMap)
if rows, err = c.pgDb.Query(getUserSQL, pq.Array(userNames)); err != nil { if rows, err = c.pgDb.Query(getUserSQL, pq.Array(userNames)); err != nil {
return nil, fmt.Errorf("error when querying users: %v", err) return nil, fmt.Errorf("error when querying users: %v", err)
} }
@ -85,7 +85,7 @@ func (c *Cluster) readPgUsersFromDatabase(userNames []string) (users spec.PgUser
} }
flags := makeUserFlags(rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin) flags := makeUserFlags(rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin)
// XXX: the code assumes the password we get from pg_authid is always MD5 // XXX: the code assumes the password we get from pg_authid is always MD5
users[rolname] = spec.PgUser{Name: rolname, Password: rolpassword, Flags: flags, MemberOf: memberof} users[rolname] = types.PgUser{Name: rolname, Password: rolpassword, Flags: flags, MemberOf: memberof}
} }
return users, nil return users, nil

View File

@ -5,7 +5,7 @@ import (
"k8s.io/client-go/pkg/api/v1" "k8s.io/client-go/pkg/api/v1"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util" "github.com/zalando-incubator/postgres-operator/pkg/util"
"github.com/zalando-incubator/postgres-operator/pkg/util/constants" "github.com/zalando-incubator/postgres-operator/pkg/util/constants"
) )
@ -50,7 +50,7 @@ func (c *Cluster) deletePods() error {
return nil return nil
} }
func (c *Cluster) deletePod(podName spec.NamespacedName) error { func (c *Cluster) deletePod(podName types.NamespacedName) error {
ch := c.registerPodSubscriber(podName) ch := c.registerPodSubscriber(podName)
defer c.unregisterPodSubscriber(podName) defer c.unregisterPodSubscriber(podName)
@ -65,7 +65,7 @@ func (c *Cluster) deletePod(podName spec.NamespacedName) error {
return nil return nil
} }
func (c *Cluster) unregisterPodSubscriber(podName spec.NamespacedName) { func (c *Cluster) unregisterPodSubscriber(podName types.NamespacedName) {
c.podSubscribersMu.Lock() c.podSubscribersMu.Lock()
defer c.podSubscribersMu.Unlock() defer c.podSubscribersMu.Unlock()
@ -77,11 +77,11 @@ func (c *Cluster) unregisterPodSubscriber(podName spec.NamespacedName) {
delete(c.podSubscribers, podName) delete(c.podSubscribers, podName)
} }
func (c *Cluster) registerPodSubscriber(podName spec.NamespacedName) chan spec.PodEvent { func (c *Cluster) registerPodSubscriber(podName types.NamespacedName) chan types.PodEvent {
c.podSubscribersMu.Lock() c.podSubscribersMu.Lock()
defer c.podSubscribersMu.Unlock() defer c.podSubscribersMu.Unlock()
ch := make(chan spec.PodEvent) ch := make(chan types.PodEvent)
if _, ok := c.podSubscribers[podName]; ok { if _, ok := c.podSubscribers[podName]; ok {
panic("pod '" + podName.String() + "' is already subscribed") panic("pod '" + podName.String() + "' is already subscribed")
} }

View File

@ -7,7 +7,7 @@ import (
"k8s.io/client-go/pkg/api/v1" "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/pkg/apis/apps/v1beta1" "k8s.io/client-go/pkg/apis/apps/v1beta1"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util" "github.com/zalando-incubator/postgres-operator/pkg/util"
"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" "github.com/zalando-incubator/postgres-operator/pkg/util/k8sutil"
@ -318,7 +318,7 @@ func (c *Cluster) applySecrets() error {
for secretUsername, secretSpec := range secrets { for secretUsername, secretSpec := range secrets {
secret, err := c.KubeClient.Secrets(secretSpec.Namespace).Create(secretSpec) secret, err := c.KubeClient.Secrets(secretSpec.Namespace).Create(secretSpec)
if k8sutil.ResourceAlreadyExists(err) { if k8sutil.ResourceAlreadyExists(err) {
var userMap map[string]spec.PgUser var userMap map[string]types.PgUser
curSecret, err := c.KubeClient.Secrets(secretSpec.Namespace).Get(secretSpec.Name) curSecret, err := c.KubeClient.Secrets(secretSpec.Namespace).Get(secretSpec.Name)
if err != nil { if err != nil {
return fmt.Errorf("could not get current secret: %v", err) return fmt.Errorf("could not get current secret: %v", err)

View File

@ -16,6 +16,7 @@ import (
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand" "k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/spec"
"github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util" "github.com/zalando-incubator/postgres-operator/pkg/util"
"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/retryutil" "github.com/zalando-incubator/postgres-operator/pkg/util/retryutil"
@ -159,7 +160,7 @@ func (c *Cluster) getTeamMembers() ([]string, error) {
return teamInfo.Members, nil return teamInfo.Members, nil
} }
func (c *Cluster) waitForPodLabel(podEvents chan spec.PodEvent) error { func (c *Cluster) waitForPodLabel(podEvents chan types.PodEvent) error {
for { for {
select { select {
case podEvent := <-podEvents: case podEvent := <-podEvents:
@ -176,11 +177,11 @@ func (c *Cluster) waitForPodLabel(podEvents chan spec.PodEvent) error {
} }
} }
func (c *Cluster) waitForPodDeletion(podEvents chan spec.PodEvent) error { func (c *Cluster) waitForPodDeletion(podEvents chan types.PodEvent) error {
for { for {
select { select {
case podEvent := <-podEvents: case podEvent := <-podEvents:
if podEvent.EventType == spec.EventDelete { if podEvent.EventType == types.EventDelete {
return nil return nil
} }
case <-time.After(c.OpConfig.PodDeletionWaitTimeout): case <-time.After(c.OpConfig.PodDeletionWaitTimeout):
@ -313,7 +314,7 @@ func (c *Cluster) podSpiloRole(pod *v1.Pod) string {
return pod.Labels[c.OpConfig.PodRoleLabel] return pod.Labels[c.OpConfig.PodRoleLabel]
} }
func (c *Cluster) ExecCommand(podName *spec.NamespacedName, command ...string) (string, error) { func (c *Cluster) ExecCommand(podName *types.NamespacedName, command ...string) (string, error) {
var ( var (
execOut bytes.Buffer execOut bytes.Buffer
execErr bytes.Buffer execErr bytes.Buffer

View File

@ -9,6 +9,7 @@ import (
"k8s.io/client-go/pkg/api/v1" "k8s.io/client-go/pkg/api/v1"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/spec"
"github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util" "github.com/zalando-incubator/postgres-operator/pkg/util"
"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/filesystems" "github.com/zalando-incubator/postgres-operator/pkg/util/filesystems"
@ -172,11 +173,11 @@ func (c *Cluster) listVolumesWithManifestSize(newVolume spec.Volume) ([]*v1.Pers
} }
// getPodNameFromPersistentVolume returns a pod name that it extracts from the volume claim ref. // getPodNameFromPersistentVolume returns a pod name that it extracts from the volume claim ref.
func getPodNameFromPersistentVolume(pv *v1.PersistentVolume) *spec.NamespacedName { func getPodNameFromPersistentVolume(pv *v1.PersistentVolume) *types.NamespacedName {
namespace := pv.Spec.ClaimRef.Namespace namespace := pv.Spec.ClaimRef.Namespace
name := pv.Spec.ClaimRef.Name[len(constants.DataVolumeName)+1:] name := pv.Spec.ClaimRef.Name[len(constants.DataVolumeName)+1:]
return &spec.NamespacedName{namespace, name} return &types.NamespacedName{namespace, name}
} }
func quantityToGigabyte(q resource.Quantity) int64 { func quantityToGigabyte(q resource.Quantity) int64 {

View File

@ -10,8 +10,8 @@ import (
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
"github.com/zalando-incubator/postgres-operator/pkg/cluster"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/spec"
"github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util/config" "github.com/zalando-incubator/postgres-operator/pkg/util/config"
"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/teams" "github.com/zalando-incubator/postgres-operator/pkg/util/teams"
@ -22,7 +22,7 @@ type Config struct {
KubeClient *kubernetes.Clientset KubeClient *kubernetes.Clientset
RestClient *rest.RESTClient RestClient *rest.RESTClient
TeamsAPIClient *teams.API TeamsAPIClient *teams.API
InfrastructureRoles map[string]spec.PgUser InfrastructureRoles map[string]types.PgUser
} }
type Controller struct { type Controller struct {
@ -31,12 +31,12 @@ type Controller struct {
logger *logrus.Entry logger *logrus.Entry
clustersMu sync.RWMutex clustersMu sync.RWMutex
clusters map[spec.NamespacedName]cluster.Interface clusters map[types.NamespacedName]types.Cluster
stopChs map[spec.NamespacedName]chan struct{} stopChs map[types.NamespacedName]chan struct{}
postgresqlInformer cache.SharedIndexInformer postgresqlInformer cache.SharedIndexInformer
podInformer cache.SharedIndexInformer podInformer cache.SharedIndexInformer
podCh chan spec.PodEvent podCh chan types.PodEvent
clusterEventQueues []*cache.FIFO clusterEventQueues []*cache.FIFO
@ -56,9 +56,9 @@ func New(controllerConfig *Config, operatorConfig *config.Config) *Controller {
Config: *controllerConfig, Config: *controllerConfig,
opConfig: operatorConfig, opConfig: operatorConfig,
logger: logger.WithField("pkg", "controller"), logger: logger.WithField("pkg", "controller"),
clusters: make(map[spec.NamespacedName]cluster.Interface), clusters: make(map[types.NamespacedName]types.Cluster),
stopChs: make(map[spec.NamespacedName]chan struct{}), stopChs: make(map[types.NamespacedName]chan struct{}),
podCh: make(chan spec.PodEvent), podCh: make(chan types.PodEvent),
} }
} }
@ -130,7 +130,7 @@ func (c *Controller) initController() {
c.clusterEventQueues = make([]*cache.FIFO, c.opConfig.Workers) c.clusterEventQueues = make([]*cache.FIFO, c.opConfig.Workers)
for i := range c.clusterEventQueues { for i := range c.clusterEventQueues {
c.clusterEventQueues[i] = cache.NewFIFO(func(obj interface{}) (string, error) { c.clusterEventQueues[i] = cache.NewFIFO(func(obj interface{}) (string, error) {
e, ok := obj.(spec.ClusterEvent) e, ok := obj.(types.ClusterEvent)
if !ok { if !ok {
return "", fmt.Errorf("could not cast to ClusterEvent") return "", fmt.Errorf("could not cast to ClusterEvent")
} }

View File

@ -6,7 +6,7 @@ import (
"k8s.io/client-go/pkg/runtime" "k8s.io/client-go/pkg/runtime"
"k8s.io/client-go/pkg/watch" "k8s.io/client-go/pkg/watch"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util" "github.com/zalando-incubator/postgres-operator/pkg/util"
) )
@ -61,11 +61,11 @@ func (c *Controller) podAdd(obj interface{}) {
return return
} }
podEvent := spec.PodEvent{ podEvent := types.PodEvent{
ClusterName: c.podClusterName(pod), ClusterName: c.podClusterName(pod),
PodName: util.NameFromMeta(pod.ObjectMeta), PodName: util.NameFromMeta(pod.ObjectMeta),
CurPod: pod, CurPod: pod,
EventType: spec.EventAdd, EventType: types.EventAdd,
ResourceVersion: pod.ResourceVersion, ResourceVersion: pod.ResourceVersion,
} }
@ -83,12 +83,12 @@ func (c *Controller) podUpdate(prev, cur interface{}) {
return return
} }
podEvent := spec.PodEvent{ podEvent := types.PodEvent{
ClusterName: c.podClusterName(curPod), ClusterName: c.podClusterName(curPod),
PodName: util.NameFromMeta(curPod.ObjectMeta), PodName: util.NameFromMeta(curPod.ObjectMeta),
PrevPod: prevPod, PrevPod: prevPod,
CurPod: curPod, CurPod: curPod,
EventType: spec.EventUpdate, EventType: types.EventUpdate,
ResourceVersion: curPod.ResourceVersion, ResourceVersion: curPod.ResourceVersion,
} }
@ -101,11 +101,11 @@ func (c *Controller) podDelete(obj interface{}) {
return return
} }
podEvent := spec.PodEvent{ podEvent := types.PodEvent{
ClusterName: c.podClusterName(pod), ClusterName: c.podClusterName(pod),
PodName: util.NameFromMeta(pod.ObjectMeta), PodName: util.NameFromMeta(pod.ObjectMeta),
CurPod: pod, CurPod: pod,
EventType: spec.EventDelete, EventType: types.EventDelete,
ResourceVersion: pod.ResourceVersion, ResourceVersion: pod.ResourceVersion,
} }

View File

@ -10,12 +10,13 @@ import (
"k8s.io/client-go/pkg/api/meta" "k8s.io/client-go/pkg/api/meta"
"k8s.io/client-go/pkg/fields" "k8s.io/client-go/pkg/fields"
"k8s.io/client-go/pkg/runtime" "k8s.io/client-go/pkg/runtime"
"k8s.io/client-go/pkg/types" ktypes "k8s.io/client-go/pkg/types"
"k8s.io/client-go/pkg/watch" "k8s.io/client-go/pkg/watch"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
"github.com/zalando-incubator/postgres-operator/pkg/cluster" "github.com/zalando-incubator/postgres-operator/pkg/cluster"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/spec"
"github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util" "github.com/zalando-incubator/postgres-operator/pkg/util"
"github.com/zalando-incubator/postgres-operator/pkg/util/constants" "github.com/zalando-incubator/postgres-operator/pkg/util/constants"
) )
@ -68,7 +69,7 @@ func (c *Controller) clusterListFunc(options api.ListOptions) (runtime.Object, e
failedClustersCnt++ failedClustersCnt++
continue continue
} }
c.queueClusterEvent(nil, pg, spec.EventSync) c.queueClusterEvent(nil, pg, types.EventSync)
activeClustersCnt++ activeClustersCnt++
} }
if len(objList) > 0 { if len(objList) > 0 {
@ -97,15 +98,15 @@ func (c *Controller) clusterWatchFunc(options api.ListOptions) (watch.Interface,
} }
func (c *Controller) processEvent(obj interface{}) error { func (c *Controller) processEvent(obj interface{}) error {
var clusterName spec.NamespacedName var clusterName types.NamespacedName
event, ok := obj.(spec.ClusterEvent) event, ok := obj.(types.ClusterEvent)
if !ok { if !ok {
return fmt.Errorf("could not cast to ClusterEvent") return fmt.Errorf("could not cast to ClusterEvent")
} }
logger := c.logger.WithField("worker", event.WorkerID) logger := c.logger.WithField("worker", event.WorkerID)
if event.EventType == spec.EventAdd || event.EventType == spec.EventSync { if event.EventType == types.EventAdd || event.EventType == types.EventSync {
clusterName = util.NameFromMeta(event.NewSpec.Metadata) clusterName = util.NameFromMeta(event.NewSpec.Metadata)
} else { } else {
clusterName = util.NameFromMeta(event.OldSpec.Metadata) clusterName = util.NameFromMeta(event.OldSpec.Metadata)
@ -116,7 +117,7 @@ func (c *Controller) processEvent(obj interface{}) error {
c.clustersMu.RUnlock() c.clustersMu.RUnlock()
switch event.EventType { switch event.EventType {
case spec.EventAdd: case types.EventAdd:
if clusterFound { if clusterFound {
logger.Debugf("Cluster '%s' already exists", clusterName) logger.Debugf("Cluster '%s' already exists", clusterName)
return nil return nil
@ -142,7 +143,7 @@ func (c *Controller) processEvent(obj interface{}) error {
} }
logger.Infof("Cluster '%s' has been created", clusterName) logger.Infof("Cluster '%s' has been created", clusterName)
case spec.EventUpdate: case types.EventUpdate:
logger.Infof("Update of the '%s' cluster started", clusterName) logger.Infof("Update of the '%s' cluster started", clusterName)
if !clusterFound { if !clusterFound {
@ -158,7 +159,7 @@ func (c *Controller) processEvent(obj interface{}) error {
} }
cl.SetFailed(nil) cl.SetFailed(nil)
logger.Infof("Cluster '%s' has been updated", clusterName) logger.Infof("Cluster '%s' has been updated", clusterName)
case spec.EventDelete: case types.EventDelete:
logger.Infof("Deletion of the '%s' cluster started", clusterName) logger.Infof("Deletion of the '%s' cluster started", clusterName)
if !clusterFound { if !clusterFound {
logger.Errorf("Unknown cluster: %s", clusterName) logger.Errorf("Unknown cluster: %s", clusterName)
@ -177,7 +178,7 @@ func (c *Controller) processEvent(obj interface{}) error {
c.clustersMu.Unlock() c.clustersMu.Unlock()
logger.Infof("Cluster '%s' has been deleted", clusterName) logger.Infof("Cluster '%s' has been deleted", clusterName)
case spec.EventSync: case types.EventSync:
logger.Infof("Syncing of the '%s' cluster started", clusterName) logger.Infof("Syncing of the '%s' cluster started", clusterName)
// no race condition because a cluster is always processed by single worker // no race condition because a cluster is always processed by single worker
@ -214,18 +215,18 @@ func (c *Controller) processClusterEventsQueue(idx int) {
} }
} }
func (c *Controller) queueClusterEvent(old, new *spec.Postgresql, eventType spec.EventType) { func (c *Controller) queueClusterEvent(old, new *spec.Postgresql, eventType types.EventType) {
var ( var (
uid types.UID uid ktypes.UID
clusterName spec.NamespacedName clusterName types.NamespacedName
clusterError error clusterError error
) )
if old != nil { //update, delete if old != nil { //update, delete
uid = old.Metadata.GetUID() uid = old.Metadata.GetUID()
clusterName = util.NameFromMeta(old.Metadata) clusterName = util.NameFromMeta(old.Metadata)
if eventType == spec.EventUpdate && new.Error == nil && old.Error != nil { if eventType == types.EventUpdate && new.Error == nil && old.Error != nil {
eventType = spec.EventSync eventType = types.EventSync
clusterError = new.Error clusterError = new.Error
} else { } else {
clusterError = old.Error clusterError = old.Error
@ -236,13 +237,13 @@ func (c *Controller) queueClusterEvent(old, new *spec.Postgresql, eventType spec
clusterError = new.Error clusterError = new.Error
} }
if clusterError != nil && eventType != spec.EventDelete { if clusterError != nil && eventType != types.EventDelete {
c.logger.Debugf("Skipping %s event for invalid cluster %s (reason: %v)", eventType, clusterName, clusterError) c.logger.Debugf("Skipping %s event for invalid cluster %s (reason: %v)", eventType, clusterName, clusterError)
return return
} }
workerID := c.clusterWorkerID(clusterName) workerID := c.clusterWorkerID(clusterName)
clusterEvent := spec.ClusterEvent{ clusterEvent := types.ClusterEvent{
EventType: eventType, EventType: eventType,
UID: uid, UID: uid,
OldSpec: old, OldSpec: old,
@ -265,7 +266,7 @@ func (c *Controller) postgresqlAdd(obj interface{}) {
} }
// We will not get multiple Add events for the same cluster // We will not get multiple Add events for the same cluster
c.queueClusterEvent(nil, pg, spec.EventAdd) c.queueClusterEvent(nil, pg, types.EventAdd)
} }
func (c *Controller) postgresqlUpdate(prev, cur interface{}) { func (c *Controller) postgresqlUpdate(prev, cur interface{}) {
@ -284,7 +285,7 @@ func (c *Controller) postgresqlUpdate(prev, cur interface{}) {
return return
} }
c.queueClusterEvent(pgOld, pgNew, spec.EventUpdate) c.queueClusterEvent(pgOld, pgNew, types.EventUpdate)
} }
func (c *Controller) postgresqlDelete(obj interface{}) { func (c *Controller) postgresqlDelete(obj interface{}) {
@ -294,5 +295,5 @@ func (c *Controller) postgresqlDelete(obj interface{}) {
return return
} }
c.queueClusterEvent(pg, nil, spec.EventDelete) c.queueClusterEvent(pg, nil, types.EventDelete)
} }

View File

@ -8,14 +8,14 @@ import (
extv1beta "k8s.io/client-go/pkg/apis/extensions/v1beta1" extv1beta "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"github.com/zalando-incubator/postgres-operator/pkg/cluster" "github.com/zalando-incubator/postgres-operator/pkg/cluster"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util/config" "github.com/zalando-incubator/postgres-operator/pkg/util/config"
"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" "github.com/zalando-incubator/postgres-operator/pkg/util/k8sutil"
) )
func (c *Controller) makeClusterConfig() cluster.Config { func (c *Controller) makeClusterConfig() cluster.Config {
infrastructureRoles := make(map[string]spec.PgUser) infrastructureRoles := make(map[string]types.PgUser)
for k, v := range c.InfrastructureRoles { for k, v := range c.InfrastructureRoles {
infrastructureRoles[k] = v infrastructureRoles[k] = v
} }
@ -43,7 +43,7 @@ func thirdPartyResource(TPRName string) *extv1beta.ThirdPartyResource {
} }
} }
func (c *Controller) clusterWorkerID(clusterName spec.NamespacedName) uint32 { func (c *Controller) clusterWorkerID(clusterName types.NamespacedName) uint32 {
return crc32.ChecksumIEEE([]byte(clusterName.String())) % c.opConfig.Workers return crc32.ChecksumIEEE([]byte(clusterName.String())) % c.opConfig.Workers
} }
@ -64,8 +64,8 @@ func (c *Controller) createTPR() error {
return k8sutil.WaitTPRReady(c.RestClient, c.opConfig.TPR.ReadyWaitInterval, c.opConfig.TPR.ReadyWaitTimeout, c.opConfig.Namespace) return k8sutil.WaitTPRReady(c.RestClient, c.opConfig.TPR.ReadyWaitInterval, c.opConfig.TPR.ReadyWaitTimeout, c.opConfig.Namespace)
} }
func (c *Controller) getInfrastructureRoles() (result map[string]spec.PgUser, err error) { func (c *Controller) getInfrastructureRoles() (result map[string]types.PgUser, err error) {
if c.opConfig.InfrastructureRolesSecretName == (spec.NamespacedName{}) { if c.opConfig.InfrastructureRolesSecretName == (types.NamespacedName{}) {
// we don't have infrastructure roles defined, bail out // we don't have infrastructure roles defined, bail out
return nil, nil return nil, nil
} }
@ -79,12 +79,12 @@ func (c *Controller) getInfrastructureRoles() (result map[string]spec.PgUser, er
} }
data := infraRolesSecret.Data data := infraRolesSecret.Data
result = make(map[string]spec.PgUser) result = make(map[string]types.PgUser)
Users: Users:
// in worst case we would have one line per user // in worst case we would have one line per user
for i := 1; i <= len(data); i++ { for i := 1; i <= len(data); i++ {
properties := []string{"user", "password", "inrole"} properties := []string{"user", "password", "inrole"}
t := spec.PgUser{} t := types.PgUser{}
for _, p := range properties { for _, p := range properties {
key := fmt.Sprintf("%s%d", p, i) key := fmt.Sprintf("%s%d", p, i)
if val, present := data[key]; !present { if val, present := data[key]; !present {
@ -115,13 +115,13 @@ Users:
return result, nil return result, nil
} }
func (c *Controller) podClusterName(pod *v1.Pod) spec.NamespacedName { func (c *Controller) podClusterName(pod *v1.Pod) types.NamespacedName {
if name, ok := pod.Labels[c.opConfig.ClusterNameLabel]; ok { if name, ok := pod.Labels[c.opConfig.ClusterNameLabel]; ok {
return spec.NamespacedName{ return types.NamespacedName{
Namespace: pod.Namespace, Namespace: pod.Namespace,
Name: name, Name: name,
} }
} }
return spec.NamespacedName{} return types.NamespacedName{}
} }

View File

@ -0,0 +1,41 @@
package types
import (
"fmt"
"strings"
"k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/pkg/types"
)
// NamespacedName describes the namespace/name pairs used in Kubernetes names.
type NamespacedName types.NamespacedName
func (n NamespacedName) String() string {
return types.NamespacedName(n).String()
}
// MarshalJSON defines marshaling rule for the namespaced name type.
func (n NamespacedName) MarshalJSON() ([]byte, error) {
return []byte("\"" + n.String() + "\""), nil
}
// Decode converts a (possibly unqualified) string into the namespaced name object.
func (n *NamespacedName) Decode(value string) error {
name := types.NewNamespacedNameFromString(value)
if strings.Trim(value, string(types.Separator)) != "" && name == (types.NamespacedName{}) {
name.Name = value
name.Namespace = v1.NamespaceDefault
} else if name.Namespace == "" {
name.Namespace = v1.NamespaceDefault
}
if name.Name == "" {
return fmt.Errorf("Incorrect namespaced name")
}
*n = NamespacedName(name)
return nil
}

View File

@ -1,20 +1,17 @@
package spec package types
import ( import (
"database/sql" "database/sql"
"fmt"
"strings"
"k8s.io/client-go/pkg/api/v1" "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/pkg/types" "k8s.io/client-go/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/spec"
) )
// EvenType contains type of the events for the TPRs and Pods received from Kubernetes // EvenType contains type of the events for the TPRs and Pods received from Kubernetes
type EventType string type EventType string
// NamespacedName describes the namespace/name pairs used in Kubernetes names.
type NamespacedName types.NamespacedName
// Possible values for the EventType // Possible values for the EventType
const ( const (
EventAdd EventType = "ADD" EventAdd EventType = "ADD"
@ -27,8 +24,8 @@ const (
type ClusterEvent struct { type ClusterEvent struct {
UID types.UID UID types.UID
EventType EventType EventType EventType
OldSpec *Postgresql OldSpec *spec.Postgresql
NewSpec *Postgresql NewSpec *spec.Postgresql
WorkerID uint32 WorkerID uint32
} }
@ -73,31 +70,13 @@ type UserSyncer interface {
ExecuteSyncRequests(req []PgSyncUserRequest, db *sql.DB) error ExecuteSyncRequests(req []PgSyncUserRequest, db *sql.DB) error
} }
func (n NamespacedName) String() string { type Cluster interface {
return types.NamespacedName(n).String() Create() error
} Delete() error
ExecCommand(podName *NamespacedName, command ...string) (string, error)
// MarshalJSON defines marshaling rule for the namespaced name type. ReceivePodEvent(event PodEvent)
func (n NamespacedName) MarshalJSON() ([]byte, error) { Run(stopCh <-chan struct{})
return []byte("\"" + n.String() + "\""), nil Sync() error
} Update(newSpec *spec.Postgresql) error
SetFailed(err error)
// Decode converts a (possibly unqualified) string into the namespaced name object.
func (n *NamespacedName) Decode(value string) error {
name := types.NewNamespacedNameFromString(value)
if strings.Trim(value, string(types.Separator)) != "" && name == (types.NamespacedName{}) {
name.Name = value
name.Namespace = v1.NamespaceDefault
} else if name.Namespace == "" {
name.Namespace = v1.NamespaceDefault
}
if name.Name == "" {
return fmt.Errorf("Incorrect namespaced name")
}
*n = NamespacedName(name)
return nil
} }

View File

@ -1,4 +1,4 @@
package spec package types
import ( import (
"bytes" "bytes"

View File

@ -5,7 +5,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/types"
) )
type TPR struct { type TPR struct {
@ -29,13 +29,13 @@ type Resources struct {
} }
type Auth struct { type Auth struct {
PamRoleName string `name:"pam_rol_name" default:"zalandos"` 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"` 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/"` TeamsAPIUrl string `name:"teams_api_url" default:"https://teams.example.com/api/"`
OAuthTokenSecretName spec.NamespacedName `name:"oauth_token_secret_name" default:"postgresql-operator"` OAuthTokenSecretName types.NamespacedName `name:"oauth_token_secret_name" default:"postgresql-operator"`
InfrastructureRolesSecretName spec.NamespacedName `name:"infrastructure_roles_secret_name"` InfrastructureRolesSecretName types.NamespacedName `name:"infrastructure_roles_secret_name"`
SuperUsername string `name:"super_username" default:"postgres"` SuperUsername string `name:"super_username" default:"postgres"`
ReplicationUsername string `name:"replication_username" default:"replication"` ReplicationUsername string `name:"replication_username" default:"replication"`
} }
type Config struct { type Config struct {

View File

@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/types"
"github.com/zalando-incubator/postgres-operator/pkg/util" "github.com/zalando-incubator/postgres-operator/pkg/util"
) )
@ -26,31 +26,31 @@ type DefaultUserSyncStrategy struct {
} }
// ProduceSyncRequests figures out the types of changes that need to happen with the given users. // ProduceSyncRequests figures out the types of changes that need to happen with the given users.
func (s DefaultUserSyncStrategy) ProduceSyncRequests(dbUsers spec.PgUserMap, func (s DefaultUserSyncStrategy) ProduceSyncRequests(dbUsers types.PgUserMap,
newUsers spec.PgUserMap) (reqs []spec.PgSyncUserRequest) { newUsers types.PgUserMap) (reqs []types.PgSyncUserRequest) {
// No existing roles are deleted or stripped of role memebership/flags // No existing roles are deleted or stripped of role memebership/flags
for name, newUser := range newUsers { for name, newUser := range newUsers {
dbUser, exists := dbUsers[name] dbUser, exists := dbUsers[name]
if !exists { if !exists {
reqs = append(reqs, spec.PgSyncUserRequest{Kind: spec.PGSyncUserAdd, User: newUser}) reqs = append(reqs, types.PgSyncUserRequest{Kind: types.PGSyncUserAdd, User: newUser})
} else { } else {
r := spec.PgSyncUserRequest{} r := types.PgSyncUserRequest{}
newMD5Password := util.PGUserPassword(newUser) newMD5Password := util.PGUserPassword(newUser)
if dbUser.Password != newMD5Password { if dbUser.Password != newMD5Password {
r.User.Password = newMD5Password r.User.Password = newMD5Password
r.Kind = spec.PGsyncUserAlter r.Kind = types.PGsyncUserAlter
} }
if addNewRoles, equal := util.SubstractStringSlices(newUser.MemberOf, dbUser.MemberOf); !equal { if addNewRoles, equal := util.SubstractStringSlices(newUser.MemberOf, dbUser.MemberOf); !equal {
r.User.MemberOf = addNewRoles r.User.MemberOf = addNewRoles
r.Kind = spec.PGsyncUserAlter r.Kind = types.PGsyncUserAlter
} }
if addNewFlags, equal := util.SubstractStringSlices(newUser.Flags, dbUser.Flags); !equal { if addNewFlags, equal := util.SubstractStringSlices(newUser.Flags, dbUser.Flags); !equal {
r.User.Flags = addNewFlags r.User.Flags = addNewFlags
r.Kind = spec.PGsyncUserAlter r.Kind = types.PGsyncUserAlter
} }
if r.Kind == spec.PGsyncUserAlter { if r.Kind == types.PGsyncUserAlter {
r.User.Name = newUser.Name r.User.Name = newUser.Name
reqs = append(reqs, r) reqs = append(reqs, r)
} }
@ -61,14 +61,14 @@ func (s DefaultUserSyncStrategy) ProduceSyncRequests(dbUsers spec.PgUserMap,
} }
// ExecuteSyncRequests makes actual database changes from the requests passed in its arguments. // ExecuteSyncRequests makes actual database changes from the requests passed in its arguments.
func (s DefaultUserSyncStrategy) ExecuteSyncRequests(reqs []spec.PgSyncUserRequest, db *sql.DB) error { func (s DefaultUserSyncStrategy) ExecuteSyncRequests(reqs []types.PgSyncUserRequest, db *sql.DB) error {
for _, r := range reqs { for _, r := range reqs {
switch r.Kind { switch r.Kind {
case spec.PGSyncUserAdd: case types.PGSyncUserAdd:
if err := s.createPgUser(r.User, db); err != nil { if err := s.createPgUser(r.User, db); err != nil {
return fmt.Errorf("could not create user '%s': %v", r.User.Name, err) return fmt.Errorf("could not create user '%s': %v", r.User.Name, err)
} }
case spec.PGsyncUserAlter: case types.PGsyncUserAlter:
if err := s.alterPgUser(r.User, db); err != nil { if err := s.alterPgUser(r.User, db); err != nil {
return fmt.Errorf("could not alter user '%s': %v", r.User.Name, err) return fmt.Errorf("could not alter user '%s': %v", r.User.Name, err)
} }
@ -80,7 +80,7 @@ func (s DefaultUserSyncStrategy) ExecuteSyncRequests(reqs []spec.PgSyncUserReque
return nil return nil
} }
func (s DefaultUserSyncStrategy) createPgUser(user spec.PgUser, db *sql.DB) (err error) { func (s DefaultUserSyncStrategy) createPgUser(user types.PgUser, db *sql.DB) (err error) {
var userFlags []string var userFlags []string
var userPassword string var userPassword string
@ -107,7 +107,7 @@ func (s DefaultUserSyncStrategy) createPgUser(user spec.PgUser, db *sql.DB) (err
return return
} }
func (s DefaultUserSyncStrategy) alterPgUser(user spec.PgUser, db *sql.DB) (err error) { func (s DefaultUserSyncStrategy) alterPgUser(user types.PgUser, db *sql.DB) (err error) {
var resultStmt []string var resultStmt []string
if user.Password != "" || len(user.Flags) > 0 { if user.Password != "" || len(user.Flags) > 0 {
@ -129,7 +129,7 @@ func (s DefaultUserSyncStrategy) alterPgUser(user spec.PgUser, db *sql.DB) (err
return return
} }
func produceAlterStmt(user spec.PgUser) string { func produceAlterStmt(user types.PgUser) string {
// ALTER ROLE ... LOGIN ENCRYPTED PASSWORD .. // ALTER ROLE ... LOGIN ENCRYPTED PASSWORD ..
result := make([]string, 1) result := make([]string, 1)
password := user.Password password := user.Password
@ -144,12 +144,12 @@ func produceAlterStmt(user spec.PgUser) string {
return fmt.Sprintf(alterUserSQL, user.Name, strings.Join(result, " ")) return fmt.Sprintf(alterUserSQL, user.Name, strings.Join(result, " "))
} }
func produceGrantStmt(user spec.PgUser) string { func produceGrantStmt(user types.PgUser) string {
// GRANT ROLE "foo", "bar" TO baz // GRANT ROLE "foo", "bar" TO baz
return fmt.Sprintf(grantToUserSQL, quoteMemberList(user), user.Name) return fmt.Sprintf(grantToUserSQL, quoteMemberList(user), user.Name)
} }
func quoteMemberList(user spec.PgUser) string { func quoteMemberList(user types.PgUser) string {
var memberof []string var memberof []string
for _, member := range user.MemberOf { for _, member := range user.MemberOf {
memberof = append(memberof, fmt.Sprintf(`"%s"`, member)) memberof = append(memberof, fmt.Sprintf(`"%s"`, member))

View File

@ -10,7 +10,7 @@ import (
"github.com/motomux/pretty" "github.com/motomux/pretty"
"k8s.io/client-go/pkg/api/v1" "k8s.io/client-go/pkg/api/v1"
"github.com/zalando-incubator/postgres-operator/pkg/spec" "github.com/zalando-incubator/postgres-operator/pkg/types"
) )
const ( const (
@ -34,15 +34,15 @@ func RandomPassword(n int) string {
} }
// NameFromMeta converts a metadata object to the NamespacedName name representation. // NameFromMeta converts a metadata object to the NamespacedName name representation.
func NameFromMeta(meta v1.ObjectMeta) spec.NamespacedName { func NameFromMeta(meta v1.ObjectMeta) types.NamespacedName {
return spec.NamespacedName{ return types.NamespacedName{
Namespace: meta.Namespace, Namespace: meta.Namespace,
Name: meta.Name, Name: meta.Name,
} }
} }
// PGUserPassword is used to generate md5 password hash for a given user. It does nothing for already hashed passwords. // PGUserPassword is used to generate md5 password hash for a given user. It does nothing for already hashed passwords.
func PGUserPassword(user spec.PgUser) string { func PGUserPassword(user types.PgUser) string {
if (len(user.Password) == md5.Size*2+len(md5prefix) && user.Password[:3] == md5prefix) || user.Password == "" { if (len(user.Password) == md5.Size*2+len(md5prefix) && user.Password[:3] == md5prefix) || user.Password == "" {
// Avoid processing already encrypted or empty passwords // Avoid processing already encrypted or empty passwords
return user.Password return user.Password

View File

@ -10,15 +10,15 @@ import (
) )
var pgUsers = []struct { var pgUsers = []struct {
in spec.PgUser in types.PgUser
out string out string
}{{spec.PgUser{ }{{types.PgUser{
Name: "test", Name: "test",
Password: "password", Password: "password",
Flags: []string{}, Flags: []string{},
MemberOf: []string{}}, MemberOf: []string{}},
"md587f77988ccb5aa917c93201ba314fcd4"}, "md587f77988ccb5aa917c93201ba314fcd4"},
{spec.PgUser{ {types.PgUser{
Name: "test", Name: "test",
Password: "md592f413f3974bdf3799bb6fecb5f9f2c6", Password: "md592f413f3974bdf3799bb6fecb5f9f2c6",
Flags: []string{}, Flags: []string{},
@ -58,7 +58,7 @@ func TestNameFromMeta(t *testing.T) {
Namespace: "default", Namespace: "default",
} }
expected := spec.NamespacedName{ expected := types.NamespacedName{
Name: "testcluster", Name: "testcluster",
Namespace: "default", Namespace: "default",
} }