aboutsummaryrefslogtreecommitdiff
path: root/weed/credential/migration.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/credential/migration.go')
-rw-r--r--weed/credential/migration.go221
1 files changed, 221 insertions, 0 deletions
diff --git a/weed/credential/migration.go b/weed/credential/migration.go
new file mode 100644
index 000000000..b286bce62
--- /dev/null
+++ b/weed/credential/migration.go
@@ -0,0 +1,221 @@
+package credential
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/seaweedfs/seaweedfs/weed/glog"
+ "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
+ "github.com/seaweedfs/seaweedfs/weed/util"
+)
+
+// MigrateCredentials migrates credentials from one store to another
+func MigrateCredentials(fromStoreName, toStoreName CredentialStoreTypeName, configuration util.Configuration, fromPrefix, toPrefix string) error {
+ ctx := context.Background()
+
+ // Create source credential manager
+ fromCM, err := NewCredentialManager(fromStoreName, configuration, fromPrefix)
+ if err != nil {
+ return fmt.Errorf("failed to create source credential manager (%s): %v", fromStoreName, err)
+ }
+ defer fromCM.Shutdown()
+
+ // Create destination credential manager
+ toCM, err := NewCredentialManager(toStoreName, configuration, toPrefix)
+ if err != nil {
+ return fmt.Errorf("failed to create destination credential manager (%s): %v", toStoreName, err)
+ }
+ defer toCM.Shutdown()
+
+ // Load configuration from source
+ glog.Infof("Loading configuration from %s store...", fromStoreName)
+ config, err := fromCM.LoadConfiguration(ctx)
+ if err != nil {
+ return fmt.Errorf("failed to load configuration from source store: %v", err)
+ }
+
+ if config == nil || len(config.Identities) == 0 {
+ glog.Info("No identities found in source store")
+ return nil
+ }
+
+ glog.Infof("Found %d identities in source store", len(config.Identities))
+
+ // Migrate each identity
+ var migrated, failed int
+ for _, identity := range config.Identities {
+ glog.V(1).Infof("Migrating user: %s", identity.Name)
+
+ // Check if user already exists in destination
+ existingUser, err := toCM.GetUser(ctx, identity.Name)
+ if err != nil && err != ErrUserNotFound {
+ glog.Errorf("Failed to check if user %s exists in destination: %v", identity.Name, err)
+ failed++
+ continue
+ }
+
+ if existingUser != nil {
+ glog.Warningf("User %s already exists in destination store, skipping", identity.Name)
+ continue
+ }
+
+ // Create user in destination
+ err = toCM.CreateUser(ctx, identity)
+ if err != nil {
+ glog.Errorf("Failed to create user %s in destination store: %v", identity.Name, err)
+ failed++
+ continue
+ }
+
+ migrated++
+ glog.V(1).Infof("Successfully migrated user: %s", identity.Name)
+ }
+
+ glog.Infof("Migration completed: %d migrated, %d failed", migrated, failed)
+
+ if failed > 0 {
+ return fmt.Errorf("migration completed with %d failures", failed)
+ }
+
+ return nil
+}
+
+// ExportCredentials exports credentials from a store to a configuration
+func ExportCredentials(storeName CredentialStoreTypeName, configuration util.Configuration, prefix string) (*iam_pb.S3ApiConfiguration, error) {
+ ctx := context.Background()
+
+ // Create credential manager
+ cm, err := NewCredentialManager(storeName, configuration, prefix)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create credential manager (%s): %v", storeName, err)
+ }
+ defer cm.Shutdown()
+
+ // Load configuration
+ config, err := cm.LoadConfiguration(ctx)
+ if err != nil {
+ return nil, fmt.Errorf("failed to load configuration: %v", err)
+ }
+
+ return config, nil
+}
+
+// ImportCredentials imports credentials from a configuration to a store
+func ImportCredentials(storeName CredentialStoreTypeName, configuration util.Configuration, prefix string, config *iam_pb.S3ApiConfiguration) error {
+ ctx := context.Background()
+
+ // Create credential manager
+ cm, err := NewCredentialManager(storeName, configuration, prefix)
+ if err != nil {
+ return fmt.Errorf("failed to create credential manager (%s): %v", storeName, err)
+ }
+ defer cm.Shutdown()
+
+ // Import each identity
+ var imported, failed int
+ for _, identity := range config.Identities {
+ glog.V(1).Infof("Importing user: %s", identity.Name)
+
+ // Check if user already exists
+ existingUser, err := cm.GetUser(ctx, identity.Name)
+ if err != nil && err != ErrUserNotFound {
+ glog.Errorf("Failed to check if user %s exists: %v", identity.Name, err)
+ failed++
+ continue
+ }
+
+ if existingUser != nil {
+ glog.Warningf("User %s already exists, skipping", identity.Name)
+ continue
+ }
+
+ // Create user
+ err = cm.CreateUser(ctx, identity)
+ if err != nil {
+ glog.Errorf("Failed to create user %s: %v", identity.Name, err)
+ failed++
+ continue
+ }
+
+ imported++
+ glog.V(1).Infof("Successfully imported user: %s", identity.Name)
+ }
+
+ glog.Infof("Import completed: %d imported, %d failed", imported, failed)
+
+ if failed > 0 {
+ return fmt.Errorf("import completed with %d failures", failed)
+ }
+
+ return nil
+}
+
+// ValidateCredentials validates that all credentials in a store are accessible
+func ValidateCredentials(storeName CredentialStoreTypeName, configuration util.Configuration, prefix string) error {
+ ctx := context.Background()
+
+ // Create credential manager
+ cm, err := NewCredentialManager(storeName, configuration, prefix)
+ if err != nil {
+ return fmt.Errorf("failed to create credential manager (%s): %v", storeName, err)
+ }
+ defer cm.Shutdown()
+
+ // Load configuration
+ config, err := cm.LoadConfiguration(ctx)
+ if err != nil {
+ return fmt.Errorf("failed to load configuration: %v", err)
+ }
+
+ if config == nil || len(config.Identities) == 0 {
+ glog.Info("No identities found in store")
+ return nil
+ }
+
+ glog.Infof("Validating %d identities...", len(config.Identities))
+
+ // Validate each identity
+ var validated, failed int
+ for _, identity := range config.Identities {
+ // Check if user can be retrieved
+ user, err := cm.GetUser(ctx, identity.Name)
+ if err != nil {
+ glog.Errorf("Failed to retrieve user %s: %v", identity.Name, err)
+ failed++
+ continue
+ }
+
+ if user == nil {
+ glog.Errorf("User %s not found", identity.Name)
+ failed++
+ continue
+ }
+
+ // Validate access keys
+ for _, credential := range identity.Credentials {
+ accessKeyUser, err := cm.GetUserByAccessKey(ctx, credential.AccessKey)
+ if err != nil {
+ glog.Errorf("Failed to retrieve user by access key %s: %v", credential.AccessKey, err)
+ failed++
+ continue
+ }
+
+ if accessKeyUser == nil || accessKeyUser.Name != identity.Name {
+ glog.Errorf("Access key %s does not map to correct user %s", credential.AccessKey, identity.Name)
+ failed++
+ continue
+ }
+ }
+
+ validated++
+ glog.V(1).Infof("Successfully validated user: %s", identity.Name)
+ }
+
+ glog.Infof("Validation completed: %d validated, %d failed", validated, failed)
+
+ if failed > 0 {
+ return fmt.Errorf("validation completed with %d failures", failed)
+ }
+
+ return nil
+}