Skip to content

Commit d781414

Browse files
committed
add unit test
1 parent efb0845 commit d781414

2 files changed

Lines changed: 150 additions & 2 deletions

File tree

internal/controller/postgrescluster/pki_test.go

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ import (
1717
appsv1 "k8s.io/api/apps/v1"
1818
corev1 "k8s.io/api/core/v1"
1919
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
20+
"k8s.io/apimachinery/pkg/runtime"
2021
"k8s.io/apimachinery/pkg/types"
22+
"k8s.io/client-go/rest"
2123
"sigs.k8s.io/controller-runtime/pkg/client"
2224

2325
"github.com/percona/percona-postgresql-operator/v2/internal/naming"
@@ -380,6 +382,150 @@ func TestReconcileCerts(t *testing.T) {
380382
})
381383
}
382384

385+
// mockCertManagerController implements certmanager.Controller for testing.
386+
// Check returns nil (cert-manager is installed). All other methods panic
387+
// because they should not be called in the upgrade scenario.
388+
type mockCertManagerController struct{}
389+
390+
func (m *mockCertManagerController) Check(context.Context, *rest.Config, string) error { return nil }
391+
func (m *mockCertManagerController) ApplyIssuer(context.Context, *v1beta1.PostgresCluster) error {
392+
panic("unexpected call")
393+
}
394+
func (m *mockCertManagerController) ApplyCAIssuer(context.Context, *v1beta1.PostgresCluster) error {
395+
panic("unexpected call")
396+
}
397+
func (m *mockCertManagerController) ApplyCACertificate(context.Context, *v1beta1.PostgresCluster) error {
398+
panic("unexpected call")
399+
}
400+
func (m *mockCertManagerController) ApplyClusterCertificate(context.Context, *v1beta1.PostgresCluster, []string) error {
401+
panic("unexpected call")
402+
}
403+
func (m *mockCertManagerController) ApplyInstanceCertificate(context.Context, *v1beta1.PostgresCluster, string, []string) error {
404+
panic("unexpected call")
405+
}
406+
func (m *mockCertManagerController) ApplyPGBouncerCertificate(context.Context, *v1beta1.PostgresCluster, []string) error {
407+
panic("unexpected call")
408+
}
409+
func (m *mockCertManagerController) ApplyPGBackRestClientCertificate(context.Context, *v1beta1.PostgresCluster) error {
410+
panic("unexpected call")
411+
}
412+
func (m *mockCertManagerController) ApplyPGBackRestRepoCertificate(context.Context, *v1beta1.PostgresCluster, []string) error {
413+
panic("unexpected call")
414+
}
415+
416+
func mockCertManagerCtrlFunc(_ client.Client, _ *runtime.Scheme, _ bool) certmanager.Controller {
417+
return &mockCertManagerController{}
418+
}
419+
420+
func TestUpgradeCertManagerDoesNotTakeOverInternalPKI(t *testing.T) {
421+
if strings.EqualFold(os.Getenv("USE_EXISTING_CLUSTER"), "true") {
422+
t.Skip("USE_EXISTING_CLUSTER: Test fails due to garbage collection")
423+
}
424+
425+
_, tClient := setupKubernetes(t)
426+
require.ParallelCapacity(t, 1)
427+
ctx := t.Context()
428+
namespace := require.Namespace(t, tClient).Name
429+
430+
reconcilerWithoutCertManager := &Reconciler{
431+
Client: tClient,
432+
Owner: ControllerName,
433+
CertManagerCtrlFunc: certmanager.NewController,
434+
}
435+
436+
cluster := testCluster()
437+
cluster.Name = "upgrade-test"
438+
cluster.Namespace = namespace
439+
assert.NilError(t, tClient.Create(ctx, cluster))
440+
441+
root, err := reconcilerWithoutCertManager.reconcileRootCertificate(ctx, cluster)
442+
assert.NilError(t, err)
443+
444+
primaryService := &corev1.Service{ObjectMeta: metav1.ObjectMeta{
445+
Namespace: namespace, Name: "upgrade-test-primary",
446+
}}
447+
replicaService := &corev1.Service{ObjectMeta: metav1.ObjectMeta{
448+
Namespace: namespace, Name: "upgrade-test-replicas",
449+
}}
450+
451+
_, err = reconcilerWithoutCertManager.reconcileClusterCertificate(ctx, root, cluster, primaryService, replicaService)
452+
assert.NilError(t, err)
453+
454+
rootSecret := &corev1.Secret{}
455+
assert.NilError(t, tClient.Get(ctx, types.NamespacedName{
456+
Name: naming.PostgresRootCASecret(cluster).Name,
457+
Namespace: namespace,
458+
}, rootSecret))
459+
assert.Equal(t, rootSecret.Annotations["cert-manager.io/certificate-name"], "")
460+
461+
clusterCertSecret := &corev1.Secret{}
462+
assert.NilError(t, tClient.Get(ctx, types.NamespacedName{
463+
Name: fmt.Sprintf(naming.ClusterCertSecret, cluster.Name),
464+
Namespace: namespace,
465+
}, clusterCertSecret))
466+
originalCertData := clusterCertSecret.Data["tls.crt"]
467+
468+
reconcilerWithCertManager := &Reconciler{
469+
Client: tClient,
470+
Owner: ControllerName,
471+
CertManagerCtrlFunc: mockCertManagerCtrlFunc,
472+
RestConfig: &rest.Config{},
473+
}
474+
475+
t.Run("isRootCACertManagerManaged returns false for internal PKI root", func(t *testing.T) {
476+
managed, err := reconcilerWithCertManager.isRootCACertManagerManaged(ctx, cluster)
477+
assert.NilError(t, err)
478+
assert.Assert(t, !managed)
479+
})
480+
481+
t.Run("reconcileClusterCertificate uses internal PKI after upgrade", func(t *testing.T) {
482+
_, err := reconcilerWithCertManager.reconcileClusterCertificate(ctx, root, cluster, primaryService, replicaService)
483+
assert.NilError(t, err)
484+
485+
updatedCertSecret := &corev1.Secret{}
486+
assert.NilError(t, tClient.Get(ctx, types.NamespacedName{
487+
Name: fmt.Sprintf(naming.ClusterCertSecret, cluster.Name),
488+
Namespace: namespace,
489+
}, updatedCertSecret))
490+
491+
assert.DeepEqual(t, originalCertData, updatedCertSecret.Data["tls.crt"])
492+
})
493+
494+
t.Run("isRootCACertManagerManaged returns true for cert-manager root", func(t *testing.T) {
495+
rootSecret.Annotations = map[string]string{
496+
"cert-manager.io/certificate-name": "test-ca-cert",
497+
}
498+
assert.NilError(t, tClient.Update(ctx, rootSecret))
499+
500+
managed, err := reconcilerWithCertManager.isRootCACertManagerManaged(ctx, cluster)
501+
assert.NilError(t, err)
502+
assert.Assert(t, managed)
503+
})
504+
505+
t.Run("isRootCACertManagerManaged returns true when no root CA exists", func(t *testing.T) {
506+
freshCluster := testCluster()
507+
freshCluster.Name = "fresh-cluster"
508+
freshCluster.Namespace = namespace
509+
assert.NilError(t, tClient.Create(ctx, freshCluster))
510+
511+
managed, err := reconcilerWithCertManager.isRootCACertManagerManaged(ctx, freshCluster)
512+
assert.NilError(t, err)
513+
assert.Assert(t, managed)
514+
})
515+
516+
t.Run("isRootCACertManagerManaged returns false when cert-manager not installed", func(t *testing.T) {
517+
rNoCertManager := &Reconciler{
518+
Client: tClient,
519+
Owner: ControllerName,
520+
CertManagerCtrlFunc: certmanager.NewController,
521+
}
522+
523+
managed, err := rNoCertManager.isRootCACertManagerManaged(ctx, cluster)
524+
assert.NilError(t, err)
525+
assert.Assert(t, !managed)
526+
})
527+
}
528+
383529
// getCertFromSecret returns a parsed certificate from the named secret
384530
func getCertFromSecret(
385531
ctx context.Context, tClient client.Client, name, namespace, dataKey string,

internal/testing/require/kubernetes.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ func kubernetes3(t TestingT) (*envtest.Environment, client.Client) {
118118
); assert.Check(t,
119119
err == nil && len(pkgs) > 0 && pkgs[0].Module != nil, "got %v\n%#v", err, pkgs,
120120
) {
121-
snapshotter, err = filepath.Rel(root, pkgs[0].Module.Dir)
122-
assert.NilError(t, err)
121+
if pkgs[0].Module.Dir != "" {
122+
snapshotter, err = filepath.Rel(root, pkgs[0].Module.Dir)
123+
assert.NilError(t, err)
124+
}
123125
}
124126

125127
kubernetes.Lock()

0 commit comments

Comments
 (0)