Skip to content

Commit 12a4113

Browse files
committed
Only patch annotations + tests refactoring
1 parent 4d21e44 commit 12a4113

File tree

8 files changed

+277
-502
lines changed

8 files changed

+277
-502
lines changed

manifests/operator-service-account-rbac.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ rules:
102102
- delete
103103
- get
104104
- update
105+
- patch
105106
# to check nodes for node readiness label
106107
- apiGroups:
107108
- ""
@@ -173,7 +174,6 @@ rules:
173174
- get
174175
- list
175176
- patch
176-
- update
177177
# to CRUD cron jobs for logical backups
178178
- apiGroups:
179179
- batch

pkg/cluster/cluster.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -764,16 +764,6 @@ func (c *Cluster) compareAnnotations(old, new map[string]string) (bool, string)
764764

765765
}
766766

767-
func (c *Cluster) extractIgnoredAnnotations(annoList map[string]string) map[string]string {
768-
result := make(map[string]string)
769-
for _, ignore := range c.OpConfig.IgnoredAnnotations {
770-
if _, ok := annoList[ignore]; ok {
771-
result[ignore] = annoList[ignore]
772-
}
773-
}
774-
return result
775-
}
776-
777767
func (c *Cluster) compareServices(old, new *v1.Service) (bool, string) {
778768
if old.Spec.Type != new.Spec.Type {
779769
return false, fmt.Sprintf("new service's type %q does not match the current one %q",
@@ -790,10 +780,6 @@ func (c *Cluster) compareServices(old, new *v1.Service) (bool, string) {
790780
}
791781
}
792782

793-
if changed, reason := c.compareAnnotations(old.Annotations, new.Annotations); changed {
794-
return !changed, "new service's annotations does not match the current one:" + reason
795-
}
796-
797783
return true, ""
798784
}
799785

pkg/cluster/cluster_test.go

Lines changed: 0 additions & 199 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,205 +1443,6 @@ func TestCompareServices(t *testing.T) {
14431443
match: false,
14441444
reason: `new service's LoadBalancerSourceRange does not match the current one`,
14451445
},
1446-
{
1447-
about: "services differ on DNS annotation",
1448-
current: newService(
1449-
map[string]string{
1450-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1451-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1452-
},
1453-
v1.ServiceTypeLoadBalancer,
1454-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1455-
new: newService(
1456-
map[string]string{
1457-
constants.ZalandoDNSNameAnnotation: "new_clstr.acid.zalan.do",
1458-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1459-
},
1460-
v1.ServiceTypeLoadBalancer,
1461-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1462-
match: false,
1463-
reason: `new service's annotations does not match the current one: "external-dns.alpha.kubernetes.io/hostname" changed from "clstr.acid.zalan.do" to "new_clstr.acid.zalan.do".`,
1464-
},
1465-
{
1466-
about: "services differ on AWS ELB annotation",
1467-
current: newService(
1468-
map[string]string{
1469-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1470-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1471-
},
1472-
v1.ServiceTypeLoadBalancer,
1473-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1474-
new: newService(
1475-
map[string]string{
1476-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1477-
constants.ElbTimeoutAnnotationName: "1800",
1478-
},
1479-
v1.ServiceTypeLoadBalancer,
1480-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1481-
match: false,
1482-
reason: `new service's annotations does not match the current one: "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout" changed from "3600" to "1800".`,
1483-
},
1484-
{
1485-
about: "service changes existing annotation",
1486-
current: newService(
1487-
map[string]string{
1488-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1489-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1490-
"foo": "bar",
1491-
},
1492-
v1.ServiceTypeLoadBalancer,
1493-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1494-
new: newService(
1495-
map[string]string{
1496-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1497-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1498-
"foo": "baz",
1499-
},
1500-
v1.ServiceTypeLoadBalancer,
1501-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1502-
match: false,
1503-
reason: `new service's annotations does not match the current one: "foo" changed from "bar" to "baz".`,
1504-
},
1505-
{
1506-
about: "service changes multiple existing annotations",
1507-
current: newService(
1508-
map[string]string{
1509-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1510-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1511-
"foo": "bar",
1512-
"bar": "foo",
1513-
},
1514-
v1.ServiceTypeLoadBalancer,
1515-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1516-
new: newService(
1517-
map[string]string{
1518-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1519-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1520-
"foo": "baz",
1521-
"bar": "fooz",
1522-
},
1523-
v1.ServiceTypeLoadBalancer,
1524-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1525-
match: false,
1526-
// Test just the prefix to avoid flakiness and map sorting
1527-
reason: `new service's annotations does not match the current one:`,
1528-
},
1529-
{
1530-
about: "service adds a new custom annotation",
1531-
current: newService(
1532-
map[string]string{
1533-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1534-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1535-
},
1536-
v1.ServiceTypeLoadBalancer,
1537-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1538-
new: newService(
1539-
map[string]string{
1540-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1541-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1542-
"foo": "bar",
1543-
},
1544-
v1.ServiceTypeLoadBalancer,
1545-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1546-
match: false,
1547-
reason: `new service's annotations does not match the current one: Added "foo" with value "bar".`,
1548-
},
1549-
{
1550-
about: "service removes a custom annotation",
1551-
current: newService(
1552-
map[string]string{
1553-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1554-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1555-
"foo": "bar",
1556-
},
1557-
v1.ServiceTypeLoadBalancer,
1558-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1559-
new: newService(
1560-
map[string]string{
1561-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1562-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1563-
},
1564-
v1.ServiceTypeLoadBalancer,
1565-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1566-
match: false,
1567-
reason: `new service's annotations does not match the current one: Removed "foo".`,
1568-
},
1569-
{
1570-
about: "service removes a custom annotation and adds a new one",
1571-
current: newService(
1572-
map[string]string{
1573-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1574-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1575-
"foo": "bar",
1576-
},
1577-
v1.ServiceTypeLoadBalancer,
1578-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1579-
new: newService(
1580-
map[string]string{
1581-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1582-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1583-
"bar": "foo",
1584-
},
1585-
v1.ServiceTypeLoadBalancer,
1586-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1587-
match: false,
1588-
reason: `new service's annotations does not match the current one: Removed "foo". Added "bar" with value "foo".`,
1589-
},
1590-
{
1591-
about: "service removes a custom annotation, adds a new one and change another",
1592-
current: newService(
1593-
map[string]string{
1594-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1595-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1596-
"foo": "bar",
1597-
"zalan": "do",
1598-
},
1599-
v1.ServiceTypeLoadBalancer,
1600-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1601-
new: newService(
1602-
map[string]string{
1603-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1604-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1605-
"bar": "foo",
1606-
"zalan": "do.com",
1607-
},
1608-
v1.ServiceTypeLoadBalancer,
1609-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1610-
match: false,
1611-
// Test just the prefix to avoid flakiness and map sorting
1612-
reason: `new service's annotations does not match the current one: Removed "foo".`,
1613-
},
1614-
{
1615-
about: "service add annotations",
1616-
current: newService(
1617-
map[string]string{},
1618-
v1.ServiceTypeLoadBalancer,
1619-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1620-
new: newService(
1621-
map[string]string{
1622-
constants.ZalandoDNSNameAnnotation: "clstr.acid.zalan.do",
1623-
constants.ElbTimeoutAnnotationName: constants.ElbTimeoutAnnotationValue,
1624-
},
1625-
v1.ServiceTypeLoadBalancer,
1626-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1627-
match: false,
1628-
// Test just the prefix to avoid flakiness and map sorting
1629-
reason: `new service's annotations does not match the current one: Added `,
1630-
},
1631-
{
1632-
about: "ignored annotations",
1633-
current: newService(
1634-
map[string]string{},
1635-
v1.ServiceTypeLoadBalancer,
1636-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1637-
new: newService(
1638-
map[string]string{
1639-
"k8s.v1.cni.cncf.io/network-status": "up",
1640-
},
1641-
v1.ServiceTypeLoadBalancer,
1642-
[]string{"128.141.0.0/16", "137.138.0.0/16"}),
1643-
match: true,
1644-
},
16451446
}
16461447

16471448
for _, tt := range tests {

pkg/cluster/connection_pooler.go

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"github.com/sirupsen/logrus"
1111
acidzalando "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do"
1212
acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
13-
"golang.org/x/exp/maps"
1413
appsv1 "k8s.io/api/apps/v1"
1514
v1 "k8s.io/api/core/v1"
1615
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -692,6 +691,26 @@ func updateConnectionPoolerDeployment(KubeClient k8sutil.KubernetesClient, newDe
692691
return deployment, nil
693692
}
694693

694+
// patchConnectionPoolerAnnotations updates the annotations of connection pooler deployment
695+
func patchConnectionPoolerAnnotations(KubeClient k8sutil.KubernetesClient, deployment *appsv1.Deployment, annotations map[string]string) (*appsv1.Deployment, error) {
696+
patchData, err := metaAnnotationsPatch(annotations)
697+
if err != nil {
698+
return nil, fmt.Errorf("could not form patch for the connection pooler deployment metadata: %v", err)
699+
}
700+
result, err := KubeClient.Deployments(deployment.Namespace).Patch(
701+
context.TODO(),
702+
deployment.Name,
703+
types.MergePatchType,
704+
[]byte(patchData),
705+
metav1.PatchOptions{},
706+
"")
707+
if err != nil {
708+
return nil, fmt.Errorf("could not patch connection pooler annotations %q: %v", patchData, err)
709+
}
710+
return result, nil
711+
712+
}
713+
695714
// Test if two connection pooler configuration needs to be synced. For simplicity
696715
// compare not the actual K8S objects, but the configuration itself and request
697716
// sync if there is any difference.
@@ -1009,18 +1028,6 @@ func (c *Cluster) syncConnectionPoolerWorker(oldSpec, newSpec *acidv1.Postgresql
10091028
syncReason = append(syncReason, []string{"new connection pooler's pod template annotations do not match the current one: " + reason}...)
10101029
deployment.Spec.Template.Annotations = newPodAnnotations
10111030
}
1012-
newAnnotations := c.AnnotationsToPropagate(c.annotationsSet(nil)) // including the downscaling annotations
1013-
ignoredAnnotations := c.extractIgnoredAnnotations(deployment.Annotations)
1014-
maps.Copy(newAnnotations, ignoredAnnotations)
1015-
if changed, reason := c.compareAnnotations(deployment.Annotations, newAnnotations); changed {
1016-
deployment.Annotations = newAnnotations
1017-
c.logger.Infof("new connection pooler deployments's annotations does not match the current one:" + reason)
1018-
c.logger.Debug("updating connection pooler deployments's annotations")
1019-
deployment, err = c.KubeClient.Deployments(deployment.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{})
1020-
if err != nil {
1021-
return nil, fmt.Errorf("could not update connection pooler annotations %q: %v", deployment.Name, err)
1022-
}
1023-
}
10241031

10251032
defaultsSync, defaultsReason := c.needSyncConnectionPoolerDefaults(&c.Config, newConnectionPooler, deployment)
10261033
syncReason = append(syncReason, defaultsReason...)
@@ -1040,6 +1047,15 @@ func (c *Cluster) syncConnectionPoolerWorker(oldSpec, newSpec *acidv1.Postgresql
10401047
}
10411048
c.ConnectionPooler[role].Deployment = deployment
10421049
}
1050+
1051+
newAnnotations := c.AnnotationsToPropagate(c.annotationsSet(nil)) // including the downscaling annotations
1052+
if changed, _ := c.compareAnnotations(deployment.Annotations, newAnnotations); changed {
1053+
deployment, err = patchConnectionPoolerAnnotations(c.KubeClient, deployment, newAnnotations)
1054+
if err != nil {
1055+
return nil, err
1056+
}
1057+
c.ConnectionPooler[role].Deployment = deployment
1058+
}
10431059
}
10441060

10451061
// check if pooler pods must be replaced due to secret update
@@ -1068,13 +1084,13 @@ func (c *Cluster) syncConnectionPoolerWorker(oldSpec, newSpec *acidv1.Postgresql
10681084
return nil, fmt.Errorf("could not delete pooler pod: %v", err)
10691085
}
10701086
} else if changed, _ := c.compareAnnotations(pod.Annotations, deployment.Spec.Template.Annotations); changed {
1071-
newAnnotations := c.extractIgnoredAnnotations(pod.Annotations)
1072-
maps.Copy(newAnnotations, deployment.Spec.Template.Annotations)
1073-
pod.Annotations = newAnnotations
1074-
c.logger.Debugf("updating annotations for connection pooler's pod %q", pod.Name)
1075-
_, err := c.KubeClient.Pods(pod.Namespace).Update(context.TODO(), &pod, metav1.UpdateOptions{})
1087+
patchData, err := metaAnnotationsPatch(deployment.Spec.Template.Annotations)
1088+
if err != nil {
1089+
return nil, fmt.Errorf("could not form patch for pooler's pod annotations: %v", err)
1090+
}
1091+
_, err = c.KubeClient.Pods(pod.Namespace).Patch(context.TODO(), pod.Name, types.MergePatchType, []byte(patchData), metav1.PatchOptions{})
10761092
if err != nil {
1077-
return nil, fmt.Errorf("could not update annotations for pod %q: %v", pod.Name, err)
1093+
return nil, fmt.Errorf("could not patch annotations for pooler's pod %q: %v", pod.Name, err)
10781094
}
10791095
}
10801096
}

0 commit comments

Comments
 (0)