Skip to content

Commit 989780a

Browse files
feat: allow secrets collector to retreive all key data if specified (#1801)
* allow secrets collector retreival all key data if specified * add new line * remove unneeded comments
1 parent 4281c67 commit 989780a

File tree

10 files changed

+232
-15
lines changed

10 files changed

+232
-15
lines changed

config/crds/troubleshoot.sh_collectors.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17077,6 +17077,8 @@ spec:
1707717077
type: string
1707817078
exclude:
1707917079
type: BoolString
17080+
includeAllData:
17081+
type: boolean
1708017082
includeValue:
1708117083
type: boolean
1708217084
key:

config/crds/troubleshoot.sh_preflights.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18897,6 +18897,8 @@ spec:
1889718897
type: string
1889818898
exclude:
1889918899
type: BoolString
18900+
includeAllData:
18901+
type: boolean
1890018902
includeValue:
1890118903
type: boolean
1890218904
key:

config/crds/troubleshoot.sh_supportbundles.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18928,6 +18928,8 @@ spec:
1892818928
type: string
1892918929
exclude:
1893018930
type: BoolString
18931+
includeAllData:
18932+
type: boolean
1893118933
includeValue:
1893218934
type: boolean
1893318935
key:
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
apiVersion: troubleshoot.sh/v1beta2
2+
kind: SupportBundle
3+
metadata:
4+
name: secret-collector-examples
5+
spec:
6+
collectors:
7+
# Basic secret collection (no key-value data included)
8+
- secret:
9+
collectorName: basic-secret
10+
name: my-app-config
11+
namespace: default
12+
13+
# Collect specific key with value
14+
- secret:
15+
collectorName: specific-key-with-value
16+
name: my-app-config
17+
namespace: default
18+
key: database-password
19+
includeValue: true
20+
21+
# NEW: Collect all key-value pairs from a secret
22+
- secret:
23+
collectorName: all-secret-data
24+
name: my-app-config
25+
namespace: default
26+
includeAllData: true
27+
28+
# NEW: Collect all key-value pairs AND a specific key (combined approach)
29+
- secret:
30+
collectorName: combined-collection
31+
name: my-app-config
32+
namespace: default
33+
key: database-password
34+
includeValue: true
35+
includeAllData: true
36+
37+
# NEW: Collect all secrets matching a selector with all their data
38+
- secret:
39+
collectorName: secrets-by-selector-all-data
40+
namespace: default
41+
selector:
42+
- app=my-app
43+
includeAllData: true
44+
45+
# Collect secrets by selector (traditional approach)
46+
- secret:
47+
collectorName: secrets-by-selector-basic
48+
namespace: default
49+
selector:
50+
- app=my-app

pkg/apis/troubleshoot/v1beta2/collector_shared.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,13 @@ type NodeMetrics struct {
5151
}
5252

5353
type Secret struct {
54-
CollectorMeta `json:",inline" yaml:",inline"`
55-
Name string `json:"name,omitempty" yaml:"name,omitempty"`
56-
Selector []string `json:"selector,omitempty" yaml:"selector,omitempty"`
57-
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
58-
Key string `json:"key,omitempty" yaml:"key,omitempty"`
59-
IncludeValue bool `json:"includeValue,omitempty" yaml:"includeValue,omitempty"`
54+
CollectorMeta `json:",inline" yaml:",inline"`
55+
Name string `json:"name,omitempty" yaml:"name,omitempty"`
56+
Selector []string `json:"selector,omitempty" yaml:"selector,omitempty"`
57+
Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
58+
Key string `json:"key,omitempty" yaml:"key,omitempty"`
59+
IncludeValue bool `json:"includeValue,omitempty" yaml:"includeValue,omitempty"`
60+
IncludeAllData bool `json:"includeAllData,omitempty" yaml:"includeAllData,omitempty"`
6061
}
6162

6263
type ConfigMap struct {

pkg/collect/secret.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ import (
1818
)
1919

2020
type SecretOutput struct {
21-
Namespace string `json:"namespace"`
22-
Name string `json:"name"`
23-
Key string `json:"key"`
24-
SecretExists bool `json:"secretExists"`
25-
KeyExists bool `json:"keyExists"`
26-
Value string `json:"value,omitempty"`
21+
Namespace string `json:"namespace"`
22+
Name string `json:"name"`
23+
Key string `json:"key"`
24+
SecretExists bool `json:"secretExists"`
25+
KeyExists bool `json:"keyExists"`
26+
Value string `json:"value,omitempty"`
27+
Data map[string]string `json:"data,omitempty"`
2728
}
2829

2930
type CollectSecret struct {
@@ -93,7 +94,13 @@ func secretToOutput(secretCollector *troubleshootv1beta2.Secret, secret *corev1.
9394

9495
if secret != nil {
9596
foundSecret.SecretExists = true
96-
if secretCollector.Key != "" {
97+
98+
if secretCollector.IncludeAllData {
99+
foundSecret.Data = make(map[string]string)
100+
for k, v := range secret.Data {
101+
foundSecret.Data[k] = string(v)
102+
}
103+
} else if secretCollector.Key != "" {
97104
if val, ok := secret.Data[secretCollector.Key]; ok {
98105
foundSecret.KeyExists = true
99106
if secretCollector.IncludeValue {
@@ -134,7 +141,8 @@ func marshalSecretOutput(secretCollector *troubleshootv1beta2.Secret, secret Sec
134141

135142
func GetSecretFileName(secretCollector *troubleshootv1beta2.Secret, name string) string {
136143
parts := []string{"secrets", secretCollector.Namespace, name}
137-
if secretCollector.Key != "" {
144+
// Only include key in filename when doing key-specific processing
145+
if secretCollector.Key != "" && !secretCollector.IncludeAllData {
138146
parts = append(parts, secretCollector.Key)
139147
}
140148
return fmt.Sprintf("%s.json", filepath.Join(parts...))
@@ -147,7 +155,8 @@ func GetSecretErrorsFileName(secretCollector *troubleshootv1beta2.Secret) string
147155
} else {
148156
parts = append(parts, selectorToString(secretCollector.Selector))
149157
}
150-
if secretCollector.Key != "" {
158+
// Only include key in filename when doing key-specific processing
159+
if secretCollector.Key != "" && !secretCollector.IncludeAllData {
151160
parts = append(parts, secretCollector.Key)
152161
}
153162
return fmt.Sprintf("%s.json", filepath.Join(parts...))

pkg/collect/secret_test.go

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,148 @@ func TestSecret(t *testing.T) {
209209
}),
210210
},
211211
},
212+
{
213+
name: "with includeAllData",
214+
secretCollector: &troubleshootv1beta2.Secret{
215+
Namespace: "test-namespace",
216+
Name: "test-secret",
217+
IncludeAllData: true,
218+
},
219+
mockSecrets: []corev1.Secret{
220+
{
221+
ObjectMeta: metav1.ObjectMeta{
222+
Name: "test-secret",
223+
Namespace: "test-namespace",
224+
},
225+
Data: map[string][]byte{
226+
"database-password": []byte("secret123"),
227+
"api-key": []byte("abc123xyz"),
228+
"jwt-secret": []byte("mysupersecret"),
229+
},
230+
},
231+
},
232+
want: CollectorResult{
233+
"secrets/test-namespace/test-secret.json": mustJSONMarshalIndent(t, SecretOutput{
234+
Namespace: "test-namespace",
235+
Name: "test-secret",
236+
SecretExists: true,
237+
Data: map[string]string{
238+
"database-password": "secret123",
239+
"api-key": "abc123xyz",
240+
"jwt-secret": "mysupersecret",
241+
},
242+
}),
243+
},
244+
},
245+
{
246+
name: "with includeAllData and specific key",
247+
secretCollector: &troubleshootv1beta2.Secret{
248+
Namespace: "test-namespace",
249+
Name: "test-secret",
250+
Key: "database-password",
251+
IncludeValue: true,
252+
IncludeAllData: true,
253+
},
254+
mockSecrets: []corev1.Secret{
255+
{
256+
ObjectMeta: metav1.ObjectMeta{
257+
Name: "test-secret",
258+
Namespace: "test-namespace",
259+
},
260+
Data: map[string][]byte{
261+
"database-password": []byte("secret123"),
262+
"api-key": []byte("abc123xyz"),
263+
"jwt-secret": []byte("mysupersecret"),
264+
},
265+
},
266+
},
267+
want: CollectorResult{
268+
"secrets/test-namespace/test-secret.json": mustJSONMarshalIndent(t, SecretOutput{
269+
Namespace: "test-namespace",
270+
Name: "test-secret",
271+
Key: "database-password",
272+
SecretExists: true,
273+
Data: map[string]string{
274+
"database-password": "secret123",
275+
"api-key": "abc123xyz",
276+
"jwt-secret": "mysupersecret",
277+
},
278+
}),
279+
},
280+
},
281+
{
282+
name: "with includeAllData secret not found",
283+
secretCollector: &troubleshootv1beta2.Secret{
284+
Namespace: "test-namespace",
285+
Name: "test-secret",
286+
IncludeAllData: true,
287+
},
288+
mockSecrets: []corev1.Secret{
289+
{
290+
ObjectMeta: metav1.ObjectMeta{
291+
Name: "other-secret",
292+
Namespace: "test-namespace",
293+
},
294+
Data: map[string][]byte{
295+
"test-key": []byte("test-value"),
296+
},
297+
},
298+
},
299+
want: CollectorResult{
300+
"secrets/test-namespace/test-secret.json": mustJSONMarshalIndent(t, SecretOutput{
301+
Namespace: "test-namespace",
302+
Name: "test-secret",
303+
SecretExists: false,
304+
}),
305+
"secrets-errors/test-namespace/test-secret.json": mustJSONMarshalIndent(t, []string{
306+
`secrets "test-secret" not found`,
307+
}),
308+
},
309+
},
310+
{
311+
name: "with includeAllData by selector",
312+
secretCollector: &troubleshootv1beta2.Secret{
313+
Namespace: "test-namespace",
314+
Selector: []string{
315+
"app=my-app",
316+
},
317+
IncludeAllData: true,
318+
},
319+
mockSecrets: []corev1.Secret{
320+
{
321+
ObjectMeta: metav1.ObjectMeta{
322+
Name: "test-secret",
323+
Namespace: "test-namespace",
324+
Labels: map[string]string{"app": "my-app"},
325+
},
326+
Data: map[string][]byte{
327+
"database-password": []byte("secret123"),
328+
"api-key": []byte("abc123xyz"),
329+
},
330+
},
331+
{
332+
ObjectMeta: metav1.ObjectMeta{
333+
Name: "other-secret",
334+
Namespace: "test-namespace",
335+
Labels: map[string]string{"app": "not-my-app"},
336+
},
337+
Data: map[string][]byte{
338+
"test-key": []byte("test-value"),
339+
},
340+
},
341+
},
342+
want: CollectorResult{
343+
"secrets/test-namespace/test-secret.json": mustJSONMarshalIndent(t, SecretOutput{
344+
Namespace: "test-namespace",
345+
Name: "test-secret",
346+
SecretExists: true,
347+
Data: map[string]string{
348+
"database-password": "secret123",
349+
"api-key": "abc123xyz",
350+
},
351+
}),
352+
},
353+
},
212354
}
213355
for _, tt := range tests {
214356
t.Run(tt.name, func(t *testing.T) {

schemas/collector-troubleshoot-v1beta2.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14527,6 +14527,9 @@
1452714527
"exclude": {
1452814528
"oneOf": [{"type": "string"},{"type": "boolean"}]
1452914529
},
14530+
"includeAllData": {
14531+
"type": "boolean"
14532+
},
1453014533
"includeValue": {
1453114534
"type": "boolean"
1453214535
},

schemas/preflight-troubleshoot-v1beta2.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17313,6 +17313,9 @@
1731317313
"exclude": {
1731417314
"oneOf": [{"type": "string"},{"type": "boolean"}]
1731517315
},
17316+
"includeAllData": {
17317+
"type": "boolean"
17318+
},
1731617319
"includeValue": {
1731717320
"type": "boolean"
1731817321
},

schemas/supportbundle-troubleshoot-v1beta2.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17359,6 +17359,9 @@
1735917359
"exclude": {
1736017360
"oneOf": [{"type": "string"},{"type": "boolean"}]
1736117361
},
17362+
"includeAllData": {
17363+
"type": "boolean"
17364+
},
1736217365
"includeValue": {
1736317366
"type": "boolean"
1736417367
},

0 commit comments

Comments
 (0)