migration.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. package credential
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/seaweedfs/seaweedfs/weed/glog"
  6. "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
  7. "github.com/seaweedfs/seaweedfs/weed/util"
  8. )
  9. // MigrateCredentials migrates credentials from one store to another
  10. func MigrateCredentials(fromStoreName, toStoreName CredentialStoreTypeName, configuration util.Configuration, fromPrefix, toPrefix string) error {
  11. ctx := context.Background()
  12. // Create source credential manager
  13. fromCM, err := NewCredentialManager(fromStoreName, configuration, fromPrefix)
  14. if err != nil {
  15. return fmt.Errorf("failed to create source credential manager (%s): %v", fromStoreName, err)
  16. }
  17. defer fromCM.Shutdown()
  18. // Create destination credential manager
  19. toCM, err := NewCredentialManager(toStoreName, configuration, toPrefix)
  20. if err != nil {
  21. return fmt.Errorf("failed to create destination credential manager (%s): %v", toStoreName, err)
  22. }
  23. defer toCM.Shutdown()
  24. // Load configuration from source
  25. glog.Infof("Loading configuration from %s store...", fromStoreName)
  26. config, err := fromCM.LoadConfiguration(ctx)
  27. if err != nil {
  28. return fmt.Errorf("failed to load configuration from source store: %w", err)
  29. }
  30. if config == nil || len(config.Identities) == 0 {
  31. glog.Info("No identities found in source store")
  32. return nil
  33. }
  34. glog.Infof("Found %d identities in source store", len(config.Identities))
  35. // Migrate each identity
  36. var migrated, failed int
  37. for _, identity := range config.Identities {
  38. glog.V(1).Infof("Migrating user: %s", identity.Name)
  39. // Check if user already exists in destination
  40. existingUser, err := toCM.GetUser(ctx, identity.Name)
  41. if err != nil && err != ErrUserNotFound {
  42. glog.Errorf("Failed to check if user %s exists in destination: %v", identity.Name, err)
  43. failed++
  44. continue
  45. }
  46. if existingUser != nil {
  47. glog.Warningf("User %s already exists in destination store, skipping", identity.Name)
  48. continue
  49. }
  50. // Create user in destination
  51. err = toCM.CreateUser(ctx, identity)
  52. if err != nil {
  53. glog.Errorf("Failed to create user %s in destination store: %v", identity.Name, err)
  54. failed++
  55. continue
  56. }
  57. migrated++
  58. glog.V(1).Infof("Successfully migrated user: %s", identity.Name)
  59. }
  60. glog.Infof("Migration completed: %d migrated, %d failed", migrated, failed)
  61. if failed > 0 {
  62. return fmt.Errorf("migration completed with %d failures", failed)
  63. }
  64. return nil
  65. }
  66. // ExportCredentials exports credentials from a store to a configuration
  67. func ExportCredentials(storeName CredentialStoreTypeName, configuration util.Configuration, prefix string) (*iam_pb.S3ApiConfiguration, error) {
  68. ctx := context.Background()
  69. // Create credential manager
  70. cm, err := NewCredentialManager(storeName, configuration, prefix)
  71. if err != nil {
  72. return nil, fmt.Errorf("failed to create credential manager (%s): %v", storeName, err)
  73. }
  74. defer cm.Shutdown()
  75. // Load configuration
  76. config, err := cm.LoadConfiguration(ctx)
  77. if err != nil {
  78. return nil, fmt.Errorf("failed to load configuration: %w", err)
  79. }
  80. return config, nil
  81. }
  82. // ImportCredentials imports credentials from a configuration to a store
  83. func ImportCredentials(storeName CredentialStoreTypeName, configuration util.Configuration, prefix string, config *iam_pb.S3ApiConfiguration) error {
  84. ctx := context.Background()
  85. // Create credential manager
  86. cm, err := NewCredentialManager(storeName, configuration, prefix)
  87. if err != nil {
  88. return fmt.Errorf("failed to create credential manager (%s): %v", storeName, err)
  89. }
  90. defer cm.Shutdown()
  91. // Import each identity
  92. var imported, failed int
  93. for _, identity := range config.Identities {
  94. glog.V(1).Infof("Importing user: %s", identity.Name)
  95. // Check if user already exists
  96. existingUser, err := cm.GetUser(ctx, identity.Name)
  97. if err != nil && err != ErrUserNotFound {
  98. glog.Errorf("Failed to check if user %s exists: %v", identity.Name, err)
  99. failed++
  100. continue
  101. }
  102. if existingUser != nil {
  103. glog.Warningf("User %s already exists, skipping", identity.Name)
  104. continue
  105. }
  106. // Create user
  107. err = cm.CreateUser(ctx, identity)
  108. if err != nil {
  109. glog.Errorf("Failed to create user %s: %v", identity.Name, err)
  110. failed++
  111. continue
  112. }
  113. imported++
  114. glog.V(1).Infof("Successfully imported user: %s", identity.Name)
  115. }
  116. glog.Infof("Import completed: %d imported, %d failed", imported, failed)
  117. if failed > 0 {
  118. return fmt.Errorf("import completed with %d failures", failed)
  119. }
  120. return nil
  121. }
  122. // ValidateCredentials validates that all credentials in a store are accessible
  123. func ValidateCredentials(storeName CredentialStoreTypeName, configuration util.Configuration, prefix string) error {
  124. ctx := context.Background()
  125. // Create credential manager
  126. cm, err := NewCredentialManager(storeName, configuration, prefix)
  127. if err != nil {
  128. return fmt.Errorf("failed to create credential manager (%s): %v", storeName, err)
  129. }
  130. defer cm.Shutdown()
  131. // Load configuration
  132. config, err := cm.LoadConfiguration(ctx)
  133. if err != nil {
  134. return fmt.Errorf("failed to load configuration: %w", err)
  135. }
  136. if config == nil || len(config.Identities) == 0 {
  137. glog.Info("No identities found in store")
  138. return nil
  139. }
  140. glog.Infof("Validating %d identities...", len(config.Identities))
  141. // Validate each identity
  142. var validated, failed int
  143. for _, identity := range config.Identities {
  144. // Check if user can be retrieved
  145. user, err := cm.GetUser(ctx, identity.Name)
  146. if err != nil {
  147. glog.Errorf("Failed to retrieve user %s: %v", identity.Name, err)
  148. failed++
  149. continue
  150. }
  151. if user == nil {
  152. glog.Errorf("User %s not found", identity.Name)
  153. failed++
  154. continue
  155. }
  156. // Validate access keys
  157. for _, credential := range identity.Credentials {
  158. accessKeyUser, err := cm.GetUserByAccessKey(ctx, credential.AccessKey)
  159. if err != nil {
  160. glog.Errorf("Failed to retrieve user by access key %s: %v", credential.AccessKey, err)
  161. failed++
  162. continue
  163. }
  164. if accessKeyUser == nil || accessKeyUser.Name != identity.Name {
  165. glog.Errorf("Access key %s does not map to correct user %s", credential.AccessKey, identity.Name)
  166. failed++
  167. continue
  168. }
  169. }
  170. validated++
  171. glog.V(1).Infof("Successfully validated user: %s", identity.Name)
  172. }
  173. glog.Infof("Validation completed: %d validated, %d failed", validated, failed)
  174. if failed > 0 {
  175. return fmt.Errorf("validation completed with %d failures", failed)
  176. }
  177. return nil
  178. }