Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions internal/controller/postgrescluster/pgbackrest.go
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,15 @@ func (r *Reconciler) reconcilePGBackRest(ctx context.Context,
return result, nil
}

// reconcile the RBAC required to run pgBackRest Jobs (e.g. for backups)
// K8SPG-698
sa, err := r.reconcilePGBackRestRBAC(ctx, postgresCluster)
if err != nil {
log.Error(err, "unable to create replica creation backup")
result.Requeue = true
return result, nil
}

var repoHost *appsv1.StatefulSet
var repoHostName string
// reconcile the pgbackrest repository host
Expand Down Expand Up @@ -1523,14 +1532,6 @@ func (r *Reconciler) reconcilePGBackRest(ctx context.Context,
result.Requeue = true
}

// reconcile the RBAC required to run pgBackRest Jobs (e.g. for backups)
sa, err := r.reconcilePGBackRestRBAC(ctx, postgresCluster)
if err != nil {
log.Error(err, "unable to create replica creation backup")
result.Requeue = true
return result, nil
}

// reconcile the pgBackRest stanza for all configuration pgBackRest repos
configHashMismatch, err := r.reconcileStanzaCreate(ctx, postgresCluster, instances, configHash)
// If a stanza create error then requeue but don't return the error. This prevents
Expand Down
108 changes: 108 additions & 0 deletions percona/controller/pgcluster/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1623,6 +1623,114 @@ var _ = Describe("Validate TLS", Ordered, func() {
})
})

type saTestClient struct {
client.Client

crName string
ns string
}

func (sc *saTestClient) checkObject(ctx context.Context, obj client.Object) error {
sts, ok := obj.(*appsv1.StatefulSet)
if !ok {
return nil
}
serviceAccountName := sts.Spec.Template.Spec.ServiceAccountName
if serviceAccountName == "" {
return errors.New("it's not expected to have empty service account name")
}

if err := sc.Get(ctx, types.NamespacedName{
Name: serviceAccountName,
Namespace: sts.Namespace,
}, new(corev1.ServiceAccount)); err != nil {
if k8serrors.IsNotFound(err) {
return errors.Wrap(err, "test error: service account should be created before the statefulset")
}
return err
}

return nil
}

func (sc *saTestClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.PatchOption) error {
if err := sc.checkObject(ctx, obj); err != nil {
panic(err) // should panic because reconciler can ignore the error
}
return sc.Client.Patch(ctx, obj, patch, opts...)
}

func (sc *saTestClient) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error {
if err := sc.checkObject(ctx, obj); err != nil {
panic(err) // should panic because reconciler can ignore the error
}
return sc.Client.Create(ctx, obj, opts...)
}

// This test ensures that the ServiceAccount associated with a StatefulSet is created
// before the StatefulSet itself. (K8SPG-698)
// The saTestClient verifies the existence of the ServiceAccount during create, patch,
// or update operations on the StatefulSet.
var _ = Describe("ServiceAccount early creation", Ordered, func() {
ctx := context.Background()

const crName = "sa-timestamp"
const ns = crName

namespace := &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: crName,
Namespace: ns,
},
}
crNamespacedName := types.NamespacedName{Name: crName, Namespace: ns}

cr, err := readDefaultCR(crName, ns)
It("should read default cr.yaml", func() {
Expect(err).NotTo(HaveOccurred())
})

cr.Default()
reconciler := reconciler(cr)
crunchyReconciler := crunchyReconciler()

var cl client.Client

BeforeAll(func() {
cl = &saTestClient{
Client: k8sClient,

crName: crName,
ns: ns,
}
reconciler.Client = cl
crunchyReconciler.Client = cl

By("Creating the Namespace to perform the tests")
err := cl.Create(ctx, namespace)
Expect(err).To(Not(HaveOccurred()))
})

AfterAll(func() {
By("Deleting the Namespace to perform the tests")
_ = cl.Delete(ctx, namespace)
})

It("should create PerconaPGCluster", func() {
status := cr.Status
Expect(cl.Create(ctx, cr)).Should(Succeed())
cr.Status = status
Expect(cl.Status().Update(ctx, cr)).Should(Succeed())
})

It("Should reconcile", func() {
_, err := reconciler.Reconcile(ctx, ctrl.Request{NamespacedName: crNamespacedName})
Expect(err).NotTo(HaveOccurred())
_, err = crunchyReconciler.Reconcile(ctx, ctrl.Request{NamespacedName: crNamespacedName})
Expect(err).NotTo(HaveOccurred())
})
})

var _ = Describe("CR Validations", Ordered, func() {
ctx := context.Background()
const crName = "cr-validation"
Expand Down
Loading