Skip to content

Commit a81a6d3

Browse files
gl-johnsonGitHub Enterprise
authored andcommitted
Merge pull request #91 from Conjur-Enterprise/allow-empty-secrets
CNJR-12566: Allow empty RequiredK8sSecrets config
2 parents 12c7f0e + 2559bf1 commit a81a6d3

7 files changed

Lines changed: 74 additions & 36 deletions

File tree

bootstrap.env

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export APP_NAMESPACE_NAME=app-$UNIQUE_TEST_ID
2323
# export RUN_IN_DOCKER=false
2424
# export CONJUR_DEPLOYMENT=oss
2525
# export SUMMON_ENV=gke
26-
# export RELOAD_ENV=false
2726
# export STOP_RUNNING_ENV=true
2827
# export CONJUR_ACCOUNT=cucumber
2928
# export CONJUR_LOG_LEVEL=debug

pkg/log/messages/error_messages.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,7 @@ const CSPFK066E string = "CSPFK066E Stopped fetching additional secrets after %d
9595
const CSPFK068E string = "CSPFK068E Retrieved secrets did not include secret '%s' requested by secret group '%s'"
9696

9797
// URL Parsing
98-
const CSPFK069E string = "CSPFK069E Invalid URL format: %s"
98+
const CSPFK069E string = "CSPFK069E Invalid URL format: %s"
99+
100+
// Label-based mode
101+
const CSPFK070E string = "CSPFK070E No labeled secrets were discovered"

pkg/log/messages/info_messages.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ const CSPFK020I string = "CSPFK020I No change in Kubernetes secret, no secrets u
3131
const CSPFK021I string = "CSPFK021I Error fetching Conjur secrets, clearing Kubernetes secrets"
3232
const CSPFK022I string = "CSPFK022I Storing secret with base64 content-type '%s' in destination '%s'"
3333
const CSPFK023I string = "CSPFK023I Retrieving all available secrets from Conjur"
34+
const CSPFK024I string = "CSPFK024I Secrets Provider set to retrieve Kubernetes secrets by label"

pkg/secrets/config/config.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,8 @@ func ValidateSecretsProviderSettings(envAndAnnots map[string]string) ([]error, [
198198
annotK8sSecretsStr := envAndAnnots[k8sSecretsKey]
199199
if storeType == "k8s_secrets" {
200200
if envK8sSecretsStr == "" && annotK8sSecretsStr == "" {
201-
errorList = append(errorList, errors.New(messages.CSPFK048E))
201+
// This is no longer considered an error, but rather a signal to use the label-based K8s Secrets mode
202+
infoList = append(infoList, fmt.Errorf(messages.CSPFK024I))
202203
} else if envK8sSecretsStr != "" && annotK8sSecretsStr != "" {
203204
infoList = append(infoList, fmt.Errorf(messages.CSPFK012I, "RequiredK8sSecrets", "K8S_SECRETS", k8sSecretsKey))
204205
}
@@ -245,7 +246,10 @@ func NewConfig(settings map[string]string) *Config {
245246
} else {
246247
k8sSecretsStr = settings["K8S_SECRETS"]
247248
k8sSecretsStr = strings.ReplaceAll(k8sSecretsStr, " ", "")
248-
k8sSecretsArr = strings.Split(k8sSecretsStr, ",")
249+
// Only split if the string is not empty to avoid creating a slice with one empty element
250+
if k8sSecretsStr != "" {
251+
k8sSecretsArr = strings.Split(k8sSecretsStr, ",")
252+
}
249253
}
250254
}
251255

pkg/secrets/config/config_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -299,21 +299,21 @@ var validateSecretsProviderSettingsTestCases = []validateSecretsProviderSettings
299299
assert: assertErrorInList(fmt.Errorf(messages.CSPFK043E, SecretsDestinationKey, "invalid", []string{File, K8s})),
300300
},
301301
{
302-
description: "if RequiredK8sSecrets is not configured in K8s Secrets mode, an error is returned",
302+
description: "if RequiredK8sSecrets is not configured in K8s Secrets mode, an info-level message is returned (indicating label-based mode)",
303303
envAndAnnots: map[string]string{
304304
"MY_POD_NAMESPACE": "test-namespace",
305305
SecretsDestinationKey: "k8s_secrets",
306306
},
307-
assert: assertErrorInList(errors.New(messages.CSPFK048E)),
307+
assert: assertInfoInList(fmt.Errorf(messages.CSPFK024I)),
308308
},
309309
{
310-
description: "if RequiredK8sSecrets is set to a null string in K8s Secrets mode, an error is returned",
310+
description: "if RequiredK8sSecrets is set to a null string in K8s Secrets mode, an info-level message is returned (indicating label-based mode)",
311311
envAndAnnots: map[string]string{
312312
"MY_POD_NAMESPACE": "test-namespace",
313313
"SECRETS_DESTINATION": "k8s_secrets",
314314
"K8S_SECRETS": "",
315315
},
316-
assert: assertErrorInList(errors.New(messages.CSPFK048E)),
316+
assert: assertInfoInList(fmt.Errorf(messages.CSPFK024I)),
317317
},
318318
{
319319
description: "if envVar 'SECRETS_DESTINATION' is malformed in the absence of annotation 'conjur.org/secrets-destination', an error is returned",

pkg/secrets/k8s_secrets_storage/provide_conjur_secrets.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ func (p *K8sProvider) Provide() (bool, error) {
159159
return false, p.log.recordedError(messages.CSPFK021E)
160160
}
161161

162+
// In label-based mode with no secrets discovered, return gracefully
163+
if len(p.requiredK8sSecrets) == 0 {
164+
p.log.warn(messages.CSPFK070E)
165+
return false, nil
166+
}
167+
162168
// Retrieve Conjur secrets for all K8s Secrets.
163169
var updated bool
164170
retrievedConjurSecrets, err := p.retrieveConjurSecrets(tr)
@@ -219,14 +225,20 @@ func (p *K8sProvider) retrieveRequiredK8sSecrets(tracer trace.Tracer) error {
219225
spanCtx, span := tracer.Start(p.traceContext, "Gather required K8s Secrets")
220226
defer span.End()
221227

222-
for _, k8sSecretName := range p.requiredK8sSecrets {
223-
_, childSpan := tracer.Start(spanCtx, "Retrieve K8s Secret")
224-
defer childSpan.End()
225-
if err := p.retrieveRequiredK8sSecret(k8sSecretName); err != nil {
226-
childSpan.RecordErrorAndSetStatus(err)
227-
span.RecordErrorAndSetStatus(err)
228-
return err
228+
if len(p.requiredK8sSecrets) > 0 {
229+
// Default behavior - pre-configured secrets
230+
for _, k8sSecretName := range p.requiredK8sSecrets {
231+
_, childSpan := tracer.Start(spanCtx, "Retrieve K8s Secret")
232+
defer childSpan.End()
233+
if err := p.retrieveRequiredK8sSecret(k8sSecretName); err != nil {
234+
childSpan.RecordErrorAndSetStatus(err)
235+
span.RecordErrorAndSetStatus(err)
236+
return err
237+
}
229238
}
239+
} else {
240+
// TODO: Check for labeled secrets
241+
return nil
230242
}
231243
return nil
232244
}

pkg/secrets/k8s_secrets_storage/provide_conjur_secrets_test.go

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ func assertErrorLogged(msg string, args ...interface{}) assertFunc {
142142
}
143143
}
144144

145+
func assertNoErrorLogged() assertFunc {
146+
return func(t *testing.T, mocks testMocks, updated bool, err error, desc string) {
147+
// Check that no errors were logged by seeing if ErrorWasLogged returns false for any common error
148+
assert.False(t, mocks.logger.ErrorWasLogged(""), desc+": should have no error logs")
149+
}
150+
}
151+
145152
func assertLogged(expected bool, logLevel string, msg string, args ...interface{}) assertFunc {
146153
return func(t *testing.T, mocks testMocks, updated bool, err error, desc string) {
147154
logStr := fmt.Sprintf(msg, args...)
@@ -814,6 +821,18 @@ func TestProvide(t *testing.T) {
814821
assertErrorContains(fmt.Sprintf(messages.CSPFK034E, "no variables to retrieve"), false),
815822
},
816823
},
824+
{
825+
desc: "Label-based mode with no pre-configured secrets returns gracefully",
826+
k8sSecrets: k8sStorageMocks.K8sSecrets{},
827+
requiredSecrets: []string{},
828+
asserts: []assertFunc{
829+
assertNoErrorLogged(),
830+
func(t *testing.T, mocks testMocks, updated bool, err error, desc string) {
831+
assert.NoError(t, err, desc+": should not error")
832+
assert.False(t, updated, desc+": should not have updates")
833+
},
834+
},
835+
},
817836
}
818837

819838
for _, tc := range testCases {
@@ -1170,28 +1189,28 @@ func TestProvideSanitization(t *testing.T) {
11701189
}
11711190

11721191
func TestBase64PKCS12SecretPreservesTrailingNull(t *testing.T) {
1173-
original := []byte{0xde, 0xad, 0xbe, 0xef, 0x00}
1174-
encoded := make([]byte, base64.StdEncoding.EncodedLen(len(original)))
1175-
base64.StdEncoding.Encode(encoded, original)
1192+
original := []byte{0xde, 0xad, 0xbe, 0xef, 0x00}
1193+
encoded := make([]byte, base64.StdEncoding.EncodedLen(len(original)))
1194+
base64.StdEncoding.Encode(encoded, original)
11761195

1177-
provider := K8sProvider{
1178-
secretsState: k8sSecretsState{
1179-
updateDestinations: map[string][]updateDestination{
1180-
"pkcs12var": {{
1181-
k8sSecretName: "pkcs12secret",
1182-
secretName: "pkcs12file",
1183-
contentType: "base64",
1184-
}},
1185-
},
1186-
},
1187-
}
1196+
provider := K8sProvider{
1197+
secretsState: k8sSecretsState{
1198+
updateDestinations: map[string][]updateDestination{
1199+
"pkcs12var": {{
1200+
k8sSecretName: "pkcs12secret",
1201+
secretName: "pkcs12file",
1202+
contentType: "base64",
1203+
}},
1204+
},
1205+
},
1206+
}
11881207

1189-
conjurSecrets := map[string][]byte{
1190-
"pkcs12var": encoded,
1191-
}
1208+
conjurSecrets := map[string][]byte{
1209+
"pkcs12var": encoded,
1210+
}
11921211

1193-
secretData := provider.createSecretData(conjurSecrets)
1194-
got := secretData["pkcs12secret"]["pkcs12file"]
1212+
secretData := provider.createSecretData(conjurSecrets)
1213+
got := secretData["pkcs12secret"]["pkcs12file"]
11951214

1196-
assert.Equal(t, original, got, "decoded PKCS#12 secret should match original including trailing null bytes")
1197-
}
1215+
assert.Equal(t, original, got, "decoded PKCS#12 secret should match original including trailing null bytes")
1216+
}

0 commit comments

Comments
 (0)