Skip to content

Commit c0aaf3d

Browse files
gkechhors
andauthored
K8SPG-799 configure imagepullsecrets for patroni version check pod - add envtests (#1184)
* K8SPG-799 configure imagepullsecrets for patroni version check pod - add envtests * fix imports * remove resources assertion - ideally whole pod should be extracted from here * fix comments * use right image --------- Co-authored-by: Viacheslav Sarzhan <slava.sarzhan@percona.com>
1 parent c77a6b2 commit c0aaf3d

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed

percona/controller/pgcluster/controller.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ func (r *PGClusterReconciler) reconcilePatroniVersionCheck(ctx context.Context,
436436
},
437437
SecurityContext: cr.Spec.InstanceSets[0].SecurityContext,
438438
TerminationGracePeriodSeconds: ptr.To(int64(5)),
439+
ImagePullSecrets: cr.Spec.ImagePullSecrets,
439440
Resources: &corev1.ResourceRequirements{
440441
Limits: corev1.ResourceList{
441442
corev1.ResourceCPU: resource.MustParse("100m"),

percona/controller/pgcluster/controller_test.go

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
k8serrors "k8s.io/apimachinery/pkg/api/errors"
2222
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2323
"k8s.io/apimachinery/pkg/types"
24+
"k8s.io/utils/ptr"
2425
ctrl "sigs.k8s.io/controller-runtime"
2526
"sigs.k8s.io/controller-runtime/pkg/client"
2627

@@ -1517,6 +1518,186 @@ var _ = Describe("ServiceAccount early creation", Ordered, func() {
15171518
})
15181519
})
15191520

1521+
var _ = Describe("patroni version check", Ordered, func() {
1522+
ctx := context.Background()
1523+
1524+
const crName = "patroni-version-test"
1525+
const ns = crName
1526+
crNamespacedName := types.NamespacedName{Name: crName, Namespace: ns}
1527+
1528+
namespace := &corev1.Namespace{
1529+
ObjectMeta: metav1.ObjectMeta{
1530+
Name: crName,
1531+
Namespace: ns,
1532+
},
1533+
}
1534+
1535+
BeforeAll(func() {
1536+
By("Creating the Namespace to perform the tests")
1537+
err := k8sClient.Create(ctx, namespace)
1538+
Expect(err).To(Not(HaveOccurred()))
1539+
})
1540+
1541+
AfterAll(func() {
1542+
By("Deleting the Namespace to perform the tests")
1543+
_ = k8sClient.Delete(ctx, namespace)
1544+
})
1545+
1546+
Context("With custom patroni version annotation", func() {
1547+
cr, err := readDefaultCR(crName, ns)
1548+
It("should read default cr.yaml", func() {
1549+
Expect(err).NotTo(HaveOccurred())
1550+
})
1551+
1552+
It("should create PerconaPGCluster with custom patroni version", func() {
1553+
if cr.Annotations == nil {
1554+
cr.Annotations = make(map[string]string)
1555+
}
1556+
cr.Annotations[pNaming.AnnotationCustomPatroniVersion] = "3.2.1"
1557+
1558+
status := cr.Status
1559+
Expect(k8sClient.Create(ctx, cr)).Should(Succeed())
1560+
cr.Status = status
1561+
Expect(k8sClient.Status().Update(ctx, cr)).Should(Succeed())
1562+
})
1563+
1564+
It("should successfully reconcile patroni version check", func() {
1565+
reconcilerInstance := reconciler(cr)
1566+
err := reconcilerInstance.reconcilePatroniVersionCheck(ctx, cr)
1567+
Expect(err).NotTo(HaveOccurred())
1568+
})
1569+
1570+
It("should copy custom patroni version to status", func() {
1571+
updatedCR := &v2.PerconaPGCluster{}
1572+
Expect(k8sClient.Get(ctx, crNamespacedName, updatedCR)).Should(Succeed())
1573+
1574+
Expect(updatedCR.Status.PatroniVersion).To(Equal("3.2.1"))
1575+
})
1576+
})
1577+
1578+
Context("Without custom patroni version annotation", func() {
1579+
const crName2 = "patroni-version-test-2"
1580+
const ns2 = crName2
1581+
crNamespacedName2 := types.NamespacedName{Name: crName2, Namespace: ns2}
1582+
1583+
namespace2 := &corev1.Namespace{
1584+
ObjectMeta: metav1.ObjectMeta{
1585+
Name: crName2,
1586+
Namespace: ns2,
1587+
},
1588+
}
1589+
1590+
BeforeAll(func() {
1591+
By("Creating the second namespace")
1592+
err := k8sClient.Create(ctx, namespace2)
1593+
Expect(err).To(Not(HaveOccurred()))
1594+
})
1595+
1596+
AfterAll(func() {
1597+
By("Deleting the second namespace")
1598+
_ = k8sClient.Delete(ctx, namespace2)
1599+
})
1600+
1601+
cr2, err := readDefaultCR(crName2, ns2)
1602+
It("should read default cr.yaml", func() {
1603+
Expect(err).NotTo(HaveOccurred())
1604+
})
1605+
1606+
It("should create PerconaPGCluster without custom patroni version annotation", func() {
1607+
if cr2.Annotations == nil {
1608+
cr2.Annotations = make(map[string]string)
1609+
}
1610+
delete(cr2.Annotations, pNaming.AnnotationCustomPatroniVersion)
1611+
1612+
uid := int64(1001)
1613+
cr2.Spec.InstanceSets[0].SecurityContext = &corev1.PodSecurityContext{
1614+
RunAsUser: &uid,
1615+
}
1616+
cr2.Spec.ImagePullSecrets = []corev1.LocalObjectReference{
1617+
{Name: "test-pull-secret"},
1618+
}
1619+
1620+
cr2.Status.PatroniVersion = "3.1.0"
1621+
cr2.Status.Postgres.ImageID = "some-image-id"
1622+
1623+
status := cr2.Status
1624+
Expect(k8sClient.Create(ctx, cr2)).Should(Succeed())
1625+
cr2.Status = status
1626+
Expect(k8sClient.Status().Update(ctx, cr2)).Should(Succeed())
1627+
1628+
pod := &corev1.Pod{
1629+
ObjectMeta: metav1.ObjectMeta{
1630+
Name: cr2.Name + "-instance-pod",
1631+
Namespace: cr2.Namespace,
1632+
Labels: map[string]string{
1633+
"postgres-operator.crunchydata.com/cluster": cr2.Name,
1634+
"postgres-operator.crunchydata.com/instance": "instance",
1635+
},
1636+
},
1637+
Spec: corev1.PodSpec{
1638+
Containers: []corev1.Container{
1639+
{
1640+
Name: "database",
1641+
Image: "postgres:16",
1642+
},
1643+
},
1644+
},
1645+
}
1646+
Expect(k8sClient.Create(ctx, pod)).Should(Succeed())
1647+
1648+
pod.Status = corev1.PodStatus{
1649+
Phase: corev1.PodRunning,
1650+
ContainerStatuses: []corev1.ContainerStatus{
1651+
{
1652+
Name: "database",
1653+
ImageID: "postgres:16",
1654+
},
1655+
},
1656+
}
1657+
Expect(k8sClient.Status().Update(ctx, pod)).Should(Succeed())
1658+
})
1659+
1660+
It("should create patroni version check pod and return errPatroniVersionCheckWait", func() {
1661+
reconcilerInstance := reconciler(cr2)
1662+
err := reconcilerInstance.reconcilePatroniVersionCheck(ctx, cr2)
1663+
Expect(err).To(HaveOccurred())
1664+
Expect(err.Error()).To(ContainSubstring("waiting for pod to initialize"))
1665+
})
1666+
1667+
It("should have created patroni version check pod with correct configuration", func() {
1668+
podName := cr2.Name + "-patroni-version-check"
1669+
pod := &corev1.Pod{}
1670+
err = k8sClient.Get(ctx, types.NamespacedName{Name: podName, Namespace: cr2.Namespace}, pod)
1671+
Expect(err).NotTo(HaveOccurred())
1672+
1673+
Expect(pod.Spec.Containers).To(HaveLen(1))
1674+
Expect(pod.Spec.Containers[0].Name).To(Equal(pNaming.ContainerPatroniVersionCheck))
1675+
Expect(pod.Spec.Containers[0].Image).To(Equal(cr2.Spec.Image))
1676+
Expect(pod.Spec.Containers[0].Command).To(Equal([]string{"bash"}))
1677+
Expect(pod.Spec.Containers[0].Args).To(Equal([]string{"-c", "sleep 60"}))
1678+
1679+
uid := int64(1001)
1680+
expectedSecurityContext := &corev1.PodSecurityContext{
1681+
RunAsUser: &uid,
1682+
}
1683+
expectedImagePullSecrets := []corev1.LocalObjectReference{
1684+
{Name: "test-pull-secret"},
1685+
}
1686+
1687+
Expect(pod.Spec.SecurityContext).To(Equal(expectedSecurityContext))
1688+
Expect(pod.Spec.TerminationGracePeriodSeconds).To(Equal(ptr.To(int64(5))))
1689+
Expect(pod.Spec.ImagePullSecrets).To(Equal(expectedImagePullSecrets))
1690+
})
1691+
1692+
It("should preserve existing patroni version in annotation", func() {
1693+
updatedCR := &v2.PerconaPGCluster{}
1694+
Expect(k8sClient.Get(ctx, crNamespacedName2, updatedCR)).Should(Succeed())
1695+
1696+
Expect(updatedCR.Status.PatroniVersion).To(Equal("3.1.0"))
1697+
})
1698+
})
1699+
})
1700+
15201701
var _ = Describe("CR Validations", Ordered, func() {
15211702
ctx := context.Background()
15221703
const crName = "cr-validation"

0 commit comments

Comments
 (0)