Feat: enable owner references (#2688)

* feat(498): Add ownerReferences to managed entities
* empty owner reference for cross namespace secret and more tests
* update ownerReferences of existing resources
* removing ownerReference requires Update API call
* CR ownerReference on PVC blocks pvc retention policy of statefulset
* make ownerreferences optional and disabled by default
* update unit test to check len ownerReferences
* update codegen
* add owner references e2e test
* update unit test
* add block_owner_deletion field to test owner reference
* fix typos and update docs once more
* reflect code feedback

---------

Co-authored-by: Max Begenau <max@begenau.com>
This commit is contained in:
Felix Kunde
2024-08-09 17:58:25 +02:00
committed by GitHub
co-authored by Max Begenau
parent d5a88f571a
commit a87307e56b
28 changed files with 535 additions and 206 deletions
+33 -9
View File
@@ -205,7 +205,6 @@ func (c *Cluster) syncService(role PostgresRole) error {
return fmt.Errorf("could not update %s service to match desired state: %v", role, err)
}
c.Services[role] = updatedSvc
c.logger.Infof("%s service %q is in the desired state now", role, util.NameFromMeta(desiredSvc.ObjectMeta))
return nil
}
if !k8sutil.ResourceNotFound(err) {
@@ -239,14 +238,24 @@ func (c *Cluster) syncEndpoint(role PostgresRole) error {
if ep, err = c.KubeClient.Endpoints(c.Namespace).Get(context.TODO(), c.endpointName(role), metav1.GetOptions{}); err == nil {
desiredEp := c.generateEndpoint(role, ep.Subsets)
if changed, _ := c.compareAnnotations(ep.Annotations, desiredEp.Annotations); changed {
patchData, err := metaAnnotationsPatch(desiredEp.Annotations)
// if owner references differ we update which would also change annotations
if !reflect.DeepEqual(ep.ObjectMeta.OwnerReferences, desiredEp.ObjectMeta.OwnerReferences) {
c.logger.Infof("new %s endpoints's owner references do not match the current ones", role)
c.setProcessName("updating %v endpoint", role)
ep, err = c.KubeClient.Endpoints(c.Namespace).Update(context.TODO(), desiredEp, metav1.UpdateOptions{})
if err != nil {
return fmt.Errorf("could not form patch for %s endpoint: %v", role, err)
return fmt.Errorf("could not update %s endpoint: %v", role, err)
}
ep, err = c.KubeClient.Endpoints(c.Namespace).Patch(context.TODO(), c.endpointName(role), types.MergePatchType, []byte(patchData), metav1.PatchOptions{})
if err != nil {
return fmt.Errorf("could not patch annotations of %s endpoint: %v", role, err)
} else {
if changed, _ := c.compareAnnotations(ep.Annotations, desiredEp.Annotations); changed {
patchData, err := metaAnnotationsPatch(desiredEp.Annotations)
if err != nil {
return fmt.Errorf("could not form patch for %s endpoint: %v", role, err)
}
ep, err = c.KubeClient.Endpoints(c.Namespace).Patch(context.TODO(), c.endpointName(role), types.MergePatchType, []byte(patchData), metav1.PatchOptions{})
if err != nil {
return fmt.Errorf("could not patch annotations of %s endpoint: %v", role, err)
}
}
}
c.Endpoints[role] = ep
@@ -957,9 +966,15 @@ func (c *Cluster) updateSecret(
userMap[userKey] = pwdUser
}
if !reflect.DeepEqual(secret.ObjectMeta.OwnerReferences, generatedSecret.ObjectMeta.OwnerReferences) {
updateSecret = true
updateSecretMsg = fmt.Sprintf("secret %s owner references do not match the current ones", secretName)
secret.ObjectMeta.OwnerReferences = generatedSecret.ObjectMeta.OwnerReferences
}
if updateSecret {
c.logger.Debugln(updateSecretMsg)
if _, err = c.KubeClient.Secrets(secret.Namespace).Update(context.TODO(), secret, metav1.UpdateOptions{}); err != nil {
if secret, err = c.KubeClient.Secrets(secret.Namespace).Update(context.TODO(), secret, metav1.UpdateOptions{}); err != nil {
return fmt.Errorf("could not update secret %s: %v", secretName, err)
}
c.Secrets[secret.UID] = secret
@@ -970,10 +985,11 @@ func (c *Cluster) updateSecret(
if err != nil {
return fmt.Errorf("could not form patch for secret %q annotations: %v", secret.Name, err)
}
_, err = c.KubeClient.Secrets(secret.Namespace).Patch(context.TODO(), secret.Name, types.MergePatchType, []byte(patchData), metav1.PatchOptions{})
secret, err = c.KubeClient.Secrets(secret.Namespace).Patch(context.TODO(), secret.Name, types.MergePatchType, []byte(patchData), metav1.PatchOptions{})
if err != nil {
return fmt.Errorf("could not patch annotations for secret %q: %v", secret.Name, err)
}
c.Secrets[secret.UID] = secret
}
return nil
@@ -1401,6 +1417,14 @@ func (c *Cluster) syncLogicalBackupJob() error {
if err != nil {
return fmt.Errorf("could not generate the desired logical backup job state: %v", err)
}
if !reflect.DeepEqual(job.ObjectMeta.OwnerReferences, desiredJob.ObjectMeta.OwnerReferences) {
c.logger.Info("new logical backup job's owner references do not match the current ones")
job, err = c.KubeClient.CronJobs(job.Namespace).Update(context.TODO(), desiredJob, metav1.UpdateOptions{})
if err != nil {
return fmt.Errorf("could not update owner references for logical backup job %q: %v", job.Name, err)
}
c.logger.Infof("logical backup job %s updated", c.getLogicalBackupJobName())
}
if match, reason := c.compareLogicalBackupJob(job, desiredJob); !match {
c.logger.Infof("logical job %s is not in the desired state and needs to be updated",
c.getLogicalBackupJobName(),