Skip to content

Commit b5e48bd

Browse files
committed
chore: add tests for secret updation behavior
1 parent 3679188 commit b5e48bd

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

test/e2e/reconcile_objects_test.go

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package e2e
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"slices"
7+
"strings"
8+
"testing"
9+
"time"
10+
11+
"github.com/openshift/cluster-monitoring-operator/test/e2e/framework"
12+
"github.com/stretchr/testify/require"
13+
"k8s.io/apimachinery/pkg/api/errors"
14+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15+
"k8s.io/apimachinery/pkg/types"
16+
)
17+
18+
func TestSecretsReconciliation(t *testing.T) {
19+
// Create assets under both scenarios for us to work with.
20+
setupUserWorkloadAssetsWithTeardownHook(t, f)
21+
userWorkloadConfigMap := f.BuildUserWorkloadConfigMap(t, `alertmanager:
22+
enabled: true
23+
`)
24+
f.MustCreateOrUpdateConfigMap(t, userWorkloadConfigMap)
25+
defer f.MustDeleteConfigMap(t, userWorkloadConfigMap)
26+
for _, secret := range []types.NamespacedName{
27+
{
28+
Name: "alertmanager-kube-rbac-proxy-metric",
29+
Namespace: f.Ns,
30+
},
31+
{
32+
Name: "alertmanager-kube-rbac-proxy-metric",
33+
Namespace: f.UserWorkloadMonitoringNs,
34+
},
35+
} {
36+
f.AssertSecretExists(secret.Name, secret.Namespace)(t)
37+
}
38+
39+
// List of secrets that should not be synced during operator's reconciliation.
40+
unsyncedSecrets := []types.NamespacedName{
41+
{
42+
Name: "alertmanager-main",
43+
Namespace: f.Ns,
44+
},
45+
{
46+
Name: "alertmanager-user-workload",
47+
Namespace: f.UserWorkloadMonitoringNs,
48+
},
49+
}
50+
cleanup := func() {
51+
// Restore all unsynced secrets to their original state.
52+
for _, secret := range unsyncedSecrets {
53+
gotSecret, err := f.KubeClient.CoreV1().Secrets(secret.Namespace).Get(context.Background(), secret.Name, metav1.GetOptions{})
54+
if err != nil {
55+
if errors.IsNotFound(err) {
56+
t.Logf("Secret %s not found, skipping cleanup", secret.String())
57+
continue
58+
}
59+
require.NoError(t, err)
60+
}
61+
data := gotSecret.Data
62+
stringData := gotSecret.StringData
63+
for k, v := range data {
64+
data[k] = []byte(strings.TrimPrefix(string(v), t.Name()))
65+
}
66+
for k, v := range stringData {
67+
stringData[k] = strings.TrimPrefix(v, t.Name())
68+
}
69+
_, err = f.KubeClient.CoreV1().Secrets(secret.Namespace).Update(context.Background(), gotSecret, metav1.UpdateOptions{})
70+
require.NoError(t, err)
71+
}
72+
}
73+
defer cleanup()
74+
75+
var syncedSecrets []types.NamespacedName
76+
secretsNS, err := f.KubeClient.CoreV1().Secrets(f.Ns).List(context.Background(), metav1.ListOptions{
77+
// Intentionally commented out as we want to fetch all secrets.
78+
// LabelSelector: "app.kubernetes.io/managed-by=cluster-monitoring-operator",
79+
})
80+
require.NoError(t, err)
81+
secretsUWMNS, err := f.KubeClient.CoreV1().Secrets(f.UserWorkloadMonitoringNs).List(context.Background(), metav1.ListOptions{
82+
// Intentionally commented out as we want to fetch all secrets.
83+
// LabelSelector: "app.kubernetes.io/managed-by=cluster-monitoring-operator",
84+
})
85+
require.NoError(t, err)
86+
for _, secret := range append(secretsNS.Items, secretsUWMNS.Items...) {
87+
secretNamespacedName := types.NamespacedName{
88+
Name: secret.Name,
89+
Namespace: secret.Namespace,
90+
}
91+
if slices.Contains(unsyncedSecrets, secretNamespacedName) {
92+
continue
93+
}
94+
syncedSecrets = append(syncedSecrets, secretNamespacedName)
95+
}
96+
require.NotEmpty(t, syncedSecrets)
97+
98+
// Update the aforementioned secrets' data.
99+
for _, secret := range append(syncedSecrets, unsyncedSecrets...) {
100+
gotSecret, err := f.KubeClient.CoreV1().Secrets(secret.Namespace).Get(context.Background(), secret.Name, metav1.GetOptions{})
101+
require.NoError(t, err)
102+
data := gotSecret.Data
103+
stringData := gotSecret.StringData
104+
for k, v := range data {
105+
data[k] = []byte(t.Name() + string(v))
106+
break
107+
}
108+
for k, v := range stringData {
109+
stringData[k] = t.Name() + v
110+
break
111+
}
112+
_, err = f.KubeClient.CoreV1().Secrets(secret.Namespace).Update(context.Background(), gotSecret, metav1.UpdateOptions{})
113+
require.NoError(t, err)
114+
}
115+
116+
// Check if the secrets were reconciled as expected.
117+
for _, secret := range syncedSecrets {
118+
err := framework.Poll(time.Second, 6*time.Minute, func() error {
119+
updatedSecret, err := f.KubeClient.CoreV1().Secrets(secret.Namespace).Get(context.Background(), secret.Name, metav1.GetOptions{})
120+
if err != nil {
121+
return err
122+
}
123+
data := updatedSecret.Data
124+
stringData := updatedSecret.StringData
125+
for _, v := range data {
126+
if strings.HasPrefix(string(v), t.Name()) {
127+
return fmt.Errorf("secret %s has unexpected data", secret.String())
128+
}
129+
}
130+
for _, v := range stringData {
131+
if strings.HasPrefix(v, t.Name()) {
132+
return fmt.Errorf("secret %s has unexpected stringData", secret.String())
133+
}
134+
}
135+
return nil
136+
})
137+
require.NoError(t, err)
138+
}
139+
140+
// Check if the secrets were reconciled unexpectedly.
141+
for _, secret := range unsyncedSecrets {
142+
updatedSecret, err := f.KubeClient.CoreV1().Secrets(secret.Namespace).Get(context.Background(), secret.Name, metav1.GetOptions{})
143+
require.NoError(t, err)
144+
for _, v := range updatedSecret.Data {
145+
require.False(t, strings.HasPrefix(string(v), t.Name()), fmt.Sprintf("secret %s was unexpectedly reconciled", secret.String()))
146+
}
147+
for _, v := range updatedSecret.StringData {
148+
require.False(t, strings.HasPrefix(v, t.Name()), fmt.Sprintf("secret %s was unexpectedly reconciled", secret.String()))
149+
}
150+
}
151+
}

0 commit comments

Comments
 (0)