diff options
Diffstat (limited to 'weed/credential/migration.go')
| -rw-r--r-- | weed/credential/migration.go | 221 |
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 +} |
