From ab43240b4e0d81b6ca511a5841fc6ed850a4ebe3 Mon Sep 17 00:00:00 2001 From: Ben McClelland Date: Mon, 18 Dec 2023 08:28:35 -0800 Subject: [PATCH] fix: add cli options to enable s3 iam service --- auth/iam.go | 14 ++++++++ auth/iam_proxy.go | 38 ++++++++++++++++------ cmd/versitygw/main.go | 75 ++++++++++++++++++++++++++++--------------- 3 files changed, 92 insertions(+), 35 deletions(-) diff --git a/auth/iam.go b/auth/iam.go index 90a0fe1..9b786a7 100644 --- a/auth/iam.go +++ b/auth/iam.go @@ -16,6 +16,7 @@ package auth import ( "errors" + "fmt" "time" ) @@ -52,6 +53,11 @@ type Opts struct { LDAPAccessAtr string LDAPSecretAtr string LDAPRoleAtr string + S3Access string + S3Secret string + S3Region string + S3Bucket string + S3Endpoint string CacheDisable bool CacheTTL int CachePrune int @@ -64,12 +70,20 @@ func New(o *Opts) (IAMService, error) { switch { case o.Dir != "": svc, err = NewInternal(o.Dir) + fmt.Printf("initializing internal IAM with %q\n", o.Dir) case o.LDAPServerURL != "": svc, err = NewLDAPService(o.LDAPServerURL, o.LDAPBindDN, o.LDAPPassword, o.LDAPQueryBase, o.LDAPAccessAtr, o.LDAPSecretAtr, o.LDAPRoleAtr, o.LDAPObjClasses) + fmt.Printf("initializing LDAP IAM with %q\n", o.LDAPServerURL) + case o.S3Endpoint != "": + svc, err = NewS3(o.S3Access, o.S3Secret, o.S3Region, o.S3Bucket, + o.S3Endpoint) + fmt.Printf("initializing S3 IAM with '%v/%v'\n", + o.S3Endpoint, o.S3Bucket) default: // if no iam options selected, default to the single user mode + fmt.Println("No IAM service configured, enabling single account mode") return IAMServiceSingle{}, nil } diff --git a/auth/iam_proxy.go b/auth/iam_proxy.go index 83ca8a1..5cf0eec 100644 --- a/auth/iam_proxy.go +++ b/auth/iam_proxy.go @@ -28,25 +28,43 @@ import ( v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" ) -type IAMServiceProxy struct { +type IAMServiceS3 struct { access string secret string region string + bucket string endpoint string } -var _ IAMService = &IAMServiceProxy{} +var _ IAMService = &IAMServiceS3{} -func NewProxy(access, secret, region, endpoint string) IAMService { - return &IAMServiceProxy{ +func NewS3(access, secret, region, bucket, endpoint string) (IAMService, error) { + if access == "" { + return nil, fmt.Errorf("must provide s3 IAM service access key") + } + if secret == "" { + return nil, fmt.Errorf("must provide s3 IAM service secret key") + } + if region == "" { + return nil, fmt.Errorf("must provide s3 IAM service region") + } + if bucket == "" { + return nil, fmt.Errorf("must provide s3 IAM service bucket") + } + if endpoint == "" { + return nil, fmt.Errorf("must provide s3 IAM service endpoint") + } + + return &IAMServiceS3{ access: access, secret: secret, region: region, + bucket: bucket, endpoint: endpoint, - } + }, nil } -func (s *IAMServiceProxy) CreateAccount(account Account) error { +func (s *IAMServiceS3) CreateAccount(account Account) error { accJson, err := json.Marshal(account) if err != nil { return fmt.Errorf("failed to parse user data: %w", err) @@ -88,7 +106,7 @@ func (s *IAMServiceProxy) CreateAccount(account Account) error { return nil } -func (s *IAMServiceProxy) GetUserAccount(access string) (Account, error) { +func (s *IAMServiceS3) GetUserAccount(access string) (Account, error) { return Account{ Access: s.access, Secret: s.secret, @@ -96,7 +114,7 @@ func (s *IAMServiceProxy) GetUserAccount(access string) (Account, error) { }, nil } -func (s *IAMServiceProxy) DeleteUserAccount(access string) error { +func (s *IAMServiceS3) DeleteUserAccount(access string) error { req, err := http.NewRequest(http.MethodPatch, fmt.Sprintf("%v/delete-user?access=%v", s.endpoint, access), nil) if err != nil { return fmt.Errorf("failed to send the request: %w", err) @@ -133,7 +151,7 @@ func (s *IAMServiceProxy) DeleteUserAccount(access string) error { return nil } -func (s *IAMServiceProxy) ListUserAccounts() ([]Account, error) { +func (s *IAMServiceS3) ListUserAccounts() ([]Account, error) { req, err := http.NewRequest(http.MethodPatch, fmt.Sprintf("%v/list-users", s.endpoint), nil) if err != nil { return []Account{}, fmt.Errorf("failed to send the request: %w", err) @@ -172,6 +190,6 @@ func (s *IAMServiceProxy) ListUserAccounts() ([]Account, error) { return accs, nil } -func (IAMServiceProxy) Shutdown() error { +func (IAMServiceS3) Shutdown() error { return nil } diff --git a/cmd/versitygw/main.go b/cmd/versitygw/main.go index 33a308c..6b5a71b 100644 --- a/cmd/versitygw/main.go +++ b/cmd/versitygw/main.go @@ -48,6 +48,9 @@ var ( ldapURL, ldapBindDN, ldapPassword string ldapQueryBase, ldapObjClasses string ldapAccessAtr, ldapSecAtr, ldapRoleAtr string + s3IamAccess, s3IamSecret string + s3IamRegion, s3IamBucket string + s3IamEndpoint string iamCacheDisable bool iamCacheTTL int iamCachePrune int @@ -260,6 +263,32 @@ func initFlags() []cli.Flag { Usage: "ldap server user role attribute name", Destination: &ldapRoleAtr, }, + &cli.StringFlag{ + Name: "s3-iam-access", + Usage: "s3 IAM access key", + Destination: &s3IamAccess, + }, + &cli.StringFlag{ + Name: "s3-iam-secret", + Usage: "s3 IAM secret key", + Destination: &s3IamSecret, + }, + &cli.StringFlag{ + Name: "s3-iam-region", + Usage: "s3 IAM region", + Destination: &s3IamRegion, + Value: "us-east-1", + }, + &cli.StringFlag{ + Name: "s3-iam-bucket", + Usage: "s3 IAM bucket", + Destination: &s3IamBucket, + }, + &cli.StringFlag{ + Name: "s3-iam-endpoint", + Usage: "s3 IAM endpoint", + Destination: &s3IamEndpoint, + }, &cli.BoolFlag{ Name: "iam-cache-disable", Usage: "disable local iam cache", @@ -340,31 +369,27 @@ func runGateway(ctx context.Context, be backend.Backend) error { admOpts = append(admOpts, s3api.WithAdminSrvTLS(cert)) } - var iam auth.IAMService - - if s3proxyEndpoint != "" { - rootUserAccess = s3proxyAccess - rootUserSecret = s3proxySecret - iam = auth.NewProxy(s3proxyAccess, s3proxySecret, s3proxyRegion, s3proxyEndpoint) - } else { - var err error - iam, err = auth.New(&auth.Opts{ - Dir: iamDir, - LDAPServerURL: ldapURL, - LDAPBindDN: ldapBindDN, - LDAPPassword: ldapPassword, - LDAPQueryBase: ldapQueryBase, - LDAPObjClasses: ldapObjClasses, - LDAPAccessAtr: ldapAccessAtr, - LDAPSecretAtr: ldapSecAtr, - LDAPRoleAtr: ldapRoleAtr, - CacheDisable: iamCacheDisable, - CacheTTL: iamCacheTTL, - CachePrune: iamCachePrune, - }) - if err != nil { - return fmt.Errorf("setup iam: %w", err) - } + iam, err := auth.New(&auth.Opts{ + Dir: iamDir, + LDAPServerURL: ldapURL, + LDAPBindDN: ldapBindDN, + LDAPPassword: ldapPassword, + LDAPQueryBase: ldapQueryBase, + LDAPObjClasses: ldapObjClasses, + LDAPAccessAtr: ldapAccessAtr, + LDAPSecretAtr: ldapSecAtr, + LDAPRoleAtr: ldapRoleAtr, + S3Access: s3IamAccess, + S3Secret: s3IamSecret, + S3Region: s3IamRegion, + S3Bucket: s3IamBucket, + S3Endpoint: s3IamEndpoint, + CacheDisable: iamCacheDisable, + CacheTTL: iamCacheTTL, + CachePrune: iamCachePrune, + }) + if err != nil { + return fmt.Errorf("setup iam: %w", err) } logger, err := s3log.InitLogger(&s3log.LogConfig{