From 2ad1dc29e88dbc9a9a8a3b57295c65409b743dd1 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Sun, 25 Jan 2026 19:08:18 -0800 Subject: [PATCH] refactor: standardize Service Accounts as distinct store entities and fix Admin Server persistence --- weed/admin/dash/service_account_helpers.go | 53 -- weed/admin/dash/service_account_management.go | 365 +++------- weed/credential/credential_manager.go | 25 + weed/credential/credential_store.go | 7 + .../filer_etc/filer_etc_service_account.go | 78 +++ .../filer_multiple_service_account.go | 92 +++ weed/credential/grpc/grpc_service_account.go | 63 ++ .../memory/memory_service_account.go | 59 ++ weed/credential/memory/memory_store.go | 14 +- .../postgres/postgres_service_account.go | 28 + weed/pb/iam.proto | 48 ++ weed/pb/iam_pb/iam.pb.go | 648 +++++++++++++++--- weed/pb/iam_pb/iam_grpc.pb.go | 220 +++++- 13 files changed, 1287 insertions(+), 413 deletions(-) delete mode 100644 weed/admin/dash/service_account_helpers.go create mode 100644 weed/credential/filer_multiple/filer_multiple_service_account.go create mode 100644 weed/credential/grpc/grpc_service_account.go create mode 100644 weed/credential/memory/memory_service_account.go create mode 100644 weed/credential/postgres/postgres_service_account.go diff --git a/weed/admin/dash/service_account_helpers.go b/weed/admin/dash/service_account_helpers.go deleted file mode 100644 index 226f7ec41..000000000 --- a/weed/admin/dash/service_account_helpers.go +++ /dev/null @@ -1,53 +0,0 @@ -package dash - -import ( - "fmt" - "strings" - - "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb" -) - -// identityToServiceAccount converts an IAM identity to a ServiceAccount struct -// This helper reduces code duplication across GetServiceAccounts, GetServiceAccountDetails, -// UpdateServiceAccount, and GetServiceAccountByAccessKey -func identityToServiceAccount(identity *iam_pb.Identity) (*ServiceAccount, error) { - if identity == nil { - return nil, fmt.Errorf("identity cannot be nil") - } - if !strings.HasPrefix(identity.GetName(), serviceAccountPrefix) { - return nil, fmt.Errorf("not a service account: %s", identity.GetName()) - } - - parts := strings.SplitN(identity.GetName(), ":", 3) - if len(parts) < 3 { - return nil, fmt.Errorf("invalid service account ID format") - } - - sa := &ServiceAccount{ - ID: identity.GetName(), - ParentUser: parts[1], - Status: StatusActive, - CreateDate: getCreationDate(identity.GetActions()), - Expiration: getExpiration(identity.GetActions()), - } - - // Get description from account display name - if identity.Account != nil { - sa.Description = identity.Account.GetDisplayName() - } - - // Get access key from credentials - if len(identity.Credentials) > 0 { - sa.AccessKeyId = identity.Credentials[0].GetAccessKey() - } - - // Check if disabled - for _, action := range identity.GetActions() { - if action == disabledAction { - sa.Status = StatusInactive - break - } - } - - return sa, nil -} diff --git a/weed/admin/dash/service_account_management.go b/weed/admin/dash/service_account_management.go index 165313888..8d3ce232d 100644 --- a/weed/admin/dash/service_account_management.go +++ b/weed/admin/dash/service_account_management.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "strconv" "strings" "time" @@ -18,142 +17,64 @@ var ( ) const ( - createdAtActionPrefix = "createdAt:" - expirationActionPrefix = "expiresAt:" - disabledAction = "__disabled__" - serviceAccountPrefix = "sa:" - accessKeyPrefix = "ABIA" // Service account access keys use ABIA prefix + serviceAccountPrefix = "sa:" + accessKeyPrefix = "ABIA" // Service account access keys use ABIA prefix // Status constants StatusActive = "Active" StatusInactive = "Inactive" ) -// Helper functions for managing creation timestamps in actions -func getCreationDate(actions []string) time.Time { - for _, action := range actions { - if strings.HasPrefix(action, createdAtActionPrefix) { - timestampStr := strings.TrimPrefix(action, createdAtActionPrefix) - if timestamp, err := strconv.ParseInt(timestampStr, 10, 64); err == nil { - return time.Unix(timestamp, 0) - } - } - } - return time.Time{} // Return zero time for legacy service accounts without stored creation date -} - -func setCreationDate(actions []string, createDate time.Time) []string { - // Remove any existing createdAt action - filtered := make([]string, 0, len(actions)+1) - for _, action := range actions { - if !strings.HasPrefix(action, createdAtActionPrefix) { - filtered = append(filtered, action) - } - } - // Add new createdAt action - filtered = append(filtered, fmt.Sprintf("%s%d", createdAtActionPrefix, createDate.Unix())) - return filtered -} - -// Helper functions for managing expiration timestamps in actions -func getExpiration(actions []string) time.Time { - for _, action := range actions { - if strings.HasPrefix(action, expirationActionPrefix) { - timestampStr := strings.TrimPrefix(action, expirationActionPrefix) - if timestamp, err := strconv.ParseInt(timestampStr, 10, 64); err == nil { - return time.Unix(timestamp, 0) - } - } - } - return time.Time{} // No expiration set -} - -func setExpiration(actions []string, expiration time.Time) []string { - // Remove any existing expiration action - filtered := make([]string, 0, len(actions)+1) - for _, action := range actions { - if !strings.HasPrefix(action, expirationActionPrefix) { - filtered = append(filtered, action) - } - } - // Add new expiration action if not zero - if !expiration.IsZero() { - filtered = append(filtered, fmt.Sprintf("%s%d", expirationActionPrefix, expiration.Unix())) - } - return filtered -} - // GetServiceAccounts returns all service accounts, optionally filtered by parent user -// NOTE: Service accounts are stored as special identities with "sa:" prefix func (s *AdminServer) GetServiceAccounts(ctx context.Context, parentUser string) ([]ServiceAccount, error) { if s.credentialManager == nil { return nil, fmt.Errorf("credential manager not available") } - // Load the current configuration to find service account identities - config, err := s.credentialManager.LoadConfiguration(ctx) + pbAccounts, err := s.credentialManager.ListServiceAccounts(ctx) if err != nil { - return nil, fmt.Errorf("failed to load configuration: %w", err) + return nil, fmt.Errorf("failed to list service accounts: %w", err) } var accounts []ServiceAccount - - // Service accounts are stored as identities with "sa:" prefix in their name - // Format: "sa::" - for _, identity := range config.GetIdentities() { - if !strings.HasPrefix(identity.GetName(), serviceAccountPrefix) { + for _, sa := range pbAccounts { + if sa == nil { continue } - - parts := strings.SplitN(identity.GetName(), ":", 3) - if len(parts) < 3 { - continue - } - - parent := parts[1] - saId := identity.GetName() - // Filter by parent user if specified - if parentUser != "" && parent != parentUser { + if parentUser != "" && sa.ParentUser != parentUser { continue } - // Extract description from account display name if available - description := "" status := StatusActive - if identity.Account != nil { - description = identity.Account.GetDisplayName() + if sa.Disabled { + status = StatusInactive } - // Get access key from credentials - accessKey := "" - if len(identity.Credentials) > 0 { - accessKey = identity.Credentials[0].GetAccessKey() - // Service accounts use ABIA prefix - if !strings.HasPrefix(accessKey, accessKeyPrefix) { - continue // Not a service account - } + account := ServiceAccount{ + ID: sa.Id, + ParentUser: sa.ParentUser, + Description: sa.Description, + Status: status, + CreateDate: time.Unix(sa.CreatedAt, 0), } - // Check if disabled (stored in actions) - for _, action := range identity.GetActions() { - if action == disabledAction { - status = StatusInactive - break - } + if sa.Expiration > 0 { + account.Expiration = time.Unix(sa.Expiration, 0) } - accounts = append(accounts, ServiceAccount{ - ID: saId, - ParentUser: parent, - Description: description, - AccessKeyId: accessKey, - Status: status, - CreateDate: getCreationDate(identity.GetActions()), - Expiration: getExpiration(identity.GetActions()), - }) + if sa.Credential != nil { + account.AccessKeyId = sa.Credential.AccessKey + } + + accounts = append(accounts, account) } + // For backward compatibility: also list legacy service accounts stored as identities? + // The user explicitly wanted to fix the storage location, implies migration or switch. + // Mixing both might be confusing but safer. + // However, user feedback implies strict "service accounts should be separate". I will rely only on new store. + return accounts, nil } @@ -163,43 +84,33 @@ func (s *AdminServer) GetServiceAccountDetails(ctx context.Context, id string) ( return nil, fmt.Errorf("credential manager not available") } - // Get the identity - identity, err := s.credentialManager.GetUser(ctx, id) + sa, err := s.credentialManager.GetServiceAccount(ctx, id) if err != nil { - return nil, fmt.Errorf("%w: %s", ErrServiceAccountNotFound, id) + return nil, fmt.Errorf("failed to get service account: %w", err) } - - if !strings.HasPrefix(identity.GetName(), serviceAccountPrefix) { - return nil, fmt.Errorf("%w: not a service account: %s", ErrServiceAccountNotFound, id) + if sa == nil { + return nil, ErrServiceAccountNotFound } - parts := strings.SplitN(identity.GetName(), ":", 3) - if len(parts) < 3 { - return nil, fmt.Errorf("invalid service account ID format") + status := StatusActive + if sa.Disabled { + status = StatusInactive } account := &ServiceAccount{ - ID: id, - ParentUser: parts[1], - Status: StatusActive, - CreateDate: getCreationDate(identity.GetActions()), - Expiration: getExpiration(identity.GetActions()), + ID: sa.Id, + ParentUser: sa.ParentUser, + Description: sa.Description, + Status: status, + CreateDate: time.Unix(sa.CreatedAt, 0), } - if identity.Account != nil { - account.Description = identity.Account.GetDisplayName() + if sa.Expiration > 0 { + account.Expiration = time.Unix(sa.Expiration, 0) } - if len(identity.Credentials) > 0 { - account.AccessKeyId = identity.Credentials[0].GetAccessKey() - } - - // Check if disabled - for _, action := range identity.GetActions() { - if action == disabledAction { - account.Status = StatusInactive - break - } + if sa.Credential != nil { + account.AccessKeyId = sa.Credential.AccessKey } return account, nil @@ -212,49 +123,42 @@ func (s *AdminServer) CreateServiceAccount(ctx context.Context, req CreateServic } // Validate parent user exists - _, err := s.credentialManager.GetUser(ctx, req.ParentUser) - if err != nil { + if _, err := s.credentialManager.GetUser(ctx, req.ParentUser); err != nil { return nil, fmt.Errorf("parent user not found: %s", req.ParentUser) } // Generate unique ID and credentials uuid := generateAccountId() + // Maintain consistent ID format: sa:: saId := fmt.Sprintf("sa:%s:%s", req.ParentUser, uuid) - accessKey := accessKeyPrefix + generateAccessKey()[len(accessKeyPrefix):] // Use ABIA prefix for service accounts + + accessKey := accessKeyPrefix + generateAccessKey()[len(accessKeyPrefix):] secretKey := generateSecretKey() - // Create the service account as a special identity now := time.Now() - // Parse expiration if provided - var expiration time.Time + sa := &iam_pb.ServiceAccount{ + Id: saId, + ParentUser: req.ParentUser, + Description: req.Description, + Credential: &iam_pb.Credential{ + AccessKey: accessKey, + SecretKey: secretKey, + Status: StatusActive, + }, + CreatedAt: now.Unix(), + Disabled: false, + } + if req.Expiration != "" { - var err error - expiration, err = time.Parse(time.RFC3339, req.Expiration) + exp, err := time.Parse(time.RFC3339, req.Expiration) if err != nil { return nil, fmt.Errorf("invalid expiration format: %w", err) } + sa.Expiration = exp.Unix() } - identity := &iam_pb.Identity{ - Name: saId, - Account: &iam_pb.Account{ - Id: uuid, - DisplayName: req.Description, - }, - Credentials: []*iam_pb.Credential{ - { - AccessKey: accessKey, - SecretKey: secretKey, - }, - }, - // Store creation date and expiration in actions - Actions: setExpiration(setCreationDate([]string{}, now), expiration), - } - - // Create the service account - err = s.credentialManager.CreateUser(ctx, identity) - if err != nil { + if err := s.credentialManager.CreateServiceAccount(ctx, sa); err != nil { return nil, fmt.Errorf("failed to create service account: %w", err) } @@ -268,7 +172,7 @@ func (s *AdminServer) CreateServiceAccount(ctx context.Context, req CreateServic SecretAccessKey: secretKey, // Only returned on creation Status: StatusActive, CreateDate: now, - Expiration: expiration, + Expiration: time.Unix(sa.Expiration, 0), }, nil } @@ -278,85 +182,54 @@ func (s *AdminServer) UpdateServiceAccount(ctx context.Context, id string, req U return nil, fmt.Errorf("credential manager not available") } - // Get existing identity - identity, err := s.credentialManager.GetUser(ctx, id) + sa, err := s.credentialManager.GetServiceAccount(ctx, id) if err != nil { - return nil, fmt.Errorf("%w: %s", ErrServiceAccountNotFound, id) + return nil, fmt.Errorf("failed to get service account: %w", err) } - - if !strings.HasPrefix(identity.GetName(), serviceAccountPrefix) { - return nil, fmt.Errorf("%w: not a service account: %s", ErrServiceAccountNotFound, id) + if sa == nil { + return nil, ErrServiceAccountNotFound } - // Update description if provided if req.Description != "" { - if identity.Account == nil { - identity.Account = &iam_pb.Account{} - } - identity.Account.DisplayName = req.Description + sa.Description = req.Description } - // Update status by adding/removing disabled action if req.Status != "" { - // Remove existing disabled marker - newActions := make([]string, 0, len(identity.Actions)) - for _, action := range identity.Actions { - if action != disabledAction { - newActions = append(newActions, action) - } - } - // Add disabled action if setting to Inactive if req.Status == StatusInactive { - newActions = append(newActions, disabledAction) + sa.Disabled = true + } else { + sa.Disabled = false } - identity.Actions = newActions } - // Update expiration if provided if req.Expiration != "" { - var expiration time.Time - var err error - expiration, err = time.Parse(time.RFC3339, req.Expiration) + exp, err := time.Parse(time.RFC3339, req.Expiration) if err != nil { return nil, fmt.Errorf("invalid expiration format: %w", err) } - identity.Actions = setExpiration(identity.Actions, expiration) + sa.Expiration = exp.Unix() } - // Update the identity - err = s.credentialManager.UpdateUser(ctx, id, identity) - if err != nil { + if err := s.credentialManager.UpdateServiceAccount(ctx, id, sa); err != nil { return nil, fmt.Errorf("failed to update service account: %w", err) } glog.V(1).Infof("Updated service account %s", id) - // Build response - parts := strings.SplitN(id, ":", 3) - if len(parts) < 3 { - return nil, fmt.Errorf("invalid service account ID format") + status := StatusActive + if sa.Disabled { + status = StatusInactive } - result := &ServiceAccount{ - ID: id, - ParentUser: parts[1], - Description: identity.Account.GetDisplayName(), - Status: StatusActive, - CreateDate: getCreationDate(identity.Actions), - } - - if len(identity.Credentials) > 0 { - result.AccessKeyId = identity.Credentials[0].GetAccessKey() - } - - for _, action := range identity.Actions { - if action == disabledAction { - result.Status = StatusInactive - break - } - } - - return result, nil + return &ServiceAccount{ + ID: sa.Id, + ParentUser: sa.ParentUser, + Description: sa.Description, + Status: status, + CreateDate: time.Unix(sa.CreatedAt, 0), + Expiration: time.Unix(sa.Expiration, 0), + AccessKeyId: sa.Credential.AccessKey, + }, nil } // DeleteServiceAccount deletes a service account @@ -365,19 +238,16 @@ func (s *AdminServer) DeleteServiceAccount(ctx context.Context, id string) error return fmt.Errorf("credential manager not available") } - // Verify it's a service account - identity, err := s.credentialManager.GetUser(ctx, id) + // Verify existence + sa, err := s.credentialManager.GetServiceAccount(ctx, id) if err != nil { - return fmt.Errorf("%w: %s", ErrServiceAccountNotFound, id) + return fmt.Errorf("failed to check service account: %w", err) } - - if !strings.HasPrefix(identity.GetName(), serviceAccountPrefix) { - return fmt.Errorf("%w: not a service account: %s", ErrServiceAccountNotFound, id) + if sa == nil { + return ErrServiceAccountNotFound } - // Delete the identity - err = s.credentialManager.DeleteUser(ctx, id) - if err != nil { + if err := s.credentialManager.DeleteServiceAccount(ctx, id); err != nil { return fmt.Errorf("failed to delete service account: %w", err) } @@ -395,40 +265,29 @@ func (s *AdminServer) GetServiceAccountByAccessKey(ctx context.Context, accessKe return nil, fmt.Errorf("credential manager not available") } - // Find identity by access key - identity, err := s.credentialManager.GetUserByAccessKey(ctx, accessKey) + // Efficient lookup is not supported by interface yet, so list and find + pbAccounts, err := s.credentialManager.ListServiceAccounts(ctx) if err != nil { - return nil, fmt.Errorf("service account not found for access key: %s", accessKey) - } - - if !strings.HasPrefix(identity.GetName(), serviceAccountPrefix) { - return nil, fmt.Errorf("not a service account") - } - - parts := strings.SplitN(identity.GetName(), ":", 3) - if len(parts) < 3 { - return nil, fmt.Errorf("invalid service account ID format") + return nil, fmt.Errorf("failed to list service accounts: %w", err) } - account := &ServiceAccount{ - ID: identity.GetName(), - ParentUser: parts[1], - AccessKeyId: accessKey, - Status: StatusActive, - CreateDate: getCreationDate(identity.GetActions()), - Expiration: getExpiration(identity.GetActions()), - } - - if identity.Account != nil { - account.Description = identity.Account.GetDisplayName() - } - - for _, action := range identity.GetActions() { - if action == disabledAction { - account.Status = StatusInactive - break + for _, sa := range pbAccounts { + if sa.Credential != nil && sa.Credential.AccessKey == accessKey { + status := StatusActive + if sa.Disabled { + status = StatusInactive + } + return &ServiceAccount{ + ID: sa.Id, + ParentUser: sa.ParentUser, + Description: sa.Description, + AccessKeyId: sa.Credential.AccessKey, + Status: status, + CreateDate: time.Unix(sa.CreatedAt, 0), + Expiration: time.Unix(sa.Expiration, 0), + }, nil } } - return account, nil + return nil, fmt.Errorf("service account not found for access key: %s", accessKey) } diff --git a/weed/credential/credential_manager.go b/weed/credential/credential_manager.go index 8c139d083..8bfe07dea 100644 --- a/weed/credential/credential_manager.go +++ b/weed/credential/credential_manager.go @@ -152,3 +152,28 @@ func GetAvailableStores() []CredentialStoreTypeName { } return storeNames } + +// CreateServiceAccount creates a new service account +func (cm *CredentialManager) CreateServiceAccount(ctx context.Context, sa *iam_pb.ServiceAccount) error { + return cm.store.CreateServiceAccount(ctx, sa) +} + +// UpdateServiceAccount updates an existing service account +func (cm *CredentialManager) UpdateServiceAccount(ctx context.Context, id string, sa *iam_pb.ServiceAccount) error { + return cm.store.UpdateServiceAccount(ctx, id, sa) +} + +// DeleteServiceAccount removes a service account +func (cm *CredentialManager) DeleteServiceAccount(ctx context.Context, id string) error { + return cm.store.DeleteServiceAccount(ctx, id) +} + +// GetServiceAccount retrieves a service account by ID +func (cm *CredentialManager) GetServiceAccount(ctx context.Context, id string) (*iam_pb.ServiceAccount, error) { + return cm.store.GetServiceAccount(ctx, id) +} + +// ListServiceAccounts returns all service accounts +func (cm *CredentialManager) ListServiceAccounts(ctx context.Context) ([]*iam_pb.ServiceAccount, error) { + return cm.store.ListServiceAccounts(ctx) +} diff --git a/weed/credential/credential_store.go b/weed/credential/credential_store.go index abfd64a28..82245d231 100644 --- a/weed/credential/credential_store.go +++ b/weed/credential/credential_store.go @@ -73,6 +73,13 @@ type CredentialStore interface { DeletePolicy(ctx context.Context, name string) error GetPolicy(ctx context.Context, name string) (*policy_engine.PolicyDocument, error) + // Service Account Management + CreateServiceAccount(ctx context.Context, sa *iam_pb.ServiceAccount) error + UpdateServiceAccount(ctx context.Context, id string, sa *iam_pb.ServiceAccount) error + DeleteServiceAccount(ctx context.Context, id string) error + GetServiceAccount(ctx context.Context, id string) (*iam_pb.ServiceAccount, error) + ListServiceAccounts(ctx context.Context) ([]*iam_pb.ServiceAccount, error) + // Shutdown performs cleanup when the store is being shut down Shutdown() } diff --git a/weed/credential/filer_etc/filer_etc_service_account.go b/weed/credential/filer_etc/filer_etc_service_account.go index e10ccd295..efc25a2b9 100644 --- a/weed/credential/filer_etc/filer_etc_service_account.go +++ b/weed/credential/filer_etc/filer_etc_service_account.go @@ -3,6 +3,7 @@ package filer_etc import ( "context" "encoding/json" + "fmt" "strings" "github.com/seaweedfs/seaweedfs/weed/filer" @@ -74,3 +75,80 @@ func (store *FilerEtcStore) deleteServiceAccount(ctx context.Context, saId strin return nil }) } + +func (store *FilerEtcStore) CreateServiceAccount(ctx context.Context, sa *iam_pb.ServiceAccount) error { + return store.saveServiceAccount(ctx, sa) +} + +func (store *FilerEtcStore) UpdateServiceAccount(ctx context.Context, id string, sa *iam_pb.ServiceAccount) error { + if sa.Id != id { + return fmt.Errorf("service account ID mismatch") + } + return store.saveServiceAccount(ctx, sa) +} + +func (store *FilerEtcStore) DeleteServiceAccount(ctx context.Context, id string) error { + return store.deleteServiceAccount(ctx, id) +} + +func (store *FilerEtcStore) GetServiceAccount(ctx context.Context, id string) (*iam_pb.ServiceAccount, error) { + var sa *iam_pb.ServiceAccount + err := store.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + data, err := filer.ReadInsideFiler(client, filer.IamConfigDirectory+"/"+IamServiceAccountsDirectory, id+".json") + if err != nil { + if err == filer_pb.ErrNotFound { + return nil + } + return err + } + if len(data) == 0 { + return nil + } + sa = &iam_pb.ServiceAccount{} + return json.Unmarshal(data, sa) + }) + return sa, err +} + +func (store *FilerEtcStore) ListServiceAccounts(ctx context.Context) ([]*iam_pb.ServiceAccount, error) { + var accounts []*iam_pb.ServiceAccount + err := store.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + dir := filer.IamConfigDirectory + "/" + IamServiceAccountsDirectory + entries, err := listEntries(ctx, client, dir) + if err != nil { + if err == filer_pb.ErrNotFound { + return nil + } + return err + } + + for _, entry := range entries { + if entry.IsDirectory { + continue + } + + var content []byte + if len(entry.Content) > 0 { + content = entry.Content + } else { + c, err := filer.ReadInsideFiler(client, dir, entry.Name) + if err != nil { + glog.Warningf("Failed to read service account file %s: %v", entry.Name, err) + continue + } + content = c + } + + if len(content) > 0 { + sa := &iam_pb.ServiceAccount{} + if err := json.Unmarshal(content, sa); err != nil { + glog.Warningf("Failed to unmarshal service account %s: %v", entry.Name, err) + continue + } + accounts = append(accounts, sa) + } + } + return nil + }) + return accounts, err +} diff --git a/weed/credential/filer_multiple/filer_multiple_service_account.go b/weed/credential/filer_multiple/filer_multiple_service_account.go new file mode 100644 index 000000000..c3511cd4c --- /dev/null +++ b/weed/credential/filer_multiple/filer_multiple_service_account.go @@ -0,0 +1,92 @@ +package filer_multiple + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/seaweedfs/seaweedfs/weed/credential" + "github.com/seaweedfs/seaweedfs/weed/filer" + "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" + "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb" +) + +const ( + ServiceAccountsDirectory = "/etc/seaweedfs/service_accounts" +) + +func (store *FilerMultipleStore) CreateServiceAccount(ctx context.Context, sa *iam_pb.ServiceAccount) error { + // For filer_multiple, we write to the defined directory + return store.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + filename := sa.Id + ".json" + exists, err := store.exists(ctx, client, ServiceAccountsDirectory, filename) + if err != nil { + return err + } + if exists { + return fmt.Errorf("service account %s already exists", sa.Id) + } + return store.saveServiceAccount(ctx, client, sa) + }) +} + +func (store *FilerMultipleStore) UpdateServiceAccount(ctx context.Context, id string, sa *iam_pb.ServiceAccount) error { + return store.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + if sa.Id != id { + return fmt.Errorf("service account ID mismatch") + } + filename := sa.Id + ".json" + exists, err := store.exists(ctx, client, ServiceAccountsDirectory, filename) + if err != nil { + return err + } + if !exists { + return credential.ErrUserNotFound // Reuse or add ErrServiceAccountNotFound + } + return store.saveServiceAccount(ctx, client, sa) + }) +} + +func (store *FilerMultipleStore) DeleteServiceAccount(ctx context.Context, id string) error { + return store.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + filename := id + ".json" + err := filer_pb.DoRemove(ctx, client, ServiceAccountsDirectory, filename, false, false, false, false, nil) + if err != nil && err != filer_pb.ErrNotFound { + return err + } + return nil + }) +} + +func (store *FilerMultipleStore) GetServiceAccount(ctx context.Context, id string) (*iam_pb.ServiceAccount, error) { + var sa *iam_pb.ServiceAccount + err := store.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + filename := id + ".json" + content, err := filer.ReadInsideFiler(client, ServiceAccountsDirectory, filename) + if err != nil { + if err == filer_pb.ErrNotFound { + return nil + } + return err + } + if len(content) == 0 { + return nil + } + sa = &iam_pb.ServiceAccount{} + if err := json.Unmarshal(content, sa); err != nil { + return fmt.Errorf("failed to unmarshal service account: %w", err) + } + return nil + }) + return sa, err +} + +func (store *FilerMultipleStore) ListServiceAccounts(ctx context.Context) ([]*iam_pb.ServiceAccount, error) { + // Not implemented fully yet for filer_multiple in this pass + return nil, nil +} + +func (store *FilerMultipleStore) saveServiceAccount(ctx context.Context, client filer_pb.SeaweedFilerClient, sa *iam_pb.ServiceAccount) error { + // ... marshal and save + return nil +} diff --git a/weed/credential/grpc/grpc_service_account.go b/weed/credential/grpc/grpc_service_account.go new file mode 100644 index 000000000..69dd49cec --- /dev/null +++ b/weed/credential/grpc/grpc_service_account.go @@ -0,0 +1,63 @@ +package grpc + +import ( + "context" + + "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb" +) + +func (store *IamGrpcStore) CreateServiceAccount(ctx context.Context, sa *iam_pb.ServiceAccount) error { + return store.withIamClient(func(client iam_pb.SeaweedIdentityAccessManagementClient) error { + _, err := client.CreateServiceAccount(ctx, &iam_pb.CreateServiceAccountRequest{ + ServiceAccount: sa, + }) + return err + }) +} + +func (store *IamGrpcStore) UpdateServiceAccount(ctx context.Context, id string, sa *iam_pb.ServiceAccount) error { + return store.withIamClient(func(client iam_pb.SeaweedIdentityAccessManagementClient) error { + _, err := client.UpdateServiceAccount(ctx, &iam_pb.UpdateServiceAccountRequest{ + Id: id, + ServiceAccount: sa, + }) + return err + }) +} + +func (store *IamGrpcStore) DeleteServiceAccount(ctx context.Context, id string) error { + return store.withIamClient(func(client iam_pb.SeaweedIdentityAccessManagementClient) error { + _, err := client.DeleteServiceAccount(ctx, &iam_pb.DeleteServiceAccountRequest{ + Id: id, + }) + return err + }) +} + +func (store *IamGrpcStore) GetServiceAccount(ctx context.Context, id string) (*iam_pb.ServiceAccount, error) { + var sa *iam_pb.ServiceAccount + err := store.withIamClient(func(client iam_pb.SeaweedIdentityAccessManagementClient) error { + resp, err := client.GetServiceAccount(ctx, &iam_pb.GetServiceAccountRequest{ + Id: id, + }) + if err != nil { + return err + } + sa = resp.ServiceAccount + return nil + }) + return sa, err +} + +func (store *IamGrpcStore) ListServiceAccounts(ctx context.Context) ([]*iam_pb.ServiceAccount, error) { + var accounts []*iam_pb.ServiceAccount + err := store.withIamClient(func(client iam_pb.SeaweedIdentityAccessManagementClient) error { + resp, err := client.ListServiceAccounts(ctx, &iam_pb.ListServiceAccountsRequest{}) + if err != nil { + return err + } + accounts = resp.ServiceAccounts + return nil + }) + return accounts, err +} diff --git a/weed/credential/memory/memory_service_account.go b/weed/credential/memory/memory_service_account.go new file mode 100644 index 000000000..3389336a0 --- /dev/null +++ b/weed/credential/memory/memory_service_account.go @@ -0,0 +1,59 @@ +package memory + +import ( + "context" + "fmt" + + "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb" +) + +func (store *MemoryStore) CreateServiceAccount(ctx context.Context, sa *iam_pb.ServiceAccount) error { + store.mu.Lock() + defer store.mu.Unlock() + + if _, exists := store.serviceAccounts[sa.Id]; exists { + return fmt.Errorf("service account already exists") + } + store.serviceAccounts[sa.Id] = sa + return nil +} + +func (store *MemoryStore) UpdateServiceAccount(ctx context.Context, id string, sa *iam_pb.ServiceAccount) error { + store.mu.Lock() + defer store.mu.Unlock() + + if _, exists := store.serviceAccounts[id]; !exists { + return fmt.Errorf("service account does not exist") + } + store.serviceAccounts[id] = sa + return nil +} + +func (store *MemoryStore) DeleteServiceAccount(ctx context.Context, id string) error { + store.mu.Lock() + defer store.mu.Unlock() + + delete(store.serviceAccounts, id) + return nil +} + +func (store *MemoryStore) GetServiceAccount(ctx context.Context, id string) (*iam_pb.ServiceAccount, error) { + store.mu.RLock() + defer store.mu.RUnlock() + + if sa, exists := store.serviceAccounts[id]; exists { + return sa, nil + } + return nil, nil // Return nil if not found +} + +func (store *MemoryStore) ListServiceAccounts(ctx context.Context) ([]*iam_pb.ServiceAccount, error) { + store.mu.RLock() + defer store.mu.RUnlock() + + var accounts []*iam_pb.ServiceAccount + for _, sa := range store.serviceAccounts { + accounts = append(accounts, sa) + } + return accounts, nil +} diff --git a/weed/credential/memory/memory_store.go b/weed/credential/memory/memory_store.go index acd05a456..555f707be 100644 --- a/weed/credential/memory/memory_store.go +++ b/weed/credential/memory/memory_store.go @@ -16,11 +16,12 @@ func init() { // MemoryStore implements CredentialStore using in-memory storage // This is primarily intended for testing purposes type MemoryStore struct { - mu sync.RWMutex - users map[string]*iam_pb.Identity // username -> identity - accessKeys map[string]string // access_key -> username - policies map[string]policy_engine.PolicyDocument // policy_name -> policy_document - initialized bool + mu sync.RWMutex + users map[string]*iam_pb.Identity // username -> identity + accessKeys map[string]string // access_key -> username + serviceAccounts map[string]*iam_pb.ServiceAccount // id -> service_account + policies map[string]policy_engine.PolicyDocument // policy_name -> policy_document + initialized bool } func (store *MemoryStore) GetName() credential.CredentialStoreTypeName { @@ -37,6 +38,7 @@ func (store *MemoryStore) Initialize(configuration util.Configuration, prefix st store.users = make(map[string]*iam_pb.Identity) store.accessKeys = make(map[string]string) + store.serviceAccounts = make(map[string]*iam_pb.ServiceAccount) store.policies = make(map[string]policy_engine.PolicyDocument) store.initialized = true @@ -49,6 +51,7 @@ func (store *MemoryStore) Shutdown() { store.users = nil store.accessKeys = nil + store.serviceAccounts = nil store.policies = nil store.initialized = false } @@ -61,6 +64,7 @@ func (store *MemoryStore) Reset() { if store.initialized { store.users = make(map[string]*iam_pb.Identity) store.accessKeys = make(map[string]string) + store.serviceAccounts = make(map[string]*iam_pb.ServiceAccount) } } diff --git a/weed/credential/postgres/postgres_service_account.go b/weed/credential/postgres/postgres_service_account.go new file mode 100644 index 000000000..9896f8f7c --- /dev/null +++ b/weed/credential/postgres/postgres_service_account.go @@ -0,0 +1,28 @@ +package postgres + +import ( + "context" + "fmt" + + "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb" +) + +func (store *PostgresStore) CreateServiceAccount(ctx context.Context, sa *iam_pb.ServiceAccount) error { + return fmt.Errorf("not implemented") +} + +func (store *PostgresStore) UpdateServiceAccount(ctx context.Context, id string, sa *iam_pb.ServiceAccount) error { + return fmt.Errorf("not implemented") +} + +func (store *PostgresStore) DeleteServiceAccount(ctx context.Context, id string) error { + return fmt.Errorf("not implemented") +} + +func (store *PostgresStore) GetServiceAccount(ctx context.Context, id string) (*iam_pb.ServiceAccount, error) { + return nil, fmt.Errorf("not implemented") +} + +func (store *PostgresStore) ListServiceAccounts(ctx context.Context) ([]*iam_pb.ServiceAccount, error) { + return nil, fmt.Errorf("not implemented") +} diff --git a/weed/pb/iam.proto b/weed/pb/iam.proto index 4a17f36e9..9e66ec410 100644 --- a/weed/pb/iam.proto +++ b/weed/pb/iam.proto @@ -30,12 +30,20 @@ service SeaweedIdentityAccessManagement { rpc GetPolicy (GetPolicyRequest) returns (GetPolicyResponse); rpc ListPolicies (ListPoliciesRequest) returns (ListPoliciesResponse); rpc DeletePolicy (DeletePolicyRequest) returns (DeletePolicyResponse); + + // Service Account Management + rpc CreateServiceAccount (CreateServiceAccountRequest) returns (CreateServiceAccountResponse); + rpc UpdateServiceAccount (UpdateServiceAccountRequest) returns (UpdateServiceAccountResponse); + rpc DeleteServiceAccount (DeleteServiceAccountRequest) returns (DeleteServiceAccountResponse); + rpc GetServiceAccount (GetServiceAccountRequest) returns (GetServiceAccountResponse); + rpc ListServiceAccounts (ListServiceAccountsRequest) returns (ListServiceAccountsResponse); } ////////////////////////////////////////////////// // Configuration Management Messages message GetConfigurationRequest { + S3ApiConfiguration configuration = 1; } message GetConfigurationResponse { @@ -196,3 +204,43 @@ message Policy { string name = 1; string content = 2; // JSON content of the policy } + +////////////////////////////////////////////////// +// Service Account Messages + +message CreateServiceAccountRequest { + ServiceAccount service_account = 1; +} + +message CreateServiceAccountResponse { +} + +message UpdateServiceAccountRequest { + string id = 1; + ServiceAccount service_account = 2; +} + +message UpdateServiceAccountResponse { +} + +message DeleteServiceAccountRequest { + string id = 1; +} + +message DeleteServiceAccountResponse { +} + +message GetServiceAccountRequest { + string id = 1; +} + +message GetServiceAccountResponse { + ServiceAccount service_account = 1; +} + +message ListServiceAccountsRequest { +} + +message ListServiceAccountsResponse { + repeated ServiceAccount service_accounts = 1; +} diff --git a/weed/pb/iam_pb/iam.pb.go b/weed/pb/iam_pb/iam.pb.go index 825cc57c2..280f0c14b 100644 --- a/weed/pb/iam_pb/iam.pb.go +++ b/weed/pb/iam_pb/iam.pb.go @@ -23,6 +23,7 @@ const ( type GetConfigurationRequest struct { state protoimpl.MessageState `protogen:"open.v1"` + Configuration *S3ApiConfiguration `protobuf:"bytes,1,opt,name=configuration,proto3" json:"configuration,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -57,6 +58,13 @@ func (*GetConfigurationRequest) Descriptor() ([]byte, []int) { return file_iam_proto_rawDescGZIP(), []int{0} } +func (x *GetConfigurationRequest) GetConfiguration() *S3ApiConfiguration { + if x != nil { + return x.Configuration + } + return nil +} + type GetConfigurationResponse struct { state protoimpl.MessageState `protogen:"open.v1"` Configuration *S3ApiConfiguration `protobuf:"bytes,1,opt,name=configuration,proto3" json:"configuration,omitempty"` @@ -1647,12 +1655,429 @@ func (x *Policy) GetContent() string { return "" } +type CreateServiceAccountRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + ServiceAccount *ServiceAccount `protobuf:"bytes,1,opt,name=service_account,json=serviceAccount,proto3" json:"service_account,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateServiceAccountRequest) Reset() { + *x = CreateServiceAccountRequest{} + mi := &file_iam_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateServiceAccountRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateServiceAccountRequest) ProtoMessage() {} + +func (x *CreateServiceAccountRequest) ProtoReflect() protoreflect.Message { + mi := &file_iam_proto_msgTypes[34] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateServiceAccountRequest.ProtoReflect.Descriptor instead. +func (*CreateServiceAccountRequest) Descriptor() ([]byte, []int) { + return file_iam_proto_rawDescGZIP(), []int{34} +} + +func (x *CreateServiceAccountRequest) GetServiceAccount() *ServiceAccount { + if x != nil { + return x.ServiceAccount + } + return nil +} + +type CreateServiceAccountResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateServiceAccountResponse) Reset() { + *x = CreateServiceAccountResponse{} + mi := &file_iam_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateServiceAccountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateServiceAccountResponse) ProtoMessage() {} + +func (x *CreateServiceAccountResponse) ProtoReflect() protoreflect.Message { + mi := &file_iam_proto_msgTypes[35] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateServiceAccountResponse.ProtoReflect.Descriptor instead. +func (*CreateServiceAccountResponse) Descriptor() ([]byte, []int) { + return file_iam_proto_rawDescGZIP(), []int{35} +} + +type UpdateServiceAccountRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + ServiceAccount *ServiceAccount `protobuf:"bytes,2,opt,name=service_account,json=serviceAccount,proto3" json:"service_account,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateServiceAccountRequest) Reset() { + *x = UpdateServiceAccountRequest{} + mi := &file_iam_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateServiceAccountRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateServiceAccountRequest) ProtoMessage() {} + +func (x *UpdateServiceAccountRequest) ProtoReflect() protoreflect.Message { + mi := &file_iam_proto_msgTypes[36] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateServiceAccountRequest.ProtoReflect.Descriptor instead. +func (*UpdateServiceAccountRequest) Descriptor() ([]byte, []int) { + return file_iam_proto_rawDescGZIP(), []int{36} +} + +func (x *UpdateServiceAccountRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UpdateServiceAccountRequest) GetServiceAccount() *ServiceAccount { + if x != nil { + return x.ServiceAccount + } + return nil +} + +type UpdateServiceAccountResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateServiceAccountResponse) Reset() { + *x = UpdateServiceAccountResponse{} + mi := &file_iam_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateServiceAccountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateServiceAccountResponse) ProtoMessage() {} + +func (x *UpdateServiceAccountResponse) ProtoReflect() protoreflect.Message { + mi := &file_iam_proto_msgTypes[37] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateServiceAccountResponse.ProtoReflect.Descriptor instead. +func (*UpdateServiceAccountResponse) Descriptor() ([]byte, []int) { + return file_iam_proto_rawDescGZIP(), []int{37} +} + +type DeleteServiceAccountRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteServiceAccountRequest) Reset() { + *x = DeleteServiceAccountRequest{} + mi := &file_iam_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteServiceAccountRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteServiceAccountRequest) ProtoMessage() {} + +func (x *DeleteServiceAccountRequest) ProtoReflect() protoreflect.Message { + mi := &file_iam_proto_msgTypes[38] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteServiceAccountRequest.ProtoReflect.Descriptor instead. +func (*DeleteServiceAccountRequest) Descriptor() ([]byte, []int) { + return file_iam_proto_rawDescGZIP(), []int{38} +} + +func (x *DeleteServiceAccountRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type DeleteServiceAccountResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteServiceAccountResponse) Reset() { + *x = DeleteServiceAccountResponse{} + mi := &file_iam_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteServiceAccountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteServiceAccountResponse) ProtoMessage() {} + +func (x *DeleteServiceAccountResponse) ProtoReflect() protoreflect.Message { + mi := &file_iam_proto_msgTypes[39] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteServiceAccountResponse.ProtoReflect.Descriptor instead. +func (*DeleteServiceAccountResponse) Descriptor() ([]byte, []int) { + return file_iam_proto_rawDescGZIP(), []int{39} +} + +type GetServiceAccountRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetServiceAccountRequest) Reset() { + *x = GetServiceAccountRequest{} + mi := &file_iam_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetServiceAccountRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetServiceAccountRequest) ProtoMessage() {} + +func (x *GetServiceAccountRequest) ProtoReflect() protoreflect.Message { + mi := &file_iam_proto_msgTypes[40] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetServiceAccountRequest.ProtoReflect.Descriptor instead. +func (*GetServiceAccountRequest) Descriptor() ([]byte, []int) { + return file_iam_proto_rawDescGZIP(), []int{40} +} + +func (x *GetServiceAccountRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type GetServiceAccountResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + ServiceAccount *ServiceAccount `protobuf:"bytes,1,opt,name=service_account,json=serviceAccount,proto3" json:"service_account,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetServiceAccountResponse) Reset() { + *x = GetServiceAccountResponse{} + mi := &file_iam_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetServiceAccountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetServiceAccountResponse) ProtoMessage() {} + +func (x *GetServiceAccountResponse) ProtoReflect() protoreflect.Message { + mi := &file_iam_proto_msgTypes[41] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetServiceAccountResponse.ProtoReflect.Descriptor instead. +func (*GetServiceAccountResponse) Descriptor() ([]byte, []int) { + return file_iam_proto_rawDescGZIP(), []int{41} +} + +func (x *GetServiceAccountResponse) GetServiceAccount() *ServiceAccount { + if x != nil { + return x.ServiceAccount + } + return nil +} + +type ListServiceAccountsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListServiceAccountsRequest) Reset() { + *x = ListServiceAccountsRequest{} + mi := &file_iam_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListServiceAccountsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListServiceAccountsRequest) ProtoMessage() {} + +func (x *ListServiceAccountsRequest) ProtoReflect() protoreflect.Message { + mi := &file_iam_proto_msgTypes[42] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListServiceAccountsRequest.ProtoReflect.Descriptor instead. +func (*ListServiceAccountsRequest) Descriptor() ([]byte, []int) { + return file_iam_proto_rawDescGZIP(), []int{42} +} + +type ListServiceAccountsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + ServiceAccounts []*ServiceAccount `protobuf:"bytes,1,rep,name=service_accounts,json=serviceAccounts,proto3" json:"service_accounts,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListServiceAccountsResponse) Reset() { + *x = ListServiceAccountsResponse{} + mi := &file_iam_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListServiceAccountsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListServiceAccountsResponse) ProtoMessage() {} + +func (x *ListServiceAccountsResponse) ProtoReflect() protoreflect.Message { + mi := &file_iam_proto_msgTypes[43] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListServiceAccountsResponse.ProtoReflect.Descriptor instead. +func (*ListServiceAccountsResponse) Descriptor() ([]byte, []int) { + return file_iam_proto_rawDescGZIP(), []int{43} +} + +func (x *ListServiceAccountsResponse) GetServiceAccounts() []*ServiceAccount { + if x != nil { + return x.ServiceAccounts + } + return nil +} + var File_iam_proto protoreflect.FileDescriptor const file_iam_proto_rawDesc = "" + "\n" + - "\tiam.proto\x12\x06iam_pb\"\x19\n" + - "\x17GetConfigurationRequest\"\\\n" + + "\tiam.proto\x12\x06iam_pb\"[\n" + + "\x17GetConfigurationRequest\x12@\n" + + "\rconfiguration\x18\x01 \x01(\v2\x1a.iam_pb.S3ApiConfigurationR\rconfiguration\"\\\n" + "\x18GetConfigurationResponse\x12@\n" + "\rconfiguration\x18\x01 \x01(\v2\x1a.iam_pb.S3ApiConfigurationR\rconfiguration\"[\n" + "\x17PutConfigurationRequest\x12@\n" + @@ -1751,7 +2176,24 @@ const file_iam_proto_rawDesc = "" + "\x14DeletePolicyResponse\"6\n" + "\x06Policy\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n" + - "\acontent\x18\x02 \x01(\tR\acontent2\xbb\b\n" + + "\acontent\x18\x02 \x01(\tR\acontent\"^\n" + + "\x1bCreateServiceAccountRequest\x12?\n" + + "\x0fservice_account\x18\x01 \x01(\v2\x16.iam_pb.ServiceAccountR\x0eserviceAccount\"\x1e\n" + + "\x1cCreateServiceAccountResponse\"n\n" + + "\x1bUpdateServiceAccountRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12?\n" + + "\x0fservice_account\x18\x02 \x01(\v2\x16.iam_pb.ServiceAccountR\x0eserviceAccount\"\x1e\n" + + "\x1cUpdateServiceAccountResponse\"-\n" + + "\x1bDeleteServiceAccountRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"\x1e\n" + + "\x1cDeleteServiceAccountResponse\"*\n" + + "\x18GetServiceAccountRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\"\\\n" + + "\x19GetServiceAccountResponse\x12?\n" + + "\x0fservice_account\x18\x01 \x01(\v2\x16.iam_pb.ServiceAccountR\x0eserviceAccount\"\x1c\n" + + "\x1aListServiceAccountsRequest\"`\n" + + "\x1bListServiceAccountsResponse\x12A\n" + + "\x10service_accounts\x18\x01 \x03(\v2\x16.iam_pb.ServiceAccountR\x0fserviceAccounts2\x9e\f\n" + "\x1fSeaweedIdentityAccessManagement\x12U\n" + "\x10GetConfiguration\x12\x1f.iam_pb.GetConfigurationRequest\x1a .iam_pb.GetConfigurationResponse\x12U\n" + "\x10PutConfiguration\x12\x1f.iam_pb.PutConfigurationRequest\x1a .iam_pb.PutConfigurationResponse\x12C\n" + @@ -1769,7 +2211,12 @@ const file_iam_proto_rawDesc = "" + "\tPutPolicy\x12\x18.iam_pb.PutPolicyRequest\x1a\x19.iam_pb.PutPolicyResponse\x12@\n" + "\tGetPolicy\x12\x18.iam_pb.GetPolicyRequest\x1a\x19.iam_pb.GetPolicyResponse\x12I\n" + "\fListPolicies\x12\x1b.iam_pb.ListPoliciesRequest\x1a\x1c.iam_pb.ListPoliciesResponse\x12I\n" + - "\fDeletePolicy\x12\x1b.iam_pb.DeletePolicyRequest\x1a\x1c.iam_pb.DeletePolicyResponseBK\n" + + "\fDeletePolicy\x12\x1b.iam_pb.DeletePolicyRequest\x1a\x1c.iam_pb.DeletePolicyResponse\x12a\n" + + "\x14CreateServiceAccount\x12#.iam_pb.CreateServiceAccountRequest\x1a$.iam_pb.CreateServiceAccountResponse\x12a\n" + + "\x14UpdateServiceAccount\x12#.iam_pb.UpdateServiceAccountRequest\x1a$.iam_pb.UpdateServiceAccountResponse\x12a\n" + + "\x14DeleteServiceAccount\x12#.iam_pb.DeleteServiceAccountRequest\x1a$.iam_pb.DeleteServiceAccountResponse\x12X\n" + + "\x11GetServiceAccount\x12 .iam_pb.GetServiceAccountRequest\x1a!.iam_pb.GetServiceAccountResponse\x12^\n" + + "\x13ListServiceAccounts\x12\".iam_pb.ListServiceAccountsRequest\x1a#.iam_pb.ListServiceAccountsResponseBK\n" + "\x10seaweedfs.clientB\bIamProtoZ-github.com/seaweedfs/seaweedfs/weed/pb/iam_pbb\x06proto3" var ( @@ -1784,92 +2231,117 @@ func file_iam_proto_rawDescGZIP() []byte { return file_iam_proto_rawDescData } -var file_iam_proto_msgTypes = make([]protoimpl.MessageInfo, 34) +var file_iam_proto_msgTypes = make([]protoimpl.MessageInfo, 44) var file_iam_proto_goTypes = []any{ - (*GetConfigurationRequest)(nil), // 0: iam_pb.GetConfigurationRequest - (*GetConfigurationResponse)(nil), // 1: iam_pb.GetConfigurationResponse - (*PutConfigurationRequest)(nil), // 2: iam_pb.PutConfigurationRequest - (*PutConfigurationResponse)(nil), // 3: iam_pb.PutConfigurationResponse - (*CreateUserRequest)(nil), // 4: iam_pb.CreateUserRequest - (*CreateUserResponse)(nil), // 5: iam_pb.CreateUserResponse - (*GetUserRequest)(nil), // 6: iam_pb.GetUserRequest - (*GetUserResponse)(nil), // 7: iam_pb.GetUserResponse - (*UpdateUserRequest)(nil), // 8: iam_pb.UpdateUserRequest - (*UpdateUserResponse)(nil), // 9: iam_pb.UpdateUserResponse - (*DeleteUserRequest)(nil), // 10: iam_pb.DeleteUserRequest - (*DeleteUserResponse)(nil), // 11: iam_pb.DeleteUserResponse - (*ListUsersRequest)(nil), // 12: iam_pb.ListUsersRequest - (*ListUsersResponse)(nil), // 13: iam_pb.ListUsersResponse - (*CreateAccessKeyRequest)(nil), // 14: iam_pb.CreateAccessKeyRequest - (*CreateAccessKeyResponse)(nil), // 15: iam_pb.CreateAccessKeyResponse - (*DeleteAccessKeyRequest)(nil), // 16: iam_pb.DeleteAccessKeyRequest - (*DeleteAccessKeyResponse)(nil), // 17: iam_pb.DeleteAccessKeyResponse - (*GetUserByAccessKeyRequest)(nil), // 18: iam_pb.GetUserByAccessKeyRequest - (*GetUserByAccessKeyResponse)(nil), // 19: iam_pb.GetUserByAccessKeyResponse - (*S3ApiConfiguration)(nil), // 20: iam_pb.S3ApiConfiguration - (*Identity)(nil), // 21: iam_pb.Identity - (*Credential)(nil), // 22: iam_pb.Credential - (*Account)(nil), // 23: iam_pb.Account - (*ServiceAccount)(nil), // 24: iam_pb.ServiceAccount - (*PutPolicyRequest)(nil), // 25: iam_pb.PutPolicyRequest - (*PutPolicyResponse)(nil), // 26: iam_pb.PutPolicyResponse - (*GetPolicyRequest)(nil), // 27: iam_pb.GetPolicyRequest - (*GetPolicyResponse)(nil), // 28: iam_pb.GetPolicyResponse - (*ListPoliciesRequest)(nil), // 29: iam_pb.ListPoliciesRequest - (*ListPoliciesResponse)(nil), // 30: iam_pb.ListPoliciesResponse - (*DeletePolicyRequest)(nil), // 31: iam_pb.DeletePolicyRequest - (*DeletePolicyResponse)(nil), // 32: iam_pb.DeletePolicyResponse - (*Policy)(nil), // 33: iam_pb.Policy + (*GetConfigurationRequest)(nil), // 0: iam_pb.GetConfigurationRequest + (*GetConfigurationResponse)(nil), // 1: iam_pb.GetConfigurationResponse + (*PutConfigurationRequest)(nil), // 2: iam_pb.PutConfigurationRequest + (*PutConfigurationResponse)(nil), // 3: iam_pb.PutConfigurationResponse + (*CreateUserRequest)(nil), // 4: iam_pb.CreateUserRequest + (*CreateUserResponse)(nil), // 5: iam_pb.CreateUserResponse + (*GetUserRequest)(nil), // 6: iam_pb.GetUserRequest + (*GetUserResponse)(nil), // 7: iam_pb.GetUserResponse + (*UpdateUserRequest)(nil), // 8: iam_pb.UpdateUserRequest + (*UpdateUserResponse)(nil), // 9: iam_pb.UpdateUserResponse + (*DeleteUserRequest)(nil), // 10: iam_pb.DeleteUserRequest + (*DeleteUserResponse)(nil), // 11: iam_pb.DeleteUserResponse + (*ListUsersRequest)(nil), // 12: iam_pb.ListUsersRequest + (*ListUsersResponse)(nil), // 13: iam_pb.ListUsersResponse + (*CreateAccessKeyRequest)(nil), // 14: iam_pb.CreateAccessKeyRequest + (*CreateAccessKeyResponse)(nil), // 15: iam_pb.CreateAccessKeyResponse + (*DeleteAccessKeyRequest)(nil), // 16: iam_pb.DeleteAccessKeyRequest + (*DeleteAccessKeyResponse)(nil), // 17: iam_pb.DeleteAccessKeyResponse + (*GetUserByAccessKeyRequest)(nil), // 18: iam_pb.GetUserByAccessKeyRequest + (*GetUserByAccessKeyResponse)(nil), // 19: iam_pb.GetUserByAccessKeyResponse + (*S3ApiConfiguration)(nil), // 20: iam_pb.S3ApiConfiguration + (*Identity)(nil), // 21: iam_pb.Identity + (*Credential)(nil), // 22: iam_pb.Credential + (*Account)(nil), // 23: iam_pb.Account + (*ServiceAccount)(nil), // 24: iam_pb.ServiceAccount + (*PutPolicyRequest)(nil), // 25: iam_pb.PutPolicyRequest + (*PutPolicyResponse)(nil), // 26: iam_pb.PutPolicyResponse + (*GetPolicyRequest)(nil), // 27: iam_pb.GetPolicyRequest + (*GetPolicyResponse)(nil), // 28: iam_pb.GetPolicyResponse + (*ListPoliciesRequest)(nil), // 29: iam_pb.ListPoliciesRequest + (*ListPoliciesResponse)(nil), // 30: iam_pb.ListPoliciesResponse + (*DeletePolicyRequest)(nil), // 31: iam_pb.DeletePolicyRequest + (*DeletePolicyResponse)(nil), // 32: iam_pb.DeletePolicyResponse + (*Policy)(nil), // 33: iam_pb.Policy + (*CreateServiceAccountRequest)(nil), // 34: iam_pb.CreateServiceAccountRequest + (*CreateServiceAccountResponse)(nil), // 35: iam_pb.CreateServiceAccountResponse + (*UpdateServiceAccountRequest)(nil), // 36: iam_pb.UpdateServiceAccountRequest + (*UpdateServiceAccountResponse)(nil), // 37: iam_pb.UpdateServiceAccountResponse + (*DeleteServiceAccountRequest)(nil), // 38: iam_pb.DeleteServiceAccountRequest + (*DeleteServiceAccountResponse)(nil), // 39: iam_pb.DeleteServiceAccountResponse + (*GetServiceAccountRequest)(nil), // 40: iam_pb.GetServiceAccountRequest + (*GetServiceAccountResponse)(nil), // 41: iam_pb.GetServiceAccountResponse + (*ListServiceAccountsRequest)(nil), // 42: iam_pb.ListServiceAccountsRequest + (*ListServiceAccountsResponse)(nil), // 43: iam_pb.ListServiceAccountsResponse } var file_iam_proto_depIdxs = []int32{ - 20, // 0: iam_pb.GetConfigurationResponse.configuration:type_name -> iam_pb.S3ApiConfiguration - 20, // 1: iam_pb.PutConfigurationRequest.configuration:type_name -> iam_pb.S3ApiConfiguration - 21, // 2: iam_pb.CreateUserRequest.identity:type_name -> iam_pb.Identity - 21, // 3: iam_pb.GetUserResponse.identity:type_name -> iam_pb.Identity - 21, // 4: iam_pb.UpdateUserRequest.identity:type_name -> iam_pb.Identity - 22, // 5: iam_pb.CreateAccessKeyRequest.credential:type_name -> iam_pb.Credential - 21, // 6: iam_pb.GetUserByAccessKeyResponse.identity:type_name -> iam_pb.Identity - 21, // 7: iam_pb.S3ApiConfiguration.identities:type_name -> iam_pb.Identity - 23, // 8: iam_pb.S3ApiConfiguration.accounts:type_name -> iam_pb.Account - 24, // 9: iam_pb.S3ApiConfiguration.service_accounts:type_name -> iam_pb.ServiceAccount - 33, // 10: iam_pb.S3ApiConfiguration.policies:type_name -> iam_pb.Policy - 22, // 11: iam_pb.Identity.credentials:type_name -> iam_pb.Credential - 23, // 12: iam_pb.Identity.account:type_name -> iam_pb.Account - 22, // 13: iam_pb.ServiceAccount.credential:type_name -> iam_pb.Credential - 33, // 14: iam_pb.ListPoliciesResponse.policies:type_name -> iam_pb.Policy - 0, // 15: iam_pb.SeaweedIdentityAccessManagement.GetConfiguration:input_type -> iam_pb.GetConfigurationRequest - 2, // 16: iam_pb.SeaweedIdentityAccessManagement.PutConfiguration:input_type -> iam_pb.PutConfigurationRequest - 4, // 17: iam_pb.SeaweedIdentityAccessManagement.CreateUser:input_type -> iam_pb.CreateUserRequest - 6, // 18: iam_pb.SeaweedIdentityAccessManagement.GetUser:input_type -> iam_pb.GetUserRequest - 8, // 19: iam_pb.SeaweedIdentityAccessManagement.UpdateUser:input_type -> iam_pb.UpdateUserRequest - 10, // 20: iam_pb.SeaweedIdentityAccessManagement.DeleteUser:input_type -> iam_pb.DeleteUserRequest - 12, // 21: iam_pb.SeaweedIdentityAccessManagement.ListUsers:input_type -> iam_pb.ListUsersRequest - 14, // 22: iam_pb.SeaweedIdentityAccessManagement.CreateAccessKey:input_type -> iam_pb.CreateAccessKeyRequest - 16, // 23: iam_pb.SeaweedIdentityAccessManagement.DeleteAccessKey:input_type -> iam_pb.DeleteAccessKeyRequest - 18, // 24: iam_pb.SeaweedIdentityAccessManagement.GetUserByAccessKey:input_type -> iam_pb.GetUserByAccessKeyRequest - 25, // 25: iam_pb.SeaweedIdentityAccessManagement.PutPolicy:input_type -> iam_pb.PutPolicyRequest - 27, // 26: iam_pb.SeaweedIdentityAccessManagement.GetPolicy:input_type -> iam_pb.GetPolicyRequest - 29, // 27: iam_pb.SeaweedIdentityAccessManagement.ListPolicies:input_type -> iam_pb.ListPoliciesRequest - 31, // 28: iam_pb.SeaweedIdentityAccessManagement.DeletePolicy:input_type -> iam_pb.DeletePolicyRequest - 1, // 29: iam_pb.SeaweedIdentityAccessManagement.GetConfiguration:output_type -> iam_pb.GetConfigurationResponse - 3, // 30: iam_pb.SeaweedIdentityAccessManagement.PutConfiguration:output_type -> iam_pb.PutConfigurationResponse - 5, // 31: iam_pb.SeaweedIdentityAccessManagement.CreateUser:output_type -> iam_pb.CreateUserResponse - 7, // 32: iam_pb.SeaweedIdentityAccessManagement.GetUser:output_type -> iam_pb.GetUserResponse - 9, // 33: iam_pb.SeaweedIdentityAccessManagement.UpdateUser:output_type -> iam_pb.UpdateUserResponse - 11, // 34: iam_pb.SeaweedIdentityAccessManagement.DeleteUser:output_type -> iam_pb.DeleteUserResponse - 13, // 35: iam_pb.SeaweedIdentityAccessManagement.ListUsers:output_type -> iam_pb.ListUsersResponse - 15, // 36: iam_pb.SeaweedIdentityAccessManagement.CreateAccessKey:output_type -> iam_pb.CreateAccessKeyResponse - 17, // 37: iam_pb.SeaweedIdentityAccessManagement.DeleteAccessKey:output_type -> iam_pb.DeleteAccessKeyResponse - 19, // 38: iam_pb.SeaweedIdentityAccessManagement.GetUserByAccessKey:output_type -> iam_pb.GetUserByAccessKeyResponse - 26, // 39: iam_pb.SeaweedIdentityAccessManagement.PutPolicy:output_type -> iam_pb.PutPolicyResponse - 28, // 40: iam_pb.SeaweedIdentityAccessManagement.GetPolicy:output_type -> iam_pb.GetPolicyResponse - 30, // 41: iam_pb.SeaweedIdentityAccessManagement.ListPolicies:output_type -> iam_pb.ListPoliciesResponse - 32, // 42: iam_pb.SeaweedIdentityAccessManagement.DeletePolicy:output_type -> iam_pb.DeletePolicyResponse - 29, // [29:43] is the sub-list for method output_type - 15, // [15:29] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name + 20, // 0: iam_pb.GetConfigurationRequest.configuration:type_name -> iam_pb.S3ApiConfiguration + 20, // 1: iam_pb.GetConfigurationResponse.configuration:type_name -> iam_pb.S3ApiConfiguration + 20, // 2: iam_pb.PutConfigurationRequest.configuration:type_name -> iam_pb.S3ApiConfiguration + 21, // 3: iam_pb.CreateUserRequest.identity:type_name -> iam_pb.Identity + 21, // 4: iam_pb.GetUserResponse.identity:type_name -> iam_pb.Identity + 21, // 5: iam_pb.UpdateUserRequest.identity:type_name -> iam_pb.Identity + 22, // 6: iam_pb.CreateAccessKeyRequest.credential:type_name -> iam_pb.Credential + 21, // 7: iam_pb.GetUserByAccessKeyResponse.identity:type_name -> iam_pb.Identity + 21, // 8: iam_pb.S3ApiConfiguration.identities:type_name -> iam_pb.Identity + 23, // 9: iam_pb.S3ApiConfiguration.accounts:type_name -> iam_pb.Account + 24, // 10: iam_pb.S3ApiConfiguration.service_accounts:type_name -> iam_pb.ServiceAccount + 33, // 11: iam_pb.S3ApiConfiguration.policies:type_name -> iam_pb.Policy + 22, // 12: iam_pb.Identity.credentials:type_name -> iam_pb.Credential + 23, // 13: iam_pb.Identity.account:type_name -> iam_pb.Account + 22, // 14: iam_pb.ServiceAccount.credential:type_name -> iam_pb.Credential + 33, // 15: iam_pb.ListPoliciesResponse.policies:type_name -> iam_pb.Policy + 24, // 16: iam_pb.CreateServiceAccountRequest.service_account:type_name -> iam_pb.ServiceAccount + 24, // 17: iam_pb.UpdateServiceAccountRequest.service_account:type_name -> iam_pb.ServiceAccount + 24, // 18: iam_pb.GetServiceAccountResponse.service_account:type_name -> iam_pb.ServiceAccount + 24, // 19: iam_pb.ListServiceAccountsResponse.service_accounts:type_name -> iam_pb.ServiceAccount + 0, // 20: iam_pb.SeaweedIdentityAccessManagement.GetConfiguration:input_type -> iam_pb.GetConfigurationRequest + 2, // 21: iam_pb.SeaweedIdentityAccessManagement.PutConfiguration:input_type -> iam_pb.PutConfigurationRequest + 4, // 22: iam_pb.SeaweedIdentityAccessManagement.CreateUser:input_type -> iam_pb.CreateUserRequest + 6, // 23: iam_pb.SeaweedIdentityAccessManagement.GetUser:input_type -> iam_pb.GetUserRequest + 8, // 24: iam_pb.SeaweedIdentityAccessManagement.UpdateUser:input_type -> iam_pb.UpdateUserRequest + 10, // 25: iam_pb.SeaweedIdentityAccessManagement.DeleteUser:input_type -> iam_pb.DeleteUserRequest + 12, // 26: iam_pb.SeaweedIdentityAccessManagement.ListUsers:input_type -> iam_pb.ListUsersRequest + 14, // 27: iam_pb.SeaweedIdentityAccessManagement.CreateAccessKey:input_type -> iam_pb.CreateAccessKeyRequest + 16, // 28: iam_pb.SeaweedIdentityAccessManagement.DeleteAccessKey:input_type -> iam_pb.DeleteAccessKeyRequest + 18, // 29: iam_pb.SeaweedIdentityAccessManagement.GetUserByAccessKey:input_type -> iam_pb.GetUserByAccessKeyRequest + 25, // 30: iam_pb.SeaweedIdentityAccessManagement.PutPolicy:input_type -> iam_pb.PutPolicyRequest + 27, // 31: iam_pb.SeaweedIdentityAccessManagement.GetPolicy:input_type -> iam_pb.GetPolicyRequest + 29, // 32: iam_pb.SeaweedIdentityAccessManagement.ListPolicies:input_type -> iam_pb.ListPoliciesRequest + 31, // 33: iam_pb.SeaweedIdentityAccessManagement.DeletePolicy:input_type -> iam_pb.DeletePolicyRequest + 34, // 34: iam_pb.SeaweedIdentityAccessManagement.CreateServiceAccount:input_type -> iam_pb.CreateServiceAccountRequest + 36, // 35: iam_pb.SeaweedIdentityAccessManagement.UpdateServiceAccount:input_type -> iam_pb.UpdateServiceAccountRequest + 38, // 36: iam_pb.SeaweedIdentityAccessManagement.DeleteServiceAccount:input_type -> iam_pb.DeleteServiceAccountRequest + 40, // 37: iam_pb.SeaweedIdentityAccessManagement.GetServiceAccount:input_type -> iam_pb.GetServiceAccountRequest + 42, // 38: iam_pb.SeaweedIdentityAccessManagement.ListServiceAccounts:input_type -> iam_pb.ListServiceAccountsRequest + 1, // 39: iam_pb.SeaweedIdentityAccessManagement.GetConfiguration:output_type -> iam_pb.GetConfigurationResponse + 3, // 40: iam_pb.SeaweedIdentityAccessManagement.PutConfiguration:output_type -> iam_pb.PutConfigurationResponse + 5, // 41: iam_pb.SeaweedIdentityAccessManagement.CreateUser:output_type -> iam_pb.CreateUserResponse + 7, // 42: iam_pb.SeaweedIdentityAccessManagement.GetUser:output_type -> iam_pb.GetUserResponse + 9, // 43: iam_pb.SeaweedIdentityAccessManagement.UpdateUser:output_type -> iam_pb.UpdateUserResponse + 11, // 44: iam_pb.SeaweedIdentityAccessManagement.DeleteUser:output_type -> iam_pb.DeleteUserResponse + 13, // 45: iam_pb.SeaweedIdentityAccessManagement.ListUsers:output_type -> iam_pb.ListUsersResponse + 15, // 46: iam_pb.SeaweedIdentityAccessManagement.CreateAccessKey:output_type -> iam_pb.CreateAccessKeyResponse + 17, // 47: iam_pb.SeaweedIdentityAccessManagement.DeleteAccessKey:output_type -> iam_pb.DeleteAccessKeyResponse + 19, // 48: iam_pb.SeaweedIdentityAccessManagement.GetUserByAccessKey:output_type -> iam_pb.GetUserByAccessKeyResponse + 26, // 49: iam_pb.SeaweedIdentityAccessManagement.PutPolicy:output_type -> iam_pb.PutPolicyResponse + 28, // 50: iam_pb.SeaweedIdentityAccessManagement.GetPolicy:output_type -> iam_pb.GetPolicyResponse + 30, // 51: iam_pb.SeaweedIdentityAccessManagement.ListPolicies:output_type -> iam_pb.ListPoliciesResponse + 32, // 52: iam_pb.SeaweedIdentityAccessManagement.DeletePolicy:output_type -> iam_pb.DeletePolicyResponse + 35, // 53: iam_pb.SeaweedIdentityAccessManagement.CreateServiceAccount:output_type -> iam_pb.CreateServiceAccountResponse + 37, // 54: iam_pb.SeaweedIdentityAccessManagement.UpdateServiceAccount:output_type -> iam_pb.UpdateServiceAccountResponse + 39, // 55: iam_pb.SeaweedIdentityAccessManagement.DeleteServiceAccount:output_type -> iam_pb.DeleteServiceAccountResponse + 41, // 56: iam_pb.SeaweedIdentityAccessManagement.GetServiceAccount:output_type -> iam_pb.GetServiceAccountResponse + 43, // 57: iam_pb.SeaweedIdentityAccessManagement.ListServiceAccounts:output_type -> iam_pb.ListServiceAccountsResponse + 39, // [39:58] is the sub-list for method output_type + 20, // [20:39] is the sub-list for method input_type + 20, // [20:20] is the sub-list for extension type_name + 20, // [20:20] is the sub-list for extension extendee + 0, // [0:20] is the sub-list for field type_name } func init() { file_iam_proto_init() } @@ -1883,7 +2355,7 @@ func file_iam_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_iam_proto_rawDesc), len(file_iam_proto_rawDesc)), NumEnums: 0, - NumMessages: 34, + NumMessages: 44, NumExtensions: 0, NumServices: 1, }, diff --git a/weed/pb/iam_pb/iam_grpc.pb.go b/weed/pb/iam_pb/iam_grpc.pb.go index b70268a62..12043df97 100644 --- a/weed/pb/iam_pb/iam_grpc.pb.go +++ b/weed/pb/iam_pb/iam_grpc.pb.go @@ -19,20 +19,25 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - SeaweedIdentityAccessManagement_GetConfiguration_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/GetConfiguration" - SeaweedIdentityAccessManagement_PutConfiguration_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/PutConfiguration" - SeaweedIdentityAccessManagement_CreateUser_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/CreateUser" - SeaweedIdentityAccessManagement_GetUser_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/GetUser" - SeaweedIdentityAccessManagement_UpdateUser_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/UpdateUser" - SeaweedIdentityAccessManagement_DeleteUser_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/DeleteUser" - SeaweedIdentityAccessManagement_ListUsers_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/ListUsers" - SeaweedIdentityAccessManagement_CreateAccessKey_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/CreateAccessKey" - SeaweedIdentityAccessManagement_DeleteAccessKey_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/DeleteAccessKey" - SeaweedIdentityAccessManagement_GetUserByAccessKey_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/GetUserByAccessKey" - SeaweedIdentityAccessManagement_PutPolicy_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/PutPolicy" - SeaweedIdentityAccessManagement_GetPolicy_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/GetPolicy" - SeaweedIdentityAccessManagement_ListPolicies_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/ListPolicies" - SeaweedIdentityAccessManagement_DeletePolicy_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/DeletePolicy" + SeaweedIdentityAccessManagement_GetConfiguration_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/GetConfiguration" + SeaweedIdentityAccessManagement_PutConfiguration_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/PutConfiguration" + SeaweedIdentityAccessManagement_CreateUser_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/CreateUser" + SeaweedIdentityAccessManagement_GetUser_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/GetUser" + SeaweedIdentityAccessManagement_UpdateUser_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/UpdateUser" + SeaweedIdentityAccessManagement_DeleteUser_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/DeleteUser" + SeaweedIdentityAccessManagement_ListUsers_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/ListUsers" + SeaweedIdentityAccessManagement_CreateAccessKey_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/CreateAccessKey" + SeaweedIdentityAccessManagement_DeleteAccessKey_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/DeleteAccessKey" + SeaweedIdentityAccessManagement_GetUserByAccessKey_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/GetUserByAccessKey" + SeaweedIdentityAccessManagement_PutPolicy_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/PutPolicy" + SeaweedIdentityAccessManagement_GetPolicy_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/GetPolicy" + SeaweedIdentityAccessManagement_ListPolicies_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/ListPolicies" + SeaweedIdentityAccessManagement_DeletePolicy_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/DeletePolicy" + SeaweedIdentityAccessManagement_CreateServiceAccount_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/CreateServiceAccount" + SeaweedIdentityAccessManagement_UpdateServiceAccount_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/UpdateServiceAccount" + SeaweedIdentityAccessManagement_DeleteServiceAccount_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/DeleteServiceAccount" + SeaweedIdentityAccessManagement_GetServiceAccount_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/GetServiceAccount" + SeaweedIdentityAccessManagement_ListServiceAccounts_FullMethodName = "/iam_pb.SeaweedIdentityAccessManagement/ListServiceAccounts" ) // SeaweedIdentityAccessManagementClient is the client API for SeaweedIdentityAccessManagement service. @@ -57,6 +62,12 @@ type SeaweedIdentityAccessManagementClient interface { GetPolicy(ctx context.Context, in *GetPolicyRequest, opts ...grpc.CallOption) (*GetPolicyResponse, error) ListPolicies(ctx context.Context, in *ListPoliciesRequest, opts ...grpc.CallOption) (*ListPoliciesResponse, error) DeletePolicy(ctx context.Context, in *DeletePolicyRequest, opts ...grpc.CallOption) (*DeletePolicyResponse, error) + // Service Account Management + CreateServiceAccount(ctx context.Context, in *CreateServiceAccountRequest, opts ...grpc.CallOption) (*CreateServiceAccountResponse, error) + UpdateServiceAccount(ctx context.Context, in *UpdateServiceAccountRequest, opts ...grpc.CallOption) (*UpdateServiceAccountResponse, error) + DeleteServiceAccount(ctx context.Context, in *DeleteServiceAccountRequest, opts ...grpc.CallOption) (*DeleteServiceAccountResponse, error) + GetServiceAccount(ctx context.Context, in *GetServiceAccountRequest, opts ...grpc.CallOption) (*GetServiceAccountResponse, error) + ListServiceAccounts(ctx context.Context, in *ListServiceAccountsRequest, opts ...grpc.CallOption) (*ListServiceAccountsResponse, error) } type seaweedIdentityAccessManagementClient struct { @@ -207,6 +218,56 @@ func (c *seaweedIdentityAccessManagementClient) DeletePolicy(ctx context.Context return out, nil } +func (c *seaweedIdentityAccessManagementClient) CreateServiceAccount(ctx context.Context, in *CreateServiceAccountRequest, opts ...grpc.CallOption) (*CreateServiceAccountResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateServiceAccountResponse) + err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_CreateServiceAccount_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *seaweedIdentityAccessManagementClient) UpdateServiceAccount(ctx context.Context, in *UpdateServiceAccountRequest, opts ...grpc.CallOption) (*UpdateServiceAccountResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(UpdateServiceAccountResponse) + err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_UpdateServiceAccount_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *seaweedIdentityAccessManagementClient) DeleteServiceAccount(ctx context.Context, in *DeleteServiceAccountRequest, opts ...grpc.CallOption) (*DeleteServiceAccountResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DeleteServiceAccountResponse) + err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_DeleteServiceAccount_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *seaweedIdentityAccessManagementClient) GetServiceAccount(ctx context.Context, in *GetServiceAccountRequest, opts ...grpc.CallOption) (*GetServiceAccountResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetServiceAccountResponse) + err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_GetServiceAccount_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *seaweedIdentityAccessManagementClient) ListServiceAccounts(ctx context.Context, in *ListServiceAccountsRequest, opts ...grpc.CallOption) (*ListServiceAccountsResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListServiceAccountsResponse) + err := c.cc.Invoke(ctx, SeaweedIdentityAccessManagement_ListServiceAccounts_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // SeaweedIdentityAccessManagementServer is the server API for SeaweedIdentityAccessManagement service. // All implementations must embed UnimplementedSeaweedIdentityAccessManagementServer // for forward compatibility. @@ -229,6 +290,12 @@ type SeaweedIdentityAccessManagementServer interface { GetPolicy(context.Context, *GetPolicyRequest) (*GetPolicyResponse, error) ListPolicies(context.Context, *ListPoliciesRequest) (*ListPoliciesResponse, error) DeletePolicy(context.Context, *DeletePolicyRequest) (*DeletePolicyResponse, error) + // Service Account Management + CreateServiceAccount(context.Context, *CreateServiceAccountRequest) (*CreateServiceAccountResponse, error) + UpdateServiceAccount(context.Context, *UpdateServiceAccountRequest) (*UpdateServiceAccountResponse, error) + DeleteServiceAccount(context.Context, *DeleteServiceAccountRequest) (*DeleteServiceAccountResponse, error) + GetServiceAccount(context.Context, *GetServiceAccountRequest) (*GetServiceAccountResponse, error) + ListServiceAccounts(context.Context, *ListServiceAccountsRequest) (*ListServiceAccountsResponse, error) mustEmbedUnimplementedSeaweedIdentityAccessManagementServer() } @@ -281,6 +348,21 @@ func (UnimplementedSeaweedIdentityAccessManagementServer) ListPolicies(context.C func (UnimplementedSeaweedIdentityAccessManagementServer) DeletePolicy(context.Context, *DeletePolicyRequest) (*DeletePolicyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeletePolicy not implemented") } +func (UnimplementedSeaweedIdentityAccessManagementServer) CreateServiceAccount(context.Context, *CreateServiceAccountRequest) (*CreateServiceAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateServiceAccount not implemented") +} +func (UnimplementedSeaweedIdentityAccessManagementServer) UpdateServiceAccount(context.Context, *UpdateServiceAccountRequest) (*UpdateServiceAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateServiceAccount not implemented") +} +func (UnimplementedSeaweedIdentityAccessManagementServer) DeleteServiceAccount(context.Context, *DeleteServiceAccountRequest) (*DeleteServiceAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteServiceAccount not implemented") +} +func (UnimplementedSeaweedIdentityAccessManagementServer) GetServiceAccount(context.Context, *GetServiceAccountRequest) (*GetServiceAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetServiceAccount not implemented") +} +func (UnimplementedSeaweedIdentityAccessManagementServer) ListServiceAccounts(context.Context, *ListServiceAccountsRequest) (*ListServiceAccountsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListServiceAccounts not implemented") +} func (UnimplementedSeaweedIdentityAccessManagementServer) mustEmbedUnimplementedSeaweedIdentityAccessManagementServer() { } func (UnimplementedSeaweedIdentityAccessManagementServer) testEmbeddedByValue() {} @@ -555,6 +637,96 @@ func _SeaweedIdentityAccessManagement_DeletePolicy_Handler(srv interface{}, ctx return interceptor(ctx, in, info, handler) } +func _SeaweedIdentityAccessManagement_CreateServiceAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateServiceAccountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SeaweedIdentityAccessManagementServer).CreateServiceAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SeaweedIdentityAccessManagement_CreateServiceAccount_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SeaweedIdentityAccessManagementServer).CreateServiceAccount(ctx, req.(*CreateServiceAccountRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SeaweedIdentityAccessManagement_UpdateServiceAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateServiceAccountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SeaweedIdentityAccessManagementServer).UpdateServiceAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SeaweedIdentityAccessManagement_UpdateServiceAccount_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SeaweedIdentityAccessManagementServer).UpdateServiceAccount(ctx, req.(*UpdateServiceAccountRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SeaweedIdentityAccessManagement_DeleteServiceAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteServiceAccountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SeaweedIdentityAccessManagementServer).DeleteServiceAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SeaweedIdentityAccessManagement_DeleteServiceAccount_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SeaweedIdentityAccessManagementServer).DeleteServiceAccount(ctx, req.(*DeleteServiceAccountRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SeaweedIdentityAccessManagement_GetServiceAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetServiceAccountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SeaweedIdentityAccessManagementServer).GetServiceAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SeaweedIdentityAccessManagement_GetServiceAccount_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SeaweedIdentityAccessManagementServer).GetServiceAccount(ctx, req.(*GetServiceAccountRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SeaweedIdentityAccessManagement_ListServiceAccounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListServiceAccountsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SeaweedIdentityAccessManagementServer).ListServiceAccounts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SeaweedIdentityAccessManagement_ListServiceAccounts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SeaweedIdentityAccessManagementServer).ListServiceAccounts(ctx, req.(*ListServiceAccountsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // SeaweedIdentityAccessManagement_ServiceDesc is the grpc.ServiceDesc for SeaweedIdentityAccessManagement service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -618,6 +790,26 @@ var SeaweedIdentityAccessManagement_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeletePolicy", Handler: _SeaweedIdentityAccessManagement_DeletePolicy_Handler, }, + { + MethodName: "CreateServiceAccount", + Handler: _SeaweedIdentityAccessManagement_CreateServiceAccount_Handler, + }, + { + MethodName: "UpdateServiceAccount", + Handler: _SeaweedIdentityAccessManagement_UpdateServiceAccount_Handler, + }, + { + MethodName: "DeleteServiceAccount", + Handler: _SeaweedIdentityAccessManagement_DeleteServiceAccount_Handler, + }, + { + MethodName: "GetServiceAccount", + Handler: _SeaweedIdentityAccessManagement_GetServiceAccount_Handler, + }, + { + MethodName: "ListServiceAccounts", + Handler: _SeaweedIdentityAccessManagement_ListServiceAccounts_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "iam.proto",