Skip to content

Commit 1a91adb

Browse files
committed
feat(498): Add ownerReferences to managed entities
1 parent 0ac5f58 commit 1a91adb

File tree

2 files changed

+128
-99
lines changed

2 files changed

+128
-99
lines changed

pkg/cluster/k8sres.go

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,10 +1473,11 @@ func (c *Cluster) generateStatefulSet(spec *acidv1.PostgresSpec) (*appsv1.Statef
14731473

14741474
statefulSet := &appsv1.StatefulSet{
14751475
ObjectMeta: metav1.ObjectMeta{
1476-
Name: c.statefulSetName(),
1477-
Namespace: c.Namespace,
1478-
Labels: c.labelsSet(true),
1479-
Annotations: c.AnnotationsToPropagate(c.annotationsSet(nil)),
1476+
Name: c.statefulSetName(),
1477+
Namespace: c.Namespace,
1478+
Labels: c.labelsSet(true),
1479+
Annotations: c.AnnotationsToPropagate(c.annotationsSet(nil)),
1480+
OwnerReferences: c.ownerReferences(),
14801481
},
14811482
Spec: appsv1.StatefulSetSpec{
14821483
Replicas: &numberOfInstances,
@@ -1813,10 +1814,11 @@ func (c *Cluster) generateSingleUserSecret(namespace string, pgUser spec.PgUser)
18131814

18141815
secret := v1.Secret{
18151816
ObjectMeta: metav1.ObjectMeta{
1816-
Name: c.credentialSecretName(username),
1817-
Namespace: pgUser.Namespace,
1818-
Labels: lbls,
1819-
Annotations: c.annotationsSet(nil),
1817+
Name: c.credentialSecretName(username),
1818+
Namespace: pgUser.Namespace,
1819+
Labels: lbls,
1820+
Annotations: c.annotationsSet(nil),
1821+
OwnerReferences: c.ownerReferences(),
18201822
},
18211823
Type: v1.SecretTypeOpaque,
18221824
Data: map[string][]byte{
@@ -1874,10 +1876,11 @@ func (c *Cluster) generateService(role PostgresRole, spec *acidv1.PostgresSpec)
18741876

18751877
service := &v1.Service{
18761878
ObjectMeta: metav1.ObjectMeta{
1877-
Name: c.serviceName(role),
1878-
Namespace: c.Namespace,
1879-
Labels: c.roleLabelsSet(true, role),
1880-
Annotations: c.annotationsSet(c.generateServiceAnnotations(role, spec)),
1879+
Name: c.serviceName(role),
1880+
Namespace: c.Namespace,
1881+
Labels: c.roleLabelsSet(true, role),
1882+
Annotations: c.annotationsSet(c.generateServiceAnnotations(role, spec)),
1883+
OwnerReferences: c.ownerReferences(),
18811884
},
18821885
Spec: serviceSpec,
18831886
}
@@ -1943,9 +1946,10 @@ func (c *Cluster) getCustomServiceAnnotations(role PostgresRole, spec *acidv1.Po
19431946
func (c *Cluster) generateEndpoint(role PostgresRole, subsets []v1.EndpointSubset) *v1.Endpoints {
19441947
endpoints := &v1.Endpoints{
19451948
ObjectMeta: metav1.ObjectMeta{
1946-
Name: c.endpointName(role),
1947-
Namespace: c.Namespace,
1948-
Labels: c.roleLabelsSet(true, role),
1949+
Name: c.endpointName(role),
1950+
Namespace: c.Namespace,
1951+
Labels: c.roleLabelsSet(true, role),
1952+
OwnerReferences: c.ownerReferences(),
19491953
},
19501954
}
19511955
if len(subsets) > 0 {
@@ -2099,10 +2103,11 @@ func (c *Cluster) generatePodDisruptionBudget() *policyv1.PodDisruptionBudget {
20992103

21002104
return &policyv1.PodDisruptionBudget{
21012105
ObjectMeta: metav1.ObjectMeta{
2102-
Name: c.podDisruptionBudgetName(),
2103-
Namespace: c.Namespace,
2104-
Labels: c.labelsSet(true),
2105-
Annotations: c.annotationsSet(nil),
2106+
Name: c.podDisruptionBudgetName(),
2107+
Namespace: c.Namespace,
2108+
Labels: c.labelsSet(true),
2109+
Annotations: c.annotationsSet(nil),
2110+
OwnerReferences: c.ownerReferences(),
21062111
},
21072112
Spec: policyv1.PodDisruptionBudgetSpec{
21082113
MinAvailable: &minAvailable,
@@ -2224,10 +2229,11 @@ func (c *Cluster) generateLogicalBackupJob() (*batchv1.CronJob, error) {
22242229

22252230
cronJob := &batchv1.CronJob{
22262231
ObjectMeta: metav1.ObjectMeta{
2227-
Name: c.getLogicalBackupJobName(),
2228-
Namespace: c.Namespace,
2229-
Labels: c.labelsSet(true),
2230-
Annotations: c.annotationsSet(nil),
2232+
Name: c.getLogicalBackupJobName(),
2233+
Namespace: c.Namespace,
2234+
Labels: c.labelsSet(true),
2235+
Annotations: c.annotationsSet(nil),
2236+
OwnerReferences: c.ownerReferences(),
22312237
},
22322238
Spec: batchv1.CronJobSpec{
22332239
Schedule: schedule,
@@ -2363,17 +2369,12 @@ func (c *Cluster) getLogicalBackupJobName() (jobName string) {
23632369
func (c *Cluster) ownerReferences() []metav1.OwnerReference {
23642370
controller := true
23652371

2366-
if c.Statefulset == nil {
2367-
c.logger.Warning("Cannot get owner reference, no statefulset")
2368-
return []metav1.OwnerReference{}
2369-
}
2370-
23712372
return []metav1.OwnerReference{
23722373
{
2373-
UID: c.Statefulset.ObjectMeta.UID,
2374-
APIVersion: "apps/v1",
2375-
Kind: "StatefulSet",
2376-
Name: c.Statefulset.ObjectMeta.Name,
2374+
UID: c.Postgresql.ObjectMeta.UID,
2375+
APIVersion: acidv1.SchemeGroupVersion.Identifier(),
2376+
Kind: acidv1.PostgresCRDResourceKind,
2377+
Name: c.Postgresql.ObjectMeta.Name,
23772378
Controller: &controller,
23782379
},
23792380
}

pkg/cluster/k8sres_test.go

Lines changed: 95 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,9 +1491,9 @@ func TestPodAffinity(t *testing.T) {
14911491
func testDeploymentOwnerReference(cluster *Cluster, deployment *appsv1.Deployment) error {
14921492
owner := deployment.ObjectMeta.OwnerReferences[0]
14931493

1494-
if owner.Name != cluster.Statefulset.ObjectMeta.Name {
1495-
return fmt.Errorf("Ownere reference is incorrect, got %s, expected %s",
1496-
owner.Name, cluster.Statefulset.ObjectMeta.Name)
1494+
if owner.Name != cluster.Postgresql.ObjectMeta.Name {
1495+
return fmt.Errorf("Owner reference is incorrect, got %s, expected %s",
1496+
owner.Name, cluster.Postgresql.ObjectMeta.Name)
14971497
}
14981498

14991499
return nil
@@ -1502,9 +1502,9 @@ func testDeploymentOwnerReference(cluster *Cluster, deployment *appsv1.Deploymen
15021502
func testServiceOwnerReference(cluster *Cluster, service *v1.Service, role PostgresRole) error {
15031503
owner := service.ObjectMeta.OwnerReferences[0]
15041504

1505-
if owner.Name != cluster.Statefulset.ObjectMeta.Name {
1506-
return fmt.Errorf("Ownere reference is incorrect, got %s, expected %s",
1507-
owner.Name, cluster.Statefulset.ObjectMeta.Name)
1505+
if owner.Name != cluster.Postgresql.ObjectMeta.Name {
1506+
return fmt.Errorf("Owner reference is incorrect, got %s, expected %s",
1507+
owner.Name, cluster.Postgresql.ObjectMeta.Name)
15081508
}
15091509

15101510
return nil
@@ -2201,112 +2201,140 @@ func TestSidecars(t *testing.T) {
22012201
}
22022202

22032203
func TestGeneratePodDisruptionBudget(t *testing.T) {
2204+
testName := "Test PodDisruptionBudget spec generation"
2205+
2206+
hasName := func(pdbName string) func(cluster *Cluster, podDisruptionBudget *policyv1.PodDisruptionBudget) error {
2207+
return func(cluster *Cluster, podDisruptionBudget *policyv1.PodDisruptionBudget) error {
2208+
if pdbName != podDisruptionBudget.ObjectMeta.Name {
2209+
return fmt.Errorf("PodDisruptionBudget name is incorrect, got %s, expected %s",
2210+
podDisruptionBudget.ObjectMeta.Name, pdbName)
2211+
}
2212+
return nil
2213+
}
2214+
}
2215+
2216+
hasMinAvailable := func(expectedMinAvailable int) func(cluster *Cluster, podDisruptionBudget *policyv1.PodDisruptionBudget) error {
2217+
return func(cluster *Cluster, podDisruptionBudget *policyv1.PodDisruptionBudget) error {
2218+
actual := podDisruptionBudget.Spec.MinAvailable.IntVal
2219+
if actual != int32(expectedMinAvailable) {
2220+
return fmt.Errorf("PodDisruptionBudget MinAvailable is incorrect, got %d, expected %d",
2221+
actual, expectedMinAvailable)
2222+
}
2223+
return nil
2224+
}
2225+
}
2226+
2227+
testLabelsAndSelectors := func(cluster *Cluster, podDisruptionBudget *policyv1.PodDisruptionBudget) error {
2228+
if podDisruptionBudget.ObjectMeta.Namespace != "myapp" {
2229+
return fmt.Errorf("Object Namespace incorrect.")
2230+
}
2231+
if !reflect.DeepEqual(podDisruptionBudget.Labels, map[string]string{"team": "myapp", "cluster-name": "myapp-database"}) {
2232+
2233+
return fmt.Errorf("Labels incorrect.")
2234+
}
2235+
if !reflect.DeepEqual(podDisruptionBudget.Spec.Selector, &metav1.LabelSelector{
2236+
MatchLabels: map[string]string{"spilo-role": "master", "cluster-name": "myapp-database"}}) {
2237+
2238+
return fmt.Errorf("MatchLabels incorrect.")
2239+
}
2240+
2241+
return nil
2242+
}
2243+
2244+
testPodDisruptionBudgetOwnerReference := func(cluster *Cluster, podDisruptionBudget *policyv1.PodDisruptionBudget) error {
2245+
owner := podDisruptionBudget.ObjectMeta.OwnerReferences[0]
2246+
2247+
if owner.Name != cluster.Postgresql.ObjectMeta.Name {
2248+
return fmt.Errorf("Owner reference is incorrect, got %s, expected %s",
2249+
owner.Name, cluster.Postgresql.ObjectMeta.Name)
2250+
}
2251+
2252+
return nil
2253+
}
2254+
22042255
tests := []struct {
2205-
c *Cluster
2206-
out policyv1.PodDisruptionBudget
2256+
scenario string
2257+
spec *Cluster
2258+
check []func(cluster *Cluster, podDisruptionBudget *policyv1.PodDisruptionBudget) error
22072259
}{
2208-
// With multiple instances.
22092260
{
2210-
New(
2261+
scenario: "With multiple instances",
2262+
spec: New(
22112263
Config{OpConfig: config.Config{Resources: config.Resources{ClusterNameLabel: "cluster-name", PodRoleLabel: "spilo-role"}, PDBNameFormat: "postgres-{cluster}-pdb"}},
22122264
k8sutil.KubernetesClient{},
22132265
acidv1.Postgresql{
22142266
ObjectMeta: metav1.ObjectMeta{Name: "myapp-database", Namespace: "myapp"},
22152267
Spec: acidv1.PostgresSpec{TeamID: "myapp", NumberOfInstances: 3}},
22162268
logger,
22172269
eventRecorder),
2218-
policyv1.PodDisruptionBudget{
2219-
ObjectMeta: metav1.ObjectMeta{
2220-
Name: "postgres-myapp-database-pdb",
2221-
Namespace: "myapp",
2222-
Labels: map[string]string{"team": "myapp", "cluster-name": "myapp-database"},
2223-
},
2224-
Spec: policyv1.PodDisruptionBudgetSpec{
2225-
MinAvailable: util.ToIntStr(1),
2226-
Selector: &metav1.LabelSelector{
2227-
MatchLabels: map[string]string{"spilo-role": "master", "cluster-name": "myapp-database"},
2228-
},
2229-
},
2270+
check: []func(cluster *Cluster, podDisruptionBudget *policyv1.PodDisruptionBudget) error{
2271+
testPodDisruptionBudgetOwnerReference,
2272+
hasName("postgres-myapp-database-pdb"),
2273+
hasMinAvailable(1),
2274+
testLabelsAndSelectors,
22302275
},
22312276
},
2232-
// With zero instances.
22332277
{
2234-
New(
2278+
scenario: "With zero instances",
2279+
spec: New(
22352280
Config{OpConfig: config.Config{Resources: config.Resources{ClusterNameLabel: "cluster-name", PodRoleLabel: "spilo-role"}, PDBNameFormat: "postgres-{cluster}-pdb"}},
22362281
k8sutil.KubernetesClient{},
22372282
acidv1.Postgresql{
22382283
ObjectMeta: metav1.ObjectMeta{Name: "myapp-database", Namespace: "myapp"},
22392284
Spec: acidv1.PostgresSpec{TeamID: "myapp", NumberOfInstances: 0}},
22402285
logger,
22412286
eventRecorder),
2242-
policyv1.PodDisruptionBudget{
2243-
ObjectMeta: metav1.ObjectMeta{
2244-
Name: "postgres-myapp-database-pdb",
2245-
Namespace: "myapp",
2246-
Labels: map[string]string{"team": "myapp", "cluster-name": "myapp-database"},
2247-
},
2248-
Spec: policyv1.PodDisruptionBudgetSpec{
2249-
MinAvailable: util.ToIntStr(0),
2250-
Selector: &metav1.LabelSelector{
2251-
MatchLabels: map[string]string{"spilo-role": "master", "cluster-name": "myapp-database"},
2252-
},
2253-
},
2287+
check: []func(cluster *Cluster, podDisruptionBudget *policyv1.PodDisruptionBudget) error{
2288+
testPodDisruptionBudgetOwnerReference,
2289+
hasName("postgres-myapp-database-pdb"),
2290+
hasMinAvailable(0),
2291+
testLabelsAndSelectors,
22542292
},
22552293
},
2256-
// With PodDisruptionBudget disabled.
22572294
{
2258-
New(
2295+
scenario: "With PodDisruptionBudget disabled",
2296+
spec: New(
22592297
Config{OpConfig: config.Config{Resources: config.Resources{ClusterNameLabel: "cluster-name", PodRoleLabel: "spilo-role"}, PDBNameFormat: "postgres-{cluster}-pdb", EnablePodDisruptionBudget: util.False()}},
22602298
k8sutil.KubernetesClient{},
22612299
acidv1.Postgresql{
22622300
ObjectMeta: metav1.ObjectMeta{Name: "myapp-database", Namespace: "myapp"},
22632301
Spec: acidv1.PostgresSpec{TeamID: "myapp", NumberOfInstances: 3}},
22642302
logger,
22652303
eventRecorder),
2266-
policyv1.PodDisruptionBudget{
2267-
ObjectMeta: metav1.ObjectMeta{
2268-
Name: "postgres-myapp-database-pdb",
2269-
Namespace: "myapp",
2270-
Labels: map[string]string{"team": "myapp", "cluster-name": "myapp-database"},
2271-
},
2272-
Spec: policyv1.PodDisruptionBudgetSpec{
2273-
MinAvailable: util.ToIntStr(0),
2274-
Selector: &metav1.LabelSelector{
2275-
MatchLabels: map[string]string{"spilo-role": "master", "cluster-name": "myapp-database"},
2276-
},
2277-
},
2304+
check: []func(cluster *Cluster, podDisruptionBudget *policyv1.PodDisruptionBudget) error{
2305+
testPodDisruptionBudgetOwnerReference,
2306+
hasName("postgres-myapp-database-pdb"),
2307+
hasMinAvailable(0),
2308+
testLabelsAndSelectors,
22782309
},
22792310
},
2280-
// With non-default PDBNameFormat and PodDisruptionBudget explicitly enabled.
22812311
{
2282-
New(
2312+
scenario: "With non-default PDBNameFormat and PodDisruptionBudget explicitly enabled",
2313+
spec: New(
22832314
Config{OpConfig: config.Config{Resources: config.Resources{ClusterNameLabel: "cluster-name", PodRoleLabel: "spilo-role"}, PDBNameFormat: "postgres-{cluster}-databass-budget", EnablePodDisruptionBudget: util.True()}},
22842315
k8sutil.KubernetesClient{},
22852316
acidv1.Postgresql{
22862317
ObjectMeta: metav1.ObjectMeta{Name: "myapp-database", Namespace: "myapp"},
22872318
Spec: acidv1.PostgresSpec{TeamID: "myapp", NumberOfInstances: 3}},
22882319
logger,
22892320
eventRecorder),
2290-
policyv1.PodDisruptionBudget{
2291-
ObjectMeta: metav1.ObjectMeta{
2292-
Name: "postgres-myapp-database-databass-budget",
2293-
Namespace: "myapp",
2294-
Labels: map[string]string{"team": "myapp", "cluster-name": "myapp-database"},
2295-
},
2296-
Spec: policyv1.PodDisruptionBudgetSpec{
2297-
MinAvailable: util.ToIntStr(1),
2298-
Selector: &metav1.LabelSelector{
2299-
MatchLabels: map[string]string{"spilo-role": "master", "cluster-name": "myapp-database"},
2300-
},
2301-
},
2321+
check: []func(cluster *Cluster, podDisruptionBudget *policyv1.PodDisruptionBudget) error{
2322+
testPodDisruptionBudgetOwnerReference,
2323+
hasName("postgres-myapp-database-databass-budget"),
2324+
hasMinAvailable(1),
2325+
testLabelsAndSelectors,
23022326
},
23032327
},
23042328
}
23052329

23062330
for _, tt := range tests {
2307-
result := tt.c.generatePodDisruptionBudget()
2308-
if !reflect.DeepEqual(*result, tt.out) {
2309-
t.Errorf("Expected PodDisruptionBudget: %#v, got %#v", tt.out, *result)
2331+
result := tt.spec.generatePodDisruptionBudget()
2332+
for _, check := range tt.check {
2333+
err := check(tt.spec, result)
2334+
if err != nil {
2335+
t.Errorf("%s [%s]: PodDisruptionBudget spec is incorrect, %+v",
2336+
testName, tt.scenario, err)
2337+
}
23102338
}
23112339
}
23122340
}

0 commit comments

Comments
 (0)