diff --git a/go.mod b/go.mod index cfc98611..135936ab 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.4.0 github.com/aerospike/aerospike-client-go/v7 v7.7.1 github.com/aerospike/aerospike-management-lib v1.4.0 - github.com/aerospike/backup-go v0.1.1-0.20241006123116-14f2a563c203 + github.com/aerospike/backup-go v0.1.1-0.20241031111119-3282f3101763 github.com/aws/aws-sdk-go-v2/config v1.27.41 github.com/aws/aws-sdk-go-v2/service/s3 v1.65.0 github.com/aws/smithy-go v1.22.0 diff --git a/go.sum b/go.sum index f695d43e..916b9de8 100644 --- a/go.sum +++ b/go.sum @@ -48,8 +48,8 @@ github.com/aerospike/aerospike-client-go/v7 v7.7.1 h1:lcskBtPZYe6ESObhIEQEp4XO1a github.com/aerospike/aerospike-client-go/v7 v7.7.1/go.mod h1:STlBtOkKT8nmp7iD+sEkr/JGEOu+4e2jGlNN0Jiu2a4= github.com/aerospike/aerospike-management-lib v1.4.0 h1:wT0l3kwzXv5DV5Cd+hD0BQq3hjSIyaPX1HaUb1304TI= github.com/aerospike/aerospike-management-lib v1.4.0/go.mod h1:3JKrmC/mLSV8SygbrPQPNV8T7bFaTMjB8wfnX25gB+4= -github.com/aerospike/backup-go v0.1.1-0.20241006123116-14f2a563c203 h1:A5JHqEiE6M+lU+B5/8fdBRKeVCyBrDJ19YRJ96TGmZo= -github.com/aerospike/backup-go v0.1.1-0.20241006123116-14f2a563c203/go.mod h1:UbeAI+l58yuq/oGBCjKNhd3dGRMX/w9hnUyFUZBPUcs= +github.com/aerospike/backup-go v0.1.1-0.20241031111119-3282f3101763 h1:dEGZqAqtKzMqztvnKNYhO0d4sNsvZ9gJfQuowk2p40M= +github.com/aerospike/backup-go v0.1.1-0.20241031111119-3282f3101763/go.mod h1:UbeAI+l58yuq/oGBCjKNhd3dGRMX/w9hnUyFUZBPUcs= github.com/aws/aws-sdk-go-v2 v1.32.0 h1:GuHp7GvMN74PXD5C97KT5D87UhIy4bQPkflQKbfkndg= github.com/aws/aws-sdk-go-v2 v1.32.0/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0= diff --git a/pkg/model/aerospike_cluster.go b/pkg/model/aerospike_cluster.go index f5e5abae..efe56f8c 100644 --- a/pkg/model/aerospike_cluster.go +++ b/pkg/model/aerospike_cluster.go @@ -7,6 +7,7 @@ import ( "encoding/pem" "errors" "fmt" + "github.com/aerospike/backup-go" "log/slog" "os" "strings" @@ -53,21 +54,45 @@ func (c *AerospikeCluster) GetUser() *string { return nil } -// GetPassword tries to read and set the password once from PasswordPath, if it exists. -// Returns the password value. If it failed to read password, it will return nil +// GetPassword tries to read and set the password once from the configured source. +// Returns the password value. If it fails to read the password, it will return nil // and try to read again next time. func (c *AerospikeCluster) GetPassword() *string { if password := c.pwd.Load(); password != nil { return password } - if c.Credentials != nil && c.Credentials.Password != nil { - c.pwd.Store(c.Credentials.Password) + if c.Credentials == nil { + return nil + } + + password := c.loadPassword() + if password != nil { + c.pwd.Store(password) + } + + return password +} + +func (c *AerospikeCluster) loadPassword() *string { + if c.Credentials.Password != nil { return c.Credentials.Password } - if c.Credentials == nil || c.Credentials.PasswordPath == nil { - slog.Warn("No credentials provided to read password") + if password := c.loadPasswordFromFile(); password != nil { + return password + } + + if password := c.loadSecretAgentPassword(); password != nil { + return password + } + + slog.Warn("No valid authentication method configured") + return nil +} + +func (c *AerospikeCluster) loadPasswordFromFile() *string { + if c.Credentials.PasswordPath == nil { return nil } @@ -79,10 +104,29 @@ func (c *AerospikeCluster) GetPassword() *string { slog.Debug("Successfully read password", "path", *c.Credentials.PasswordPath) password := string(data) - c.pwd.Store(&password) return &password } +func (c *AerospikeCluster) loadSecretAgentPassword() *string { + if c.Credentials.SecretAgent == nil || c.Credentials.KeySecret == nil { + return nil + } + + password, err := getPasswordFromSecretAgent(c.Credentials.SecretAgent, c.Credentials.KeySecret) + if err != nil { + slog.Error("Failed to get password from secret agent", + "agent", *c.Credentials.SecretAgent, + "err", err) + return nil + } + + return &password +} + +func getPasswordFromSecretAgent(agent *SecretAgent, secret *string) (string, error) { + return backup.ParseSecret(agent.ToSecretAgentConfig(), *secret) +} + // GetAuthMode safely returns the authentication mode. func (c *AerospikeCluster) GetAuthMode() *string { if c.Credentials != nil { @@ -270,6 +314,10 @@ type Credentials struct { PasswordPath *string // The authentication mode string (INTERNAL, EXTERNAL, EXTERNAL_INSECURE, PKI). AuthMode *string + // The name of the configured Secret Agent to use for authentication + SecretAgent *SecretAgent + // The key to retrieve from the Secret Agent + KeySecret *string } // SeedNode represents details of a node in the Aerospike cluster. diff --git a/pkg/model/secret_agent.go b/pkg/model/secret_agent.go index 053a155d..8e0f748d 100644 --- a/pkg/model/secret_agent.go +++ b/pkg/model/secret_agent.go @@ -1,5 +1,7 @@ package model +import "github.com/aerospike/backup-go" + // SecretAgent represents the configuration of an Aerospike Secret Agent // for a backup/restore operation. // Aerospike Secret Agent acts as a proxy layer between Aerospike server and one or more @@ -21,3 +23,18 @@ type SecretAgent struct { // Flag that shows if secret agent responses are encrypted with base64. IsBase64 *bool } + +func (s *SecretAgent) ToSecretAgentConfig() *backup.SecretAgentConfig { + if s == nil { + return nil + } + + return &backup.SecretAgentConfig{ + ConnectionType: s.ConnectionType, + Address: s.Address, + Port: s.Port, + TimeoutMillisecond: s.Timeout, + CaFile: s.TLSCAString, + IsBase64: s.IsBase64, + } +} diff --git a/pkg/service/backup_go.go b/pkg/service/backup_go.go index 371317c2..9725b63b 100644 --- a/pkg/service/backup_go.go +++ b/pkg/service/backup_go.go @@ -41,7 +41,7 @@ func (b *BackupGo) BackupRun( return nil, fmt.Errorf("failed to create backup writer, %w", err) } - handler, err := client.Backup(ctx, config, writerFactory) + handler, err := client.Backup(ctx, config, writerFactory, nil) if err != nil { return nil, fmt.Errorf("failed to start backup, %w", err) } @@ -119,16 +119,7 @@ func makeBackupConfig( } } - if secretAgent != nil { - config.SecretAgentConfig = &backup.SecretAgentConfig{ - ConnectionType: secretAgent.ConnectionType, - Address: secretAgent.Address, - Port: secretAgent.Port, - TimeoutMillisecond: secretAgent.Timeout, - CaFile: secretAgent.TLSCAString, - IsBase64: secretAgent.IsBase64, - } - } + config.SecretAgentConfig = secretAgent.ToSecretAgentConfig() return config } diff --git a/pkg/service/client_manager.go b/pkg/service/client_manager.go index 95fee9df..d1851586 100644 --- a/pkg/service/client_manager.go +++ b/pkg/service/client_manager.go @@ -52,7 +52,7 @@ func (f *DefaultClientFactory) IsClusterHealthy(client backup.AerospikeClient) b return false } - info, err := node.RequestInfo(nil, "status") + info, err := node.RequestInfo(client.GetDefaultInfoPolicy(), "status") return err == nil && info["status"] == "ok" }