Skip to content

Commit c638a2b

Browse files
authored
fix: Handle malformed cluster secrets gracefully (#739)
Signed-off-by: jannfis <jann@mistrust.net>
1 parent d96a91b commit c638a2b

File tree

2 files changed

+67
-3
lines changed

2 files changed

+67
-3
lines changed

internal/argocd/cluster/informer.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ func (m *Manager) onClusterAdded(res *v1.Secret) {
4444
cluster, err := db.SecretToCluster(res)
4545
if err != nil {
4646
log().WithError(err).Error("Not a cluster secret or malformed data")
47+
return
4748
}
4849

4950
// TODO(jannfis): Do we want to validate cluster configuration here?
@@ -78,7 +79,7 @@ func (m *Manager) onClusterUpdated(old *v1.Secret, new *v1.Secret) {
7879

7980
c, err := db.SecretToCluster(new)
8081
if err != nil {
81-
log().WithError(err).Errorf("Could not update ")
82+
log().WithError(err).Errorf("Not a cluster secret or malformed data")
8283
return
8384
}
8485

@@ -90,9 +91,11 @@ func (m *Manager) onClusterUpdated(old *v1.Secret, new *v1.Secret) {
9091
}
9192
}
9293

93-
// Unmap cluster from old agent
94+
// Unmap cluster from old agent. If the cluster isn't mapped yet (that
95+
// can happen if onClusterAdded found a malformed secret), we treat the
96+
// operation as upsert instead of unmapping the old cluster.
9497
log().Tracef("Unmapping cluster %s from agent %s", c.Name, oldAgent)
95-
if err = m.unmapCluster(oldAgent); err != nil {
98+
if err = m.unmapCluster(oldAgent); err != nil && err != ErrNotMapped {
9699
log().WithError(err).Errorf("Could not unmap cluster %s from agent %s", c.Name, oldAgent)
97100
return
98101
}

internal/argocd/cluster/informer_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,23 @@ func Test_onClusterAdded(t *testing.T) {
2828
m.onClusterAdded(s)
2929
assert.Len(t, m.clusters, 1)
3030
})
31+
t.Run("Secret is malformed", func(t *testing.T) {
32+
m, err := NewManager(context.TODO(), "argocd", "", "", "", kube.NewFakeKubeClient("argocd"))
33+
require.NoError(t, err)
34+
s := &v1.Secret{
35+
ObjectMeta: metav1.ObjectMeta{
36+
Labels: map[string]string{
37+
LabelKeyClusterAgentMapping: "agent",
38+
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
39+
},
40+
},
41+
Data: map[string][]byte{
42+
"config": []byte("invalid json"),
43+
},
44+
}
45+
m.onClusterAdded(s)
46+
assert.Len(t, m.clusters, 0)
47+
})
3148
t.Run("Secret is missing one or more labels", func(t *testing.T) {
3249
m, err := NewManager(context.TODO(), "argocd", "", "", "", kube.NewFakeKubeClient("argocd"))
3350
require.NoError(t, err)
@@ -91,6 +108,50 @@ func Test_onClusterUpdated(t *testing.T) {
91108
assert.Nil(t, m.mapping("agent1"))
92109
assert.NotNil(t, m.mapping("agent2"))
93110
})
111+
t.Run("Secret is malformed", func(t *testing.T) {
112+
old := &v1.Secret{
113+
ObjectMeta: metav1.ObjectMeta{
114+
Labels: map[string]string{
115+
LabelKeyClusterAgentMapping: "agent1",
116+
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
117+
},
118+
Name: "cluster1",
119+
Namespace: "argocd",
120+
},
121+
Data: map[string][]byte{
122+
"name": []byte("cluster1"),
123+
},
124+
}
125+
new := &v1.Secret{
126+
ObjectMeta: metav1.ObjectMeta{
127+
Labels: map[string]string{
128+
LabelKeyClusterAgentMapping: "agent1",
129+
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
130+
},
131+
Name: "cluster1",
132+
Namespace: "argocd",
133+
},
134+
Data: map[string][]byte{
135+
"name": []byte("cluster2"),
136+
},
137+
}
138+
m, err := NewManager(context.TODO(), "argocd", "", "", "", kube.NewFakeKubeClient("argocd"))
139+
require.NoError(t, err)
140+
m.mapCluster("agent1", &v1alpha1.Cluster{Name: "cluster1"})
141+
assert.NotNil(t, m.mapping("agent1"))
142+
// First (successful) update will change the cluster name to "cluster2"
143+
m.onClusterUpdated(old, new)
144+
assert.NotNil(t, m.mapping("agent1"))
145+
assert.Equal(t, "cluster2", m.mapping("agent1").Name)
146+
old = new.DeepCopy()
147+
// Inject some invalid data to the new secret to trigger an error
148+
new.Data["name"] = []byte("cluster3")
149+
new.Data["config"] = []byte("invalid json")
150+
// Second (unsuccessful) update will not change the cluster name
151+
m.onClusterUpdated(old, new)
152+
assert.NotNil(t, m.mapping("agent1"))
153+
assert.Equal(t, "cluster2", m.mapping("agent1").Name)
154+
})
94155

95156
t.Run("Can't remap to an agent that has a mapping already", func(t *testing.T) {
96157
old := &v1.Secret{

0 commit comments

Comments
 (0)