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"
"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/k8sutil"
)
@ -17,7 +17,7 @@ import (
var (
KubeConfigFile string
podNamespace string
configMapName spec.NamespacedName
configMapName types.NamespacedName
OutOfCluster bool
noTeamsAPI bool
noDatabaseAccess bool
@ -78,7 +78,7 @@ func main() {
controllerConfig := ControllerConfig()
if configMapName != (spec.NamespacedName{}) {
if configMapName != (types.NamespacedName{}) {
configMap, err := controllerConfig.KubeClient.ConfigMaps(configMapName.Namespace).Get(configMapName.Name)
if err != nil {
panic(err)

View File

@ -14,11 +14,12 @@ import (
"k8s.io/client-go/pkg/api"
"k8s.io/client-go/pkg/api/v1"
"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/tools/cache"
"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/config"
"github.com/zalando-incubator/postgres-operator/pkg/util/constants"
@ -28,17 +29,6 @@ import (
"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
const (
@ -53,13 +43,13 @@ type Config struct {
RestConfig *rest.Config
TeamsAPIClient *teams.API
OpConfig config.Config
InfrastructureRoles map[string]spec.PgUser // inherited from the controller
InfrastructureRoles map[string]types.PgUser // inherited from the controller
}
type kubeResources struct {
Service map[PostgresRole]*v1.Service
Endpoint *v1.Endpoints
Secrets map[types.UID]*v1.Secret
Secrets map[ktypes.UID]*v1.Secret
Statefulset *v1beta1.StatefulSet
//Pods are treated separately
//PVCs are treated separately
@ -70,14 +60,14 @@ type Cluster struct {
spec.Postgresql
Config
logger *logrus.Entry
pgUsers map[string]spec.PgUser
systemUsers map[string]spec.PgUser
podSubscribers map[spec.NamespacedName]chan spec.PodEvent
pgUsers map[string]types.PgUser
systemUsers map[string]types.PgUser
podSubscribers map[types.NamespacedName]chan types.PodEvent
podSubscribersMu sync.RWMutex
pgDb *sql.DB
mu sync.Mutex
masterLess bool
userSyncStrategy spec.UserSyncer
userSyncStrategy types.UserSyncer
deleteOptions *v1.DeleteOptions
podEventsQueue *cache.FIFO
}
@ -92,11 +82,11 @@ type compareStatefulsetResult struct {
// New creates a new cluster. This function should be called from a controller.
func New(cfg Config, pgSpec spec.Postgresql, logger *logrus.Entry) *Cluster {
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
podEventsQueue := cache.NewFIFO(func(obj interface{}) (string, error) {
e, ok := obj.(spec.PodEvent)
e, ok := obj.(types.PodEvent)
if !ok {
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,
Postgresql: pgSpec,
logger: lg,
pgUsers: make(map[string]spec.PgUser),
systemUsers: make(map[string]spec.PgUser),
podSubscribers: make(map[spec.NamespacedName]chan spec.PodEvent),
pgUsers: make(map[string]types.PgUser),
systemUsers: make(map[string]types.PgUser),
podSubscribers: make(map[types.NamespacedName]chan types.PodEvent),
kubeResources: kubeResources,
masterLess: false,
userSyncStrategy: users.DefaultUserSyncStrategy{},
@ -121,7 +111,7 @@ func New(cfg Config, pgSpec spec.Postgresql, logger *logrus.Entry) *Cluster {
return cluster
}
func (c *Cluster) clusterName() spec.NamespacedName {
func (c *Cluster) clusterName() types.NamespacedName {
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.
func (c *Cluster) ReceivePodEvent(event spec.PodEvent) {
func (c *Cluster) ReceivePodEvent(event types.PodEvent) {
if err := c.podEventsQueue.Add(event); err != nil {
c.logger.Errorf("error when receiving pod events: %v", err)
}
}
func (c *Cluster) processPodEvent(obj interface{}) error {
event, ok := obj.(spec.PodEvent)
event, ok := obj.(types.PodEvent)
if !ok {
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
// secrets, therefore, setting flags like SUPERUSER or REPLICATION
// is not necessary here
c.systemUsers[constants.SuperuserKeyName] = spec.PgUser{
c.systemUsers[constants.SuperuserKeyName] = types.PgUser{
Name: c.OpConfig.SuperUsername,
Password: util.RandomPassword(constants.PasswordLength),
}
c.systemUsers[constants.ReplicationUserKeyName] = spec.PgUser{
c.systemUsers[constants.ReplicationUserKeyName] = types.PgUser{
Name: c.OpConfig.ReplicationUsername,
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)
}
c.pgUsers[username] = spec.PgUser{
c.pgUsers[username] = types.PgUser{
Name: username,
Password: util.RandomPassword(constants.PasswordLength),
Flags: flags,
@ -627,7 +617,7 @@ func (c *Cluster) initHumanUsers() error {
for _, username := range teamMembers {
flags := []string{constants.RoleFlagLogin, constants.RoleFlagSuperuser}
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

View File

@ -4,12 +4,12 @@ import (
"fmt"
"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/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))
if err != nil {
return "", "", err
@ -22,7 +22,7 @@ func (c *Cluster) getPostgresFilesystemInfo(podName *spec.NamespacedName) (devic
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
// first, determine the device and the filesystem
deviceName, fsType, err := c.getPostgresFilesystemInfo(podName)

View File

@ -11,6 +11,7 @@ import (
"k8s.io/client-go/pkg/util/intstr"
"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"
)
@ -404,7 +405,7 @@ func (c *Cluster) genUserSecrets() (secrets map[string]*v1.Secret) {
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)
if pgUser.Password == "" {
return nil

View File

@ -7,7 +7,7 @@ import (
"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"
)
@ -60,9 +60,9 @@ func (c *Cluster) initDbConn() (err error) {
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
users = make(spec.PgUserMap)
users = make(types.PgUserMap)
if rows, err = c.pgDb.Query(getUserSQL, pq.Array(userNames)); err != nil {
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)
// 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

View File

@ -5,7 +5,7 @@ import (
"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/constants"
)
@ -50,7 +50,7 @@ func (c *Cluster) deletePods() error {
return nil
}
func (c *Cluster) deletePod(podName spec.NamespacedName) error {
func (c *Cluster) deletePod(podName types.NamespacedName) error {
ch := c.registerPodSubscriber(podName)
defer c.unregisterPodSubscriber(podName)
@ -65,7 +65,7 @@ func (c *Cluster) deletePod(podName spec.NamespacedName) error {
return nil
}
func (c *Cluster) unregisterPodSubscriber(podName spec.NamespacedName) {
func (c *Cluster) unregisterPodSubscriber(podName types.NamespacedName) {
c.podSubscribersMu.Lock()
defer c.podSubscribersMu.Unlock()
@ -77,11 +77,11 @@ func (c *Cluster) unregisterPodSubscriber(podName spec.NamespacedName) {
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()
defer c.podSubscribersMu.Unlock()
ch := make(chan spec.PodEvent)
ch := make(chan types.PodEvent)
if _, ok := c.podSubscribers[podName]; ok {
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/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/constants"
"github.com/zalando-incubator/postgres-operator/pkg/util/k8sutil"
@ -318,7 +318,7 @@ func (c *Cluster) applySecrets() error {
for secretUsername, secretSpec := range secrets {
secret, err := c.KubeClient.Secrets(secretSpec.Namespace).Create(secretSpec)
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)
if err != nil {
return fmt.Errorf("could not get current secret: %v", err)

View File

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

View File

@ -9,6 +9,7 @@ import (
"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/constants"
"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.
func getPodNameFromPersistentVolume(pv *v1.PersistentVolume) *spec.NamespacedName {
func getPodNameFromPersistentVolume(pv *v1.PersistentVolume) *types.NamespacedName {
namespace := pv.Spec.ClaimRef.Namespace
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 {

View File

@ -10,8 +10,8 @@ import (
"k8s.io/client-go/rest"
"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/types"
"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/teams"
@ -22,7 +22,7 @@ type Config struct {
KubeClient *kubernetes.Clientset
RestClient *rest.RESTClient
TeamsAPIClient *teams.API
InfrastructureRoles map[string]spec.PgUser
InfrastructureRoles map[string]types.PgUser
}
type Controller struct {
@ -31,12 +31,12 @@ type Controller struct {
logger *logrus.Entry
clustersMu sync.RWMutex
clusters map[spec.NamespacedName]cluster.Interface
stopChs map[spec.NamespacedName]chan struct{}
clusters map[types.NamespacedName]types.Cluster
stopChs map[types.NamespacedName]chan struct{}
postgresqlInformer cache.SharedIndexInformer
podInformer cache.SharedIndexInformer
podCh chan spec.PodEvent
podCh chan types.PodEvent
clusterEventQueues []*cache.FIFO
@ -56,9 +56,9 @@ func New(controllerConfig *Config, operatorConfig *config.Config) *Controller {
Config: *controllerConfig,
opConfig: operatorConfig,
logger: logger.WithField("pkg", "controller"),
clusters: make(map[spec.NamespacedName]cluster.Interface),
stopChs: make(map[spec.NamespacedName]chan struct{}),
podCh: make(chan spec.PodEvent),
clusters: make(map[types.NamespacedName]types.Cluster),
stopChs: make(map[types.NamespacedName]chan struct{}),
podCh: make(chan types.PodEvent),
}
}
@ -130,7 +130,7 @@ func (c *Controller) initController() {
c.clusterEventQueues = make([]*cache.FIFO, c.opConfig.Workers)
for i := range c.clusterEventQueues {
c.clusterEventQueues[i] = cache.NewFIFO(func(obj interface{}) (string, error) {
e, ok := obj.(spec.ClusterEvent)
e, ok := obj.(types.ClusterEvent)
if !ok {
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/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"
)
@ -61,11 +61,11 @@ func (c *Controller) podAdd(obj interface{}) {
return
}
podEvent := spec.PodEvent{
podEvent := types.PodEvent{
ClusterName: c.podClusterName(pod),
PodName: util.NameFromMeta(pod.ObjectMeta),
CurPod: pod,
EventType: spec.EventAdd,
EventType: types.EventAdd,
ResourceVersion: pod.ResourceVersion,
}
@ -83,12 +83,12 @@ func (c *Controller) podUpdate(prev, cur interface{}) {
return
}
podEvent := spec.PodEvent{
podEvent := types.PodEvent{
ClusterName: c.podClusterName(curPod),
PodName: util.NameFromMeta(curPod.ObjectMeta),
PrevPod: prevPod,
CurPod: curPod,
EventType: spec.EventUpdate,
EventType: types.EventUpdate,
ResourceVersion: curPod.ResourceVersion,
}
@ -101,11 +101,11 @@ func (c *Controller) podDelete(obj interface{}) {
return
}
podEvent := spec.PodEvent{
podEvent := types.PodEvent{
ClusterName: c.podClusterName(pod),
PodName: util.NameFromMeta(pod.ObjectMeta),
CurPod: pod,
EventType: spec.EventDelete,
EventType: types.EventDelete,
ResourceVersion: pod.ResourceVersion,
}

View File

@ -10,12 +10,13 @@ import (
"k8s.io/client-go/pkg/api/meta"
"k8s.io/client-go/pkg/fields"
"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/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/types"
"github.com/zalando-incubator/postgres-operator/pkg/util"
"github.com/zalando-incubator/postgres-operator/pkg/util/constants"
)
@ -68,7 +69,7 @@ func (c *Controller) clusterListFunc(options api.ListOptions) (runtime.Object, e
failedClustersCnt++
continue
}
c.queueClusterEvent(nil, pg, spec.EventSync)
c.queueClusterEvent(nil, pg, types.EventSync)
activeClustersCnt++
}
if len(objList) > 0 {
@ -97,15 +98,15 @@ func (c *Controller) clusterWatchFunc(options api.ListOptions) (watch.Interface,
}
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 {
return fmt.Errorf("could not cast to ClusterEvent")
}
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)
} else {
clusterName = util.NameFromMeta(event.OldSpec.Metadata)
@ -116,7 +117,7 @@ func (c *Controller) processEvent(obj interface{}) error {
c.clustersMu.RUnlock()
switch event.EventType {
case spec.EventAdd:
case types.EventAdd:
if clusterFound {
logger.Debugf("Cluster '%s' already exists", clusterName)
return nil
@ -142,7 +143,7 @@ func (c *Controller) processEvent(obj interface{}) error {
}
logger.Infof("Cluster '%s' has been created", clusterName)
case spec.EventUpdate:
case types.EventUpdate:
logger.Infof("Update of the '%s' cluster started", clusterName)
if !clusterFound {
@ -158,7 +159,7 @@ func (c *Controller) processEvent(obj interface{}) error {
}
cl.SetFailed(nil)
logger.Infof("Cluster '%s' has been updated", clusterName)
case spec.EventDelete:
case types.EventDelete:
logger.Infof("Deletion of the '%s' cluster started", clusterName)
if !clusterFound {
logger.Errorf("Unknown cluster: %s", clusterName)
@ -177,7 +178,7 @@ func (c *Controller) processEvent(obj interface{}) error {
c.clustersMu.Unlock()
logger.Infof("Cluster '%s' has been deleted", clusterName)
case spec.EventSync:
case types.EventSync:
logger.Infof("Syncing of the '%s' cluster started", clusterName)
// 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 (
uid types.UID
clusterName spec.NamespacedName
uid ktypes.UID
clusterName types.NamespacedName
clusterError error
)
if old != nil { //update, delete
uid = old.Metadata.GetUID()
clusterName = util.NameFromMeta(old.Metadata)
if eventType == spec.EventUpdate && new.Error == nil && old.Error != nil {
eventType = spec.EventSync
if eventType == types.EventUpdate && new.Error == nil && old.Error != nil {
eventType = types.EventSync
clusterError = new.Error
} else {
clusterError = old.Error
@ -236,13 +237,13 @@ func (c *Controller) queueClusterEvent(old, new *spec.Postgresql, eventType spec
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)
return
}
workerID := c.clusterWorkerID(clusterName)
clusterEvent := spec.ClusterEvent{
clusterEvent := types.ClusterEvent{
EventType: eventType,
UID: uid,
OldSpec: old,
@ -265,7 +266,7 @@ func (c *Controller) postgresqlAdd(obj interface{}) {
}
// 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{}) {
@ -284,7 +285,7 @@ func (c *Controller) postgresqlUpdate(prev, cur interface{}) {
return
}
c.queueClusterEvent(pgOld, pgNew, spec.EventUpdate)
c.queueClusterEvent(pgOld, pgNew, types.EventUpdate)
}
func (c *Controller) postgresqlDelete(obj interface{}) {
@ -294,5 +295,5 @@ func (c *Controller) postgresqlDelete(obj interface{}) {
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"
"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/constants"
"github.com/zalando-incubator/postgres-operator/pkg/util/k8sutil"
)
func (c *Controller) makeClusterConfig() cluster.Config {
infrastructureRoles := make(map[string]spec.PgUser)
infrastructureRoles := make(map[string]types.PgUser)
for k, v := range c.InfrastructureRoles {
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
}
@ -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)
}
func (c *Controller) getInfrastructureRoles() (result map[string]spec.PgUser, err error) {
if c.opConfig.InfrastructureRolesSecretName == (spec.NamespacedName{}) {
func (c *Controller) getInfrastructureRoles() (result map[string]types.PgUser, err error) {
if c.opConfig.InfrastructureRolesSecretName == (types.NamespacedName{}) {
// we don't have infrastructure roles defined, bail out
return nil, nil
}
@ -79,12 +79,12 @@ func (c *Controller) getInfrastructureRoles() (result map[string]spec.PgUser, er
}
data := infraRolesSecret.Data
result = make(map[string]spec.PgUser)
result = make(map[string]types.PgUser)
Users:
// in worst case we would have one line per user
for i := 1; i <= len(data); i++ {
properties := []string{"user", "password", "inrole"}
t := spec.PgUser{}
t := types.PgUser{}
for _, p := range properties {
key := fmt.Sprintf("%s%d", p, i)
if val, present := data[key]; !present {
@ -115,13 +115,13 @@ Users:
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 {
return spec.NamespacedName{
return types.NamespacedName{
Namespace: pod.Namespace,
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 (
"database/sql"
"fmt"
"strings"
"k8s.io/client-go/pkg/api/v1"
"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
type EventType string
// NamespacedName describes the namespace/name pairs used in Kubernetes names.
type NamespacedName types.NamespacedName
// Possible values for the EventType
const (
EventAdd EventType = "ADD"
@ -27,8 +24,8 @@ const (
type ClusterEvent struct {
UID types.UID
EventType EventType
OldSpec *Postgresql
NewSpec *Postgresql
OldSpec *spec.Postgresql
NewSpec *spec.Postgresql
WorkerID uint32
}
@ -73,31 +70,13 @@ type UserSyncer interface {
ExecuteSyncRequests(req []PgSyncUserRequest, db *sql.DB) error
}
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
type Cluster interface {
Create() error
Delete() error
ExecCommand(podName *NamespacedName, command ...string) (string, error)
ReceivePodEvent(event PodEvent)
Run(stopCh <-chan struct{})
Sync() error
Update(newSpec *spec.Postgresql) error
SetFailed(err error)
}

View File

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

View File

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

View File

@ -5,7 +5,7 @@ import (
"fmt"
"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"
)
@ -26,31 +26,31 @@ type DefaultUserSyncStrategy struct {
}
// ProduceSyncRequests figures out the types of changes that need to happen with the given users.
func (s DefaultUserSyncStrategy) ProduceSyncRequests(dbUsers spec.PgUserMap,
newUsers spec.PgUserMap) (reqs []spec.PgSyncUserRequest) {
func (s DefaultUserSyncStrategy) ProduceSyncRequests(dbUsers types.PgUserMap,
newUsers types.PgUserMap) (reqs []types.PgSyncUserRequest) {
// No existing roles are deleted or stripped of role memebership/flags
for name, newUser := range newUsers {
dbUser, exists := dbUsers[name]
if !exists {
reqs = append(reqs, spec.PgSyncUserRequest{Kind: spec.PGSyncUserAdd, User: newUser})
reqs = append(reqs, types.PgSyncUserRequest{Kind: types.PGSyncUserAdd, User: newUser})
} else {
r := spec.PgSyncUserRequest{}
r := types.PgSyncUserRequest{}
newMD5Password := util.PGUserPassword(newUser)
if dbUser.Password != newMD5Password {
r.User.Password = newMD5Password
r.Kind = spec.PGsyncUserAlter
r.Kind = types.PGsyncUserAlter
}
if addNewRoles, equal := util.SubstractStringSlices(newUser.MemberOf, dbUser.MemberOf); !equal {
r.User.MemberOf = addNewRoles
r.Kind = spec.PGsyncUserAlter
r.Kind = types.PGsyncUserAlter
}
if addNewFlags, equal := util.SubstractStringSlices(newUser.Flags, dbUser.Flags); !equal {
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
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.
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 {
switch r.Kind {
case spec.PGSyncUserAdd:
case types.PGSyncUserAdd:
if err := s.createPgUser(r.User, db); err != nil {
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 {
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
}
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 userPassword string
@ -107,7 +107,7 @@ func (s DefaultUserSyncStrategy) createPgUser(user spec.PgUser, db *sql.DB) (err
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
if user.Password != "" || len(user.Flags) > 0 {
@ -129,7 +129,7 @@ func (s DefaultUserSyncStrategy) alterPgUser(user spec.PgUser, db *sql.DB) (err
return
}
func produceAlterStmt(user spec.PgUser) string {
func produceAlterStmt(user types.PgUser) string {
// ALTER ROLE ... LOGIN ENCRYPTED PASSWORD ..
result := make([]string, 1)
password := user.Password
@ -144,12 +144,12 @@ func produceAlterStmt(user spec.PgUser) string {
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
return fmt.Sprintf(grantToUserSQL, quoteMemberList(user), user.Name)
}
func quoteMemberList(user spec.PgUser) string {
func quoteMemberList(user types.PgUser) string {
var memberof []string
for _, member := range user.MemberOf {
memberof = append(memberof, fmt.Sprintf(`"%s"`, member))

View File

@ -10,7 +10,7 @@ import (
"github.com/motomux/pretty"
"k8s.io/client-go/pkg/api/v1"
"github.com/zalando-incubator/postgres-operator/pkg/spec"
"github.com/zalando-incubator/postgres-operator/pkg/types"
)
const (
@ -34,15 +34,15 @@ func RandomPassword(n int) string {
}
// NameFromMeta converts a metadata object to the NamespacedName name representation.
func NameFromMeta(meta v1.ObjectMeta) spec.NamespacedName {
return spec.NamespacedName{
func NameFromMeta(meta v1.ObjectMeta) types.NamespacedName {
return types.NamespacedName{
Namespace: meta.Namespace,
Name: meta.Name,
}
}
// 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 == "" {
// Avoid processing already encrypted or empty passwords
return user.Password

View File

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