mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-10-09 01:33:05 +02:00
Merge branch 'master' into feature/refactor-tpr
# Conflicts: # cmd/main.go # pkg/cluster/cluster.go # pkg/controller/controller.go # pkg/controller/util.go
This commit is contained in:
@@ -31,6 +31,7 @@ type Config struct {
|
||||
|
||||
type Controller struct {
|
||||
Config
|
||||
|
||||
opConfig *config.Config
|
||||
logger *logrus.Entry
|
||||
|
||||
@@ -51,7 +52,7 @@ type Controller struct {
|
||||
lastClusterSyncTime int64
|
||||
}
|
||||
|
||||
func New(controllerConfig *Config) *Controller {
|
||||
func NewController(controllerConfig *Config) *Controller {
|
||||
configMapData := make(map[string]string)
|
||||
logger := logrus.New()
|
||||
|
||||
@@ -126,7 +127,7 @@ func (c *Controller) initController() {
|
||||
c.logger.Fatalf("could not register ThirdPartyResource: %v", err)
|
||||
}
|
||||
|
||||
if infraRoles, err := c.getInfrastructureRoles(); err != nil {
|
||||
if infraRoles, err := c.getInfrastructureRoles(&c.opConfig.InfrastructureRolesSecretName); err != nil {
|
||||
c.logger.Warningf("could not get infrastructure roles: %v", err)
|
||||
} else {
|
||||
c.InfrastructureRoles = infraRoles
|
||||
|
||||
@@ -22,7 +22,7 @@ func (c *Controller) podListFunc(options meta_v1.ListOptions) (runtime.Object, e
|
||||
TimeoutSeconds: options.TimeoutSeconds,
|
||||
}
|
||||
|
||||
return c.KubeClient.CoreV1().Pods(c.opConfig.Namespace).List(opts)
|
||||
return c.KubeClient.Pods(c.opConfig.Namespace).List(opts)
|
||||
}
|
||||
|
||||
func (c *Controller) podWatchFunc(options meta_v1.ListOptions) (watch.Interface, error) {
|
||||
@@ -37,7 +37,7 @@ func (c *Controller) podWatchFunc(options meta_v1.ListOptions) (watch.Interface,
|
||||
TimeoutSeconds: options.TimeoutSeconds,
|
||||
}
|
||||
|
||||
return c.KubeClient.CoreV1Client.Pods(c.opConfig.Namespace).Watch(opts)
|
||||
return c.KubeClient.Pods(c.opConfig.Namespace).Watch(opts)
|
||||
}
|
||||
|
||||
func (c *Controller) podAdd(obj interface{}) {
|
||||
|
||||
@@ -61,17 +61,17 @@ 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(rolesSecret *spec.NamespacedName) (result map[string]spec.PgUser, err error) {
|
||||
if *rolesSecret == (spec.NamespacedName{}) {
|
||||
// we don't have infrastructure roles defined, bail out
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
infraRolesSecret, err := c.KubeClient.
|
||||
Secrets(c.opConfig.InfrastructureRolesSecretName.Namespace).
|
||||
Get(c.opConfig.InfrastructureRolesSecretName.Name, meta_v1.GetOptions{})
|
||||
Secrets(rolesSecret.Namespace).
|
||||
Get(rolesSecret.Name)
|
||||
if err != nil {
|
||||
c.logger.Debugf("Infrastructure roles secret name: %q", c.opConfig.InfrastructureRolesSecretName)
|
||||
c.logger.Debugf("Infrastructure roles secret name: %q", *rolesSecret)
|
||||
return nil, fmt.Errorf("could not get infrastructure roles secret: %v", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/pkg/api/v1"
|
||||
|
||||
"github.com/zalando-incubator/postgres-operator/pkg/spec"
|
||||
"github.com/zalando-incubator/postgres-operator/pkg/util/config"
|
||||
"github.com/zalando-incubator/postgres-operator/pkg/util/k8sutil"
|
||||
)
|
||||
|
||||
const (
|
||||
testInfrastructureRolesSecretName = "infrastructureroles-test"
|
||||
)
|
||||
|
||||
type mockSecret struct {
|
||||
v1core.SecretInterface
|
||||
}
|
||||
|
||||
func (c *mockSecret) Get(name string) (*v1.Secret, error) {
|
||||
if name != testInfrastructureRolesSecretName {
|
||||
return nil, fmt.Errorf("NotFound")
|
||||
}
|
||||
secret := &v1.Secret{}
|
||||
secret.Name = mockController.opConfig.ClusterNameLabel
|
||||
secret.Data = map[string][]byte{
|
||||
"user1": []byte("testrole"),
|
||||
"password1": []byte("testpassword"),
|
||||
"inrole1": []byte("testinrole"),
|
||||
}
|
||||
return secret, nil
|
||||
|
||||
}
|
||||
|
||||
type MockSecretGetter struct {
|
||||
}
|
||||
|
||||
func (c *MockSecretGetter) Secrets(namespace string) v1core.SecretInterface {
|
||||
return &mockSecret{}
|
||||
}
|
||||
|
||||
func newMockKubernetesClient() k8sutil.KubernetesClient {
|
||||
return k8sutil.KubernetesClient{SecretsGetter: &MockSecretGetter{}}
|
||||
}
|
||||
|
||||
func newMockController() *Controller {
|
||||
controller := NewController(&Config{}, &config.Config{})
|
||||
controller.opConfig.ClusterNameLabel = "cluster-name"
|
||||
controller.opConfig.InfrastructureRolesSecretName =
|
||||
spec.NamespacedName{v1.NamespaceDefault, testInfrastructureRolesSecretName}
|
||||
controller.opConfig.Workers = 4
|
||||
controller.KubeClient = newMockKubernetesClient()
|
||||
return controller
|
||||
}
|
||||
|
||||
var mockController = newMockController()
|
||||
|
||||
func TestPodClusterName(t *testing.T) {
|
||||
var testTable = []struct {
|
||||
in *v1.Pod
|
||||
expected spec.NamespacedName
|
||||
}{
|
||||
{
|
||||
&v1.Pod{},
|
||||
spec.NamespacedName{},
|
||||
},
|
||||
{
|
||||
&v1.Pod{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Namespace: v1.NamespaceDefault,
|
||||
Labels: map[string]string{
|
||||
mockController.opConfig.ClusterNameLabel: "testcluster",
|
||||
},
|
||||
},
|
||||
},
|
||||
spec.NamespacedName{v1.NamespaceDefault, "testcluster"},
|
||||
},
|
||||
}
|
||||
for _, test := range testTable {
|
||||
resp := mockController.podClusterName(test.in)
|
||||
if resp != test.expected {
|
||||
t.Errorf("expected response %v does not match the actual %v", test.expected, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestClusterWorkerID(t *testing.T) {
|
||||
var testTable = []struct {
|
||||
in spec.NamespacedName
|
||||
expected uint32
|
||||
}{
|
||||
{
|
||||
in: spec.NamespacedName{"foo", "bar"},
|
||||
expected: 2,
|
||||
},
|
||||
{
|
||||
in: spec.NamespacedName{"default", "testcluster"},
|
||||
expected: 3,
|
||||
},
|
||||
}
|
||||
for _, test := range testTable {
|
||||
resp := mockController.clusterWorkerID(test.in)
|
||||
if resp != test.expected {
|
||||
t.Errorf("expected response %v does not match the actual %v", test.expected, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetInfrastructureRoles(t *testing.T) {
|
||||
var testTable = []struct {
|
||||
secretName spec.NamespacedName
|
||||
expectedRoles map[string]spec.PgUser
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
spec.NamespacedName{},
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
spec.NamespacedName{v1.NamespaceDefault, "null"},
|
||||
nil,
|
||||
fmt.Errorf(`could not get infrastructure roles secret: NotFound`),
|
||||
},
|
||||
{
|
||||
spec.NamespacedName{v1.NamespaceDefault, testInfrastructureRolesSecretName},
|
||||
map[string]spec.PgUser{
|
||||
"testrole": {
|
||||
"testrole",
|
||||
"testpassword",
|
||||
nil,
|
||||
[]string{"testinrole"},
|
||||
},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
}
|
||||
for _, test := range testTable {
|
||||
roles, err := mockController.getInfrastructureRoles(&test.secretName)
|
||||
if err != test.expectedError {
|
||||
if err != nil && test.expectedError != nil && err.Error() == test.expectedError.Error() {
|
||||
continue
|
||||
}
|
||||
t.Errorf("expected error '%v' does not match the actual error '%v'", test.expectedError, err)
|
||||
}
|
||||
if !reflect.DeepEqual(roles, test.expectedRoles) {
|
||||
t.Errorf("expected roles output %v does not match the actual %v", test.expectedRoles, roles)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user