Skip to content

Commit c2589f3

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

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+
"strings"
7+
"testing"
8+
"time"
9+
10+
"github.com/openshift/cluster-monitoring-operator/test/e2e/framework"
11+
"github.com/stretchr/testify/require"
12+
"k8s.io/apimachinery/pkg/api/errors"
13+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14+
"k8s.io/apimachinery/pkg/types"
15+
)
16+
17+
func TestSecretsReconciliation(t *testing.T) {
18+
// Create assets under both scenarios for us to work with.
19+
setupUserWorkloadAssetsWithTeardownHook(t, f)
20+
userWorkloadConfigMap := f.BuildUserWorkloadConfigMap(t, `alertmanager:
21+
enabled: true
22+
`)
23+
f.MustCreateOrUpdateConfigMap(t, userWorkloadConfigMap)
24+
defer f.MustDeleteConfigMap(t, userWorkloadConfigMap)
25+
for _, secret := range []types.NamespacedName{
26+
{
27+
Name: "alertmanager-kube-rbac-proxy-metric",
28+
Namespace: f.Ns,
29+
},
30+
{
31+
Name: "alertmanager-kube-rbac-proxy-metric",
32+
Namespace: f.UserWorkloadMonitoringNs,
33+
},
34+
} {
35+
f.AssertSecretExists(secret.Name, secret.Namespace)(t)
36+
}
37+
38+
// List of secrets that should not be synced during operator's reconciliation.
39+
unsyncedSecrets := []types.NamespacedName{
40+
{
41+
Name: "alertmanager-main",
42+
Namespace: f.Ns,
43+
},
44+
{
45+
Name: "alertmanager-user-workload",
46+
Namespace: f.UserWorkloadMonitoringNs,
47+
},
48+
}
49+
cleanup := func() {
50+
// Restore all unsynced secrets to their original state.
51+
for _, secret := range unsyncedSecrets {
52+
gotSecret, err := f.KubeClient.CoreV1().Secrets(secret.Namespace).Get(context.Background(), secret.Name, metav1.GetOptions{})
53+
if err != nil {
54+
if errors.IsNotFound(err) {
55+
t.Logf("Secret %s not found, skipping cleanup", secret.String())
56+
continue
57+
}
58+
require.NoError(t, err)
59+
}
60+
data := gotSecret.Data
61+
stringData := gotSecret.StringData
62+
for k, v := range data {
63+
data[k] = []byte(strings.TrimPrefix(string(v), t.Name()))
64+
}
65+
for k, v := range stringData {
66+
stringData[k] = strings.TrimPrefix(v, t.Name())
67+
}
68+
_, err = f.KubeClient.CoreV1().Secrets(secret.Namespace).Update(context.Background(), gotSecret, metav1.UpdateOptions{})
69+
require.NoError(t, err)
70+
}
71+
}
72+
defer cleanup()
73+
74+
var syncedSecrets []types.NamespacedName
75+
secretsNS, err := f.KubeClient.CoreV1().Secrets(f.Ns).List(context.Background(), metav1.ListOptions{
76+
// Intentionally commented out as we want to fetch all secrets.
77+
// LabelSelector: "app.kubernetes.io/managed-by=cluster-monitoring-operator",
78+
})
79+
require.NoError(t, err)
80+
secretsUWMNS, err := f.KubeClient.CoreV1().Secrets(f.UserWorkloadMonitoringNs).List(context.Background(), metav1.ListOptions{
81+
// Intentionally commented out as we want to fetch all secrets.
82+
// LabelSelector: "app.kubernetes.io/managed-by=cluster-monitoring-operator",
83+
})
84+
require.NoError(t, err)
85+
for _, secret := range append(secretsNS.Items, secretsUWMNS.Items...) {
86+
for _, unsyncedSecret := range unsyncedSecrets {
87+
if secret.Name == unsyncedSecret.Name && secret.Namespace == unsyncedSecret.Namespace {
88+
continue
89+
}
90+
}
91+
syncedSecrets = append(syncedSecrets, types.NamespacedName{
92+
Name: secret.Name,
93+
Namespace: secret.Namespace,
94+
})
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)