Skip to content

Commit

Permalink
Add support for AWS shared credentials file
Browse files Browse the repository at this point in the history
Also adds a CLI flag and fields for session token, which must be passed
alongside the access key and secret when using temporary credentials.

Signed-off-by: Brad Davidson <[email protected]>
  • Loading branch information
brandond committed Jan 15, 2025
1 parent d0ea741 commit 0de71f5
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 16 deletions.
6 changes: 6 additions & 0 deletions pkg/cli/cmds/etcd_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ var EtcdSnapshotFlags = []cli.Flag{
EnvVar: "AWS_SECRET_ACCESS_KEY",
Destination: &ServerConfig.EtcdS3SecretKey,
},
&cli.StringFlag{
Name: "s3-session-token,etcd-s3-session-token",
Usage: "(db) S3 session token",
EnvVar: "AWS_SESSION_TOKEN",
Destination: &ServerConfig.EtcdS3SessionToken,
},
&cli.StringFlag{
Name: "s3-bucket,etcd-s3-bucket",
Usage: "(db) S3 bucket name",
Expand Down
7 changes: 7 additions & 0 deletions pkg/cli/cmds/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ type Server struct {
EtcdS3SkipSSLVerify bool
EtcdS3AccessKey string
EtcdS3SecretKey string
EtcdS3SessionToken string
EtcdS3BucketName string
EtcdS3Region string
EtcdS3Folder string
Expand Down Expand Up @@ -438,6 +439,12 @@ var ServerFlags = []cli.Flag{
EnvVar: "AWS_SECRET_ACCESS_KEY",
Destination: &ServerConfig.EtcdS3SecretKey,
},
&cli.StringFlag{
Name: "etcd-s3-session-token",
Usage: "(db) S3 session token",
EnvVar: "AWS_SESSION_TOKEN",
Destination: &ServerConfig.EtcdS3SessionToken,
},
&cli.StringFlag{
Name: "etcd-s3-bucket",
Usage: "(db) S3 bucket name",
Expand Down
1 change: 1 addition & 0 deletions pkg/cli/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
Proxy: cfg.EtcdS3Proxy,
Region: cfg.EtcdS3Region,
SecretKey: cfg.EtcdS3SecretKey,
SessionToken: cfg.EtcdS3SessionToken,
SkipSSLVerify: cfg.EtcdS3SkipSSLVerify,
Timeout: metav1.Duration{Duration: cfg.EtcdS3Timeout},
}
Expand Down
1 change: 1 addition & 0 deletions pkg/daemons/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ type EtcdS3 struct {
Proxy string `json:"proxy,omitempty"`
Region string `json:"region,omitempty"`
SecretKey string `json:"secretKey,omitempty"`
SessionToken string `json:"sessionToken,omitempty"`
Insecure bool `json:"insecure,omitempty"`
SkipSSLVerify bool `json:"skipSSLVerify,omitempty"`
Timeout metav1.Duration `json:"timeout,omitempty"`
Expand Down
17 changes: 9 additions & 8 deletions pkg/etcd/s3/config_secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,15 @@ func (c *Controller) getConfigFromSecret(secretName string) (*config.EtcdS3, err
}

etcdS3 := &config.EtcdS3{
AccessKey: string(secret.Data["etcd-s3-access-key"]),
Bucket: string(secret.Data["etcd-s3-bucket"]),
Endpoint: defaultEtcdS3.Endpoint,
Folder: string(secret.Data["etcd-s3-folder"]),
Proxy: string(secret.Data["etcd-s3-proxy"]),
Region: defaultEtcdS3.Region,
SecretKey: string(secret.Data["etcd-s3-secret-key"]),
Timeout: *defaultEtcdS3.Timeout.DeepCopy(),
AccessKey: string(secret.Data["etcd-s3-access-key"]),
Bucket: string(secret.Data["etcd-s3-bucket"]),
Endpoint: defaultEtcdS3.Endpoint,
Folder: string(secret.Data["etcd-s3-folder"]),
Proxy: string(secret.Data["etcd-s3-proxy"]),
Region: defaultEtcdS3.Region,
SecretKey: string(secret.Data["etcd-s3-secret-key"]),
SessionToken: string(secret.Data["etcd-s3-session-token"]),
Timeout: *defaultEtcdS3.Timeout.DeepCopy(),
}

// Set endpoint from secret if set
Expand Down
25 changes: 17 additions & 8 deletions pkg/etcd/s3/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,14 +199,23 @@ func (c *Controller) GetClient(ctx context.Context, etcdS3 *config.EtcdS3) (*Cli
tr.Proxy = http.ProxyURL(u)
}

var creds *credentials.Credentials
if len(etcdS3.AccessKey) == 0 && len(etcdS3.SecretKey) == 0 {
creds = credentials.NewIAM("") // for running on ec2 instance
if _, err := creds.Get(); err != nil {
return nil, errors.Wrap(err, "failed to get IAM credentials")
}
} else {
creds = credentials.NewStaticV4(etcdS3.AccessKey, etcdS3.SecretKey, "")
creds := credentials.NewChainCredentials([]credentials.Provider{
&credentials.Static{
Value: credentials.Value{
AccessKeyID: etcdS3.AccessKey,
SecretAccessKey: etcdS3.SecretKey,
SessionToken: etcdS3.SessionToken,
SignerType: credentials.SignatureV4,
},
},
&credentials.FileAWSCredentials{},
&credentials.IAM{},
})

if cval, err := creds.Get(); err != nil {
return nil, errors.Wrap(err, "failed to get credentials")
} else if cval.SignerType == credentials.SignatureAnonymous {
return nil, errors.New("all credential providers failed; cannot use anonymous")
}

opt := minio.Options{
Expand Down
1 change: 1 addition & 0 deletions pkg/etcd/snapshot/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type S3Config struct {
// Mask these fields in the embedded struct to avoid serializing their values in the snapshotFile record
AccessKey string `json:"accessKey,omitempty"`
ConfigSecret string `json:"configSecret,omitempty"`
SessionToken string `json:"sessionToken,omitempty"`
Proxy string `json:"proxy,omitempty"`
SecretKey string `json:"secretKey,omitempty"`
Timeout metav1.Duration `json:"timeout,omitempty"`
Expand Down

0 comments on commit 0de71f5

Please sign in to comment.