Add a simple tests for CreateSecret
This commit is contained in:
parent
ba1f886043
commit
b0756a1f75
|
|
@ -127,6 +127,14 @@ func New(cfg Config, kubeClient k8sutil.KubernetesClient, pgSpec acidv1.Postgres
|
|||
return cluster
|
||||
}
|
||||
|
||||
func (c *Cluster) SetTeamsAPIClient(client teams.Interface) {
|
||||
c.teamsAPIClient = client
|
||||
}
|
||||
|
||||
func (c *Cluster) SetOAuthTokenGetter(getter OAuthTokenGetter) {
|
||||
c.oauthTokenGetter = getter
|
||||
}
|
||||
|
||||
func (c *Cluster) clusterName() spec.NamespacedName {
|
||||
return util.NameFromMeta(c.ObjectMeta)
|
||||
}
|
||||
|
|
@ -222,7 +230,7 @@ func (c *Cluster) PlanForSecrets() (plan Plan) {
|
|||
|
||||
if k8sutil.ResourceNotFound(err) {
|
||||
msg = "Generate plan to create new secret %q"
|
||||
c.logger.Debugf(msg, util.NameFromMeta(secret.ObjectMeta))
|
||||
c.logger.Debugf(msg, util.NameFromMeta(secretSpec.ObjectMeta))
|
||||
plan = append(plan, NewCreateSecret(secretUsername, secretSpec, c))
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
acidv1 "github.com/zalando-incubator/postgres-operator/pkg/apis/acid.zalan.do/v1"
|
||||
"github.com/zalando-incubator/postgres-operator/pkg/apiserver"
|
||||
"github.com/zalando-incubator/postgres-operator/pkg/cluster"
|
||||
"github.com/zalando-incubator/postgres-operator/pkg/spec"
|
||||
|
|
@ -25,6 +26,20 @@ import (
|
|||
acidv1informer "github.com/zalando-incubator/postgres-operator/pkg/generated/informers/externalversions/acid.zalan.do/v1"
|
||||
)
|
||||
|
||||
type ClusterFactory interface {
|
||||
addCluster(ctrl *Controller,
|
||||
lg *logrus.Entry,
|
||||
clusterName spec.NamespacedName,
|
||||
pgSpec *acidv1.Postgresql,
|
||||
) *cluster.Cluster
|
||||
}
|
||||
|
||||
type ClusterGenerator struct {
|
||||
ClusterFactory
|
||||
|
||||
KubeClient k8sutil.KubernetesClient
|
||||
}
|
||||
|
||||
// Controller represents operator controller
|
||||
type Controller struct {
|
||||
config spec.ControllerConfig
|
||||
|
|
@ -59,6 +74,8 @@ type Controller struct {
|
|||
PodServiceAccount *v1.ServiceAccount
|
||||
PodServiceAccountRoleBinding *rbacv1beta1.RoleBinding
|
||||
namespacesWithDefinedRBAC sync.Map
|
||||
|
||||
clusterFactory ClusterFactory
|
||||
}
|
||||
|
||||
// NewController creates a new controller
|
||||
|
|
@ -77,6 +94,7 @@ func NewController(controllerConfig *spec.ControllerConfig) *Controller {
|
|||
teamClusters: make(map[string][]spec.NamespacedName),
|
||||
stopCh: make(chan struct{}),
|
||||
podCh: make(chan cluster.PodEvent),
|
||||
clusterFactory: &ClusterGenerator{},
|
||||
}
|
||||
logger.Hooks.Add(c)
|
||||
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ func (c *Controller) acquireInitialListOfClusters() error {
|
|||
continue
|
||||
}
|
||||
clusterName = util.NameFromMeta(pg.ObjectMeta)
|
||||
c.addCluster(c.logger, clusterName, &pg)
|
||||
c.clusterFactory.addCluster(c, c.logger, clusterName, &pg)
|
||||
c.logger.Debugf("added new cluster: %q", clusterName)
|
||||
}
|
||||
// initiate initial sync of all clusters.
|
||||
|
|
@ -144,18 +144,20 @@ func (c *Controller) acquireInitialListOfClusters() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) addCluster(lg *logrus.Entry, clusterName spec.NamespacedName, pgSpec *acidv1.Postgresql) *cluster.Cluster {
|
||||
cl := cluster.New(c.makeClusterConfig(), c.KubeClient, *pgSpec, lg)
|
||||
cl.Run(c.stopCh)
|
||||
func (c *ClusterGenerator) addCluster(ctrl *Controller,
|
||||
lg *logrus.Entry, clusterName spec.NamespacedName, pgSpec *acidv1.Postgresql) *cluster.Cluster {
|
||||
|
||||
cl := cluster.New(ctrl.makeClusterConfig(), ctrl.KubeClient, *pgSpec, lg)
|
||||
cl.Run(ctrl.stopCh)
|
||||
teamName := strings.ToLower(cl.Spec.TeamID)
|
||||
|
||||
defer c.clustersMu.Unlock()
|
||||
c.clustersMu.Lock()
|
||||
defer ctrl.clustersMu.Unlock()
|
||||
ctrl.clustersMu.Lock()
|
||||
|
||||
c.teamClusters[teamName] = append(c.teamClusters[teamName], clusterName)
|
||||
c.clusters[clusterName] = cl
|
||||
c.clusterLogs[clusterName] = ringlog.New(c.opConfig.RingLogLines)
|
||||
c.clusterHistory[clusterName] = ringlog.New(c.opConfig.ClusterHistoryEntries)
|
||||
ctrl.teamClusters[teamName] = append(ctrl.teamClusters[teamName], clusterName)
|
||||
ctrl.clusters[clusterName] = cl
|
||||
ctrl.clusterLogs[clusterName] = ringlog.New(ctrl.opConfig.RingLogLines)
|
||||
ctrl.clusterHistory[clusterName] = ringlog.New(ctrl.opConfig.ClusterHistoryEntries)
|
||||
|
||||
return cl
|
||||
}
|
||||
|
|
@ -182,7 +184,7 @@ func (c *Controller) generatePlan(event ClusterEvent) cluster.Plan {
|
|||
case EventAdd:
|
||||
log.Infof("Creation of the cluster started")
|
||||
|
||||
newCluster := c.addCluster(log, clusterName, event.NewSpec)
|
||||
newCluster := c.clusterFactory.addCluster(c, log, clusterName, event.NewSpec)
|
||||
c.curWorkerCluster.Store(event.WorkerID, newCluster)
|
||||
return newCluster.PlanForCreate()
|
||||
|
||||
|
|
@ -272,7 +274,7 @@ func (c *Controller) processEvent(event ClusterEvent) {
|
|||
|
||||
lg.Infof("creation of the cluster started")
|
||||
|
||||
cl = c.addCluster(lg, clusterName, event.NewSpec)
|
||||
cl = c.clusterFactory.addCluster(c, lg, clusterName, event.NewSpec)
|
||||
|
||||
c.curWorkerCluster.Store(event.WorkerID, cl)
|
||||
|
||||
|
|
@ -341,7 +343,7 @@ func (c *Controller) processEvent(event ClusterEvent) {
|
|||
|
||||
// no race condition because a cluster is always processed by single worker
|
||||
if !clusterFound {
|
||||
cl = c.addCluster(lg, clusterName, event.NewSpec)
|
||||
cl = c.clusterFactory.addCluster(c, lg, clusterName, event.NewSpec)
|
||||
}
|
||||
|
||||
c.curWorkerCluster.Store(event.WorkerID, cl)
|
||||
|
|
|
|||
|
|
@ -1,20 +1,101 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
acidv1 "github.com/zalando-incubator/postgres-operator/pkg/apis/acid.zalan.do/v1"
|
||||
"github.com/zalando-incubator/postgres-operator/pkg/spec"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"k8s.io/api/core/v1"
|
||||
|
||||
acidv1 "github.com/zalando-incubator/postgres-operator/pkg/apis/acid.zalan.do/v1"
|
||||
"github.com/zalando-incubator/postgres-operator/pkg/cluster"
|
||||
"github.com/zalando-incubator/postgres-operator/pkg/spec"
|
||||
"github.com/zalando-incubator/postgres-operator/pkg/util/k8sutil"
|
||||
"github.com/zalando-incubator/postgres-operator/pkg/util/teams"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
)
|
||||
|
||||
var (
|
||||
True = true
|
||||
False = false
|
||||
True = true
|
||||
False = false
|
||||
logger = logrus.New().WithField("test", "cluster")
|
||||
)
|
||||
|
||||
const (
|
||||
superUserName = "postgres"
|
||||
replicationUserName = "standby"
|
||||
)
|
||||
|
||||
var mockTeamsAPI mockTeamsAPIClient
|
||||
|
||||
type mockOAuthTokenGetter struct {
|
||||
cluster.OAuthTokenGetter
|
||||
}
|
||||
|
||||
type mockClusterGenerator struct {
|
||||
ClusterGenerator
|
||||
}
|
||||
|
||||
type NotFoundError struct{}
|
||||
|
||||
func (e *NotFoundError) Error() string {
|
||||
return "error"
|
||||
}
|
||||
|
||||
func (e *NotFoundError) Status() metav1.Status {
|
||||
return metav1.Status{
|
||||
Reason: metav1.StatusReasonNotFound,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *mockClusterGenerator) addCluster(ctrl *Controller,
|
||||
lg *logrus.Entry, clusterName spec.NamespacedName, pgSpec *acidv1.Postgresql) *cluster.Cluster {
|
||||
|
||||
mockTeamsAPI.setMembers([]string{"test-user"})
|
||||
cl := cluster.New(ctrl.makeClusterConfig(), ctrl.KubeClient, *pgSpec, lg)
|
||||
cl.SetTeamsAPIClient(&mockTeamsAPI)
|
||||
cl.SetOAuthTokenGetter(&mockOAuthTokenGetter{})
|
||||
cl.Spec.TeamID = "test-team"
|
||||
return cl
|
||||
}
|
||||
|
||||
type mockTeamsAPIClient struct {
|
||||
members []string
|
||||
}
|
||||
|
||||
func (m *mockTeamsAPIClient) TeamInfo(teamID, token string) (tm *teams.Team, err error) {
|
||||
return &teams.Team{Members: m.members}, nil
|
||||
}
|
||||
|
||||
func (m *mockTeamsAPIClient) setMembers(members []string) {
|
||||
m.members = members
|
||||
}
|
||||
|
||||
type mockNoSecretGetter struct {
|
||||
}
|
||||
|
||||
type testNoSecret struct {
|
||||
v1core.SecretInterface
|
||||
}
|
||||
|
||||
func (c *testNoSecret) Get(name string, options metav1.GetOptions) (*v1.Secret, error) {
|
||||
return nil, &NotFoundError{}
|
||||
|
||||
}
|
||||
|
||||
func (c *mockNoSecretGetter) Secrets(namespace string) v1core.SecretInterface {
|
||||
return &testNoSecret{}
|
||||
}
|
||||
|
||||
func mockKubernetesClient() k8sutil.KubernetesClient {
|
||||
return k8sutil.KubernetesClient{
|
||||
SecretsGetter: &mockNoSecretGetter{},
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeDeprecatedPostgreSQLSpecParameters(t *testing.T) {
|
||||
c := NewController(&spec.ControllerConfig{})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
in *acidv1.PostgresSpec
|
||||
|
|
@ -42,3 +123,43 @@ func TestMergeDeprecatedPostgreSQLSpecParameters(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeneratePlan(t *testing.T) {
|
||||
c := NewController(&spec.ControllerConfig{})
|
||||
c.opConfig.SuperUsername = "test-superuser"
|
||||
c.opConfig.SecretNameTemplate = "secret"
|
||||
c.clusterFactory = &mockClusterGenerator{}
|
||||
c.KubeClient = mockKubernetesClient()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
in ClusterEvent
|
||||
contains cluster.Plan
|
||||
error string
|
||||
}{
|
||||
{
|
||||
"Cluster add produces plan with a CreateSecret",
|
||||
ClusterEvent{
|
||||
EventType: EventAdd,
|
||||
NewSpec: &acidv1.Postgresql{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "TestCluster",
|
||||
Namespace: "TestNamespace",
|
||||
},
|
||||
},
|
||||
},
|
||||
[]cluster.Action{cluster.CreateSecret{}, cluster.CreateSecret{}},
|
||||
"A plan for a new cluster should create secrets",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
result := c.generatePlan(tt.in)
|
||||
for idx, output := range result {
|
||||
output := reflect.TypeOf(output)
|
||||
expected := reflect.TypeOf(tt.contains[idx])
|
||||
if output != expected {
|
||||
t.Errorf("%s: %v", tt.name, tt.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,10 +196,10 @@ func (c *Controller) podClusterName(pod *v1.Pod) spec.NamespacedName {
|
|||
}
|
||||
|
||||
func eventInSlice(a EventType, list []EventType) bool {
|
||||
for _, b := range list {
|
||||
if b == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
for _, b := range list {
|
||||
if b == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue