s3: Read S3 secrets from live hub cluster instead of gathered data#382
Merged
nirs merged 8 commits intoRamenDR:mainfrom Feb 17, 2026
Merged
s3: Read S3 secrets from live hub cluster instead of gathered data#382nirs merged 8 commits intoRamenDR:mainfrom
nirs merged 8 commits intoRamenDR:mainfrom
Conversation
ea99cfc to
ad17c7b
Compare
ad17c7b to
f83649e
Compare
f83649e to
2182b14
Compare
Member
Author
|
Addressed the changes as discussed, updated description with test results. |
2182b14 to
e2ec36a
Compare
Member
Author
|
Updates:
|
nirs
reviewed
Feb 12, 2026
e2ec36a to
fa8fb2e
Compare
fa8fb2e to
0232bc4
Compare
nirs
reviewed
Feb 16, 2026
nirs
reviewed
Feb 16, 2026
Member
There was a problem hiding this comment.
Suggested changes:
- rename helper secret value so we don't trigger gosec and it is clear that we don't keep secrets in the code
- use []byte for secrets read from k8s secrets, matching the real value
- rename Profile secrets fields to match the AWS names for clarity
- remove unneeded Wrong helper constants
- unify invalid/empty secrets tests
diff --git a/pkg/gather/command_test.go b/pkg/gather/command_test.go
index cefe5c0..e1dadd9 100644
--- a/pkg/gather/command_test.go
+++ b/pkg/gather/command_test.go
@@ -106,12 +106,12 @@ var (
},
}
- getSecretEmpty = &validation.Mock{
+ getSecretInvalid = &validation.Mock{
GetSecretFunc: func(ctx validation.Context, cluster *types.Cluster, name, namespace string) (*corev1.Secret, error) {
return &corev1.Secret{
Data: map[string][]byte{
- "AWS_ACCESS_KEY_ID": []byte(helpers.WrongAccessKey),
- "AWS_SECRET_ACCESS_KEY": []byte(helpers.WrongSecretKey),
+ "AWS_ACCESS_KEY_ID": []byte("invalid id"),
+ "AWS_SECRET_ACCESS_KEY": []byte("invalid key"),
},
}, nil
},
@@ -357,8 +357,8 @@ func TestGatherApplicationGetSecretFailed(t *testing.T) {
checkItems(t, cmd.report.Steps[1], items)
}
-func TestGatherApplicationGetSecretEmpty(t *testing.T) {
- cmd := testCommand(t, getSecretEmpty)
+func TestGatherApplicationGetSecretInvalid(t *testing.T) {
+ cmd := testCommand(t, getSecretInvalid)
helpers.AddGatheredData(t, cmd.dataDir(), "appset-deploy-rbd", "validate-application")
if err := cmd.Application(drpcName, drpcNamespace); err == nil {
t.Fatal("command did not fail")
@@ -372,8 +372,8 @@ func TestGatherApplicationGetSecretEmpty(t *testing.T) {
checkStep(t, cmd.report.Steps[0], "validate config", report.Passed)
checkStep(t, cmd.report.Steps[1], "gather data", report.Failed)
- // When GetSecret returns a secret with no data. The profile will have empty
- // credentials causing S3 gather to fail.
+ // When GetSecret returns a secret with invalid value, causing S3 gather to
+ // fail.
items := []*report.Step{
{Name: "inspect application", Status: report.Passed},
{Name: "gather \"hub\"", Status: report.Passed},
diff --git a/pkg/helpers/helpers.go b/pkg/helpers/helpers.go
index 882abaa..19cfd3d 100644
--- a/pkg/helpers/helpers.go
+++ b/pkg/helpers/helpers.go
@@ -19,21 +19,13 @@ import (
const (
Modified = "modified"
- // Base64 decoded secret values from testdata.
- // Both K8s and OCP testdata secrets use the same values.
- AccessKey = "this is not a real secret"
- //nolint:gosec
- SecretKey = "this is not a real key"
+ // Secrets from test testdata. Both k8s and ocp use the same values.
- // Invalid credentials for testing GetSecret failure scenarios.
- WrongAccessKey = "wrong-access-key"
- WrongSecretKey = "wrong-secret-key"
+ FakeAWSKeyID = "this is not a real secret"
+ FakeAWSKey = "this is not a real key"
- // Secret key fingerprints (SHA-256 hashes) for testdata.
- // Both K8s and OCP testdata secrets have the same data values.
- AccessKeyFingerprint = "F3:1C:B8:5A:2C:33:BA:C3:57:84:22:D5:11:F5:35:40:FF:A8:6A:34:B8:CD:42:AC:86:65:E2:2B:E1:05:EA:23"
- //nolint:gosec
- SecretKeyFingerprint = "BC:42:FE:14:DB:F0:91:1C:91:1F:8F:CF:72:AF:CE:C5:83:5C:AF:93:AC:08:40:CE:31:D8:67:CA:AC:BC:E4:16"
+ FakeAWSKeyIDFingerprint = "F3:1C:B8:5A:2C:33:BA:C3:57:84:22:D5:11:F5:35:40:FF:A8:6A:34:B8:CD:42:AC:86:65:E2:2B:E1:05:EA:23"
+ FakeAWSKeyFingerprint = "BC:42:FE:14:DB:F0:91:1C:91:1F:8F:CF:72:AF:CE:C5:83:5C:AF:93:AC:08:40:CE:31:D8:67:CA:AC:BC:E4:16"
)
func MarshalYAML(t *testing.T, a any) string {
diff --git a/pkg/ramen/ramen.go b/pkg/ramen/ramen.go
index a9c8c28..d0f8472 100644
--- a/pkg/ramen/ramen.go
+++ b/pkg/ramen/ramen.go
@@ -276,19 +276,19 @@ func ClusterProfiles(
// S3ProfileFromStore creates an s3.Profile from a ramen S3StoreProfile and secret.
// If secret is nil, the profile will have empty credentials.
func S3ProfileFromStore(storeProfile *ramenapi.S3StoreProfile, secret *corev1.Secret) *s3.Profile {
- var accessKey, secretKey string
+ var accessKey, secretKey []byte
if secret != nil {
- accessKey = string(secret.Data["AWS_ACCESS_KEY_ID"])
- secretKey = string(secret.Data["AWS_SECRET_ACCESS_KEY"])
+ accessKey = secret.Data["AWS_ACCESS_KEY_ID"]
+ secretKey = secret.Data["AWS_SECRET_ACCESS_KEY"]
}
return &s3.Profile{
- Name: storeProfile.S3ProfileName,
- Bucket: storeProfile.S3Bucket,
- Region: storeProfile.S3Region,
- Endpoint: storeProfile.S3CompatibleEndpoint,
- CACertificate: storeProfile.CACertificates,
- AccessKey: accessKey,
- SecretKey: secretKey,
+ Name: storeProfile.S3ProfileName,
+ Bucket: storeProfile.S3Bucket,
+ Region: storeProfile.S3Region,
+ Endpoint: storeProfile.S3CompatibleEndpoint,
+ CACertificate: storeProfile.CACertificates,
+ AWSAccessKeyID: accessKey,
+ AWSSecretAccessKey: secretKey,
}
}
diff --git a/pkg/report/clusters_test.go b/pkg/report/clusters_test.go
index 90749b2..a6726c3 100644
--- a/pkg/report/clusters_test.go
+++ b/pkg/report/clusters_test.go
@@ -688,11 +688,11 @@ func testClusterStatus() *report.ClustersStatus {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
// CACertificate is optional, empty is OK if hub also has no cert.
@@ -728,11 +728,11 @@ func testClusterStatus() *report.ClustersStatus {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -824,11 +824,11 @@ func testClusterStatus() *report.ClustersStatus {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -863,11 +863,11 @@ func testClusterStatus() *report.ClustersStatus {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -958,11 +958,11 @@ func testClusterStatus() *report.ClustersStatus {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -997,11 +997,11 @@ func testClusterStatus() *report.ClustersStatus {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
diff --git a/pkg/s3/s3.go b/pkg/s3/s3.go
index e43008b..a26c76c 100644
--- a/pkg/s3/s3.go
+++ b/pkg/s3/s3.go
@@ -35,13 +35,13 @@ const (
// Profile contains S3 connection and authentication information.
type Profile struct {
- Name string
- Bucket string
- Region string
- Endpoint string
- CACertificate []byte
- AccessKey string
- SecretKey string
+ Name string
+ Bucket string
+ Region string
+ Endpoint string
+ CACertificate []byte
+ AWSAccessKeyID []byte
+ AWSSecretAccessKey []byte
}
// Result represents the result of gathering from an S3 profile.
@@ -189,11 +189,14 @@ func newObjectStore(
configOptions := []func(*config.LoadOptions) error{
config.WithRegion(profile.Region),
config.WithBaseEndpoint(profile.Endpoint),
- config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(
- profile.AccessKey,
- profile.SecretKey,
- "",
- )),
+ config.WithCredentialsProvider(
+ // AWS credentials are always ASCII text, safe to convert to string.
+ credentials.NewStaticCredentialsProvider(
+ string(profile.AWSAccessKeyID),
+ string(profile.AWSSecretAccessKey),
+ "",
+ ),
+ ),
// Add zap logger to the config to redirect AWS SDK logs.
config.WithLogger(awsSDKLogger(log)),
}
diff --git a/pkg/testing/mock.go b/pkg/testing/mock.go
index 34d17dd..f09d89d 100644
--- a/pkg/testing/mock.go
+++ b/pkg/testing/mock.go
@@ -4,6 +4,7 @@
package testing
import (
+ "bytes"
"errors"
"github.com/ramendr/ramen/e2e/types"
@@ -139,8 +140,8 @@ func (m *Mock) GetSecret(
}
return &corev1.Secret{
Data: map[string][]byte{
- "AWS_ACCESS_KEY_ID": []byte(helpers.AccessKey),
- "AWS_SECRET_ACCESS_KEY": []byte(helpers.SecretKey),
+ "AWS_ACCESS_KEY_ID": []byte(helpers.FakeAWSKeyID),
+ "AWS_SECRET_ACCESS_KEY": []byte(helpers.FakeAWSKey),
},
}, nil
}
@@ -157,7 +158,8 @@ func (m *Mock) GatherS3(
results := make(chan s3.Result, len(profiles))
for _, profile := range profiles {
// Fail if s3 secret credentials don't match expected testdata values.
- if profile.AccessKey != helpers.AccessKey || profile.SecretKey != helpers.SecretKey {
+ if !bytes.Equal(profile.AWSAccessKeyID, []byte(helpers.FakeAWSKeyID)) ||
+ !bytes.Equal(profile.AWSSecretAccessKey, []byte(helpers.FakeAWSKey)) {
results <- s3.Result{ProfileName: profile.Name, Err: errors.New("invalid credentials")}
} else {
results <- s3.Result{ProfileName: profile.Name, Err: nil}
diff --git a/pkg/validate/command_test.go b/pkg/validate/command_test.go
index 051a216..04b73fd 100644
--- a/pkg/validate/command_test.go
+++ b/pkg/validate/command_test.go
@@ -176,8 +176,8 @@ var (
GetSecretFunc: func(ctx validation.Context, cluster *types.Cluster, name, namespace string) (*corev1.Secret, error) {
return &corev1.Secret{
Data: map[string][]byte{
- "AWS_ACCESS_KEY_ID": []byte(helpers.WrongAccessKey),
- "AWS_SECRET_ACCESS_KEY": []byte(helpers.WrongSecretKey),
+ "AWS_ACCESS_KEY_ID": []byte("invalid id"),
+ "AWS_SECRET_ACCESS_KEY": []byte("invalid key"),
},
}, nil
},
@@ -195,8 +195,8 @@ var (
GetSecretFunc: func(ctx validation.Context, cluster *types.Cluster, name, namespace string) (*corev1.Secret, error) {
return &corev1.Secret{
Data: map[string][]byte{
- "AWS_ACCESS_KEY_ID": []byte(helpers.WrongAccessKey),
- "AWS_SECRET_ACCESS_KEY": []byte(helpers.WrongSecretKey),
+ "AWS_ACCESS_KEY_ID": []byte("invalid id"),
+ "AWS_SECRET_ACCESS_KEY": []byte("invalid key"),
},
}, nil
},
@@ -930,11 +930,11 @@ func TestValidateClustersK8s(t *testing.T) {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
// CACertificate is optional, empty is OK if hub also has no cert.
@@ -970,11 +970,11 @@ func TestValidateClustersK8s(t *testing.T) {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -1066,11 +1066,11 @@ func TestValidateClustersK8s(t *testing.T) {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -1105,11 +1105,11 @@ func TestValidateClustersK8s(t *testing.T) {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -1200,11 +1200,11 @@ func TestValidateClustersK8s(t *testing.T) {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -1239,11 +1239,11 @@ func TestValidateClustersK8s(t *testing.T) {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -1497,11 +1497,11 @@ func TestValidateClustersOcp(t *testing.T) {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -1536,11 +1536,11 @@ func TestValidateClustersOcp(t *testing.T) {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -1632,11 +1632,11 @@ func TestValidateClustersOcp(t *testing.T) {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -1671,11 +1671,11 @@ func TestValidateClustersOcp(t *testing.T) {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -1766,11 +1766,11 @@ func TestValidateClustersOcp(t *testing.T) {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
@@ -1805,11 +1805,11 @@ func TestValidateClustersOcp(t *testing.T) {
},
AWSAccessKeyID: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.AccessKeyFingerprint,
+ Value: helpers.FakeAWSKeyIDFingerprint,
},
AWSSecretAccessKey: report.ValidatedFingerprint{
Validated: report.Validated{State: report.OK},
- Value: helpers.SecretKeyFingerprint,
+ Value: helpers.FakeAWSKeyFingerprint,
},
},
CACertificate: report.ValidatedFingerprint{
diff --git a/pkg/validation/mock.go b/pkg/validation/mock.go
index 04e2474..fb17bee 100644
--- a/pkg/validation/mock.go
+++ b/pkg/validation/mock.go
@@ -4,6 +4,7 @@
package validation
import (
+ "bytes"
"errors"
"github.com/ramendr/ramen/e2e/types"
@@ -73,8 +74,8 @@ func (m *Mock) GetSecret(
}
return &corev1.Secret{
Data: map[string][]byte{
- "AWS_ACCESS_KEY_ID": []byte(helpers.AccessKey),
- "AWS_SECRET_ACCESS_KEY": []byte(helpers.SecretKey),
+ "AWS_ACCESS_KEY_ID": []byte(helpers.FakeAWSKeyID),
+ "AWS_SECRET_ACCESS_KEY": []byte(helpers.FakeAWSKey),
},
}, nil
}
@@ -91,7 +92,8 @@ func (m *Mock) GatherS3(
results := make(chan s3.Result, len(profiles))
for _, profile := range profiles {
// Fail if s3 secret credentials don't match expected testdata values.
- if profile.AccessKey != helpers.AccessKey || profile.SecretKey != helpers.SecretKey {
+ if !bytes.Equal(profile.AWSAccessKeyID, []byte(helpers.FakeAWSKeyID)) ||
+ !bytes.Equal(profile.AWSSecretAccessKey, []byte(helpers.FakeAWSKey)) {
results <- s3.Result{ProfileName: profile.Name, Err: errors.New("invalid credentials")}
} else {
results <- s3.Result{ProfileName: profile.Name, Err: nil}
@@ -108,7 +110,8 @@ func (m *Mock) CheckS3(ctx Context, profiles []*s3.Profile) <-chan s3.Result {
results := make(chan s3.Result, len(profiles))
for _, profile := range profiles {
// Fail if s3 secret credentials don't match expected testdata values.
- if profile.AccessKey != helpers.AccessKey || profile.SecretKey != helpers.SecretKey {
+ if !bytes.Equal(profile.AWSAccessKeyID, []byte(helpers.FakeAWSKeyID)) ||
+ !bytes.Equal(profile.AWSSecretAccessKey, []byte(helpers.FakeAWSKey)) {
results <- s3.Result{ProfileName: profile.Name, Err: errors.New("invalid credentials")}
} else {
results <- s3.Result{ProfileName: profile.Name, Err: nil}Rename AccessKey and SecretKey to AWSAccessKeyID and AWSSecretAccessKey to match AWS naming conventions. Change credentials type from string to []byte to match the K8s secret data type, avoiding unnecessary conversions. Convert to string only when passing to the AWS SDK. Signed-off-by: Parikshith <parikshithb@gmail.com>
Add GetSecret method to fetch S3 secrets from live cluster. Default mock returns testdata credentials, allowing S3 operations to validate credentials and fail when missing or invalid. Signed-off-by: Parikshith <parikshithb@gmail.com>
Rename AccessKeyFingerprint and SecretKeyFingerprint to FakeAWSKeyIDFingerprint and FakeAWSKeyFingerprint Signed-off-by: Parikshith <parikshithb@gmail.com>
Move console.Step to start of function and add console.Error messages for failures. Change log levels from Warn to Error. Signed-off-by: Parikshith <parikshithb@gmail.com>
With secret sanitization (RamenDR#374), gathered secrets will contain hashes instead of actual credentials, breaking S3 operations. - Add GetSecret to backend interfaces to fetch secrets from live cluster - Update ClusterProfiles to return ramenapi.S3StoreProfile directly - Add S3ProfileFromStore helper to convert profile with credentials - Add cancellation support when fetching S3 secrets Add helper functions for S3 operations: - gatherApplicationS3Data: inspect and gather, stop only on cancellation - checkClustersS3: inspect and check, stop only on cancellation Both helpers return false only on cancellation, allowing validation to continue on other errors and report them in results. This ensures S3 operations (GatherS3, CheckS3) have real credentials even when gathered data contains sanitized secrets. Assisted-by: Cursor/Claude Opus 4.5 Signed-off-by: Parikshith <parikshithb@gmail.com>
Signed-off-by: Parikshith <parikshithb@gmail.com>
Add tests to verify cancellation handling during S3 profile inspection: - TestGatherApplicationInspectS3ProfilesCanceled - TestValidateClustersInspectS3ProfilesCanceled - TestValidateApplicationInspectS3ProfilesCanceled Tests verify that when GetSecret is canceled, the command stops immediately with Canceled status and skips subsequent S3 operations and validation steps. Signed-off-by: Parikshith <parikshithb@gmail.com>
Add tests for missing and empty secret scenarios: - TestGatherApplicationGetSecretFailed - TestGatherApplicationGetSecretInvalid - TestValidateClustersGetSecretFailed - TestValidateClustersGetSecretInvalid - TestValidateApplicationGetSecretFailed - TestValidateApplicationGetSecretInvalid Tests verify that when GetSecret fails or returns invalid data, S3 operations fail due to missing/invalid credentials. Signed-off-by: Parikshith <parikshithb@gmail.com>
0232bc4 to
e160cfb
Compare
nirs
approved these changes
Feb 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
With secret sanitization (#374), gathered secrets will contain hashes
instead of actual credentials, breaking S3 operations.
Add helper functions for S3 operations:
Both helpers return false only on cancellation, allowing validation to
continue on other errors and report them in results.
This ensures S3 operations (GatherS3, CheckS3) have real credentials
even when gathered data contains sanitized secrets.
Testing
Pass:
gather application:
validate application:
validate clusters:
Failure:
ramen-s3-secret-dr1secret on hub.gather application:
validate application:
validate clusters:
Gather application
Validate Application
validate clusters:
Log warning:
Fixes #380