// ABOUTME: Resource management for EdgeConnect delete command with deletion execution // ABOUTME: Handles actual deletion operations with proper ordering (instances first, then app) package v1 import ( "context" "fmt" "time" "edp.buildth.ing/DevFW-CICD/edge-connect-client/v2/sdk/edgeconnect" ) // ResourceManagerInterface defines the interface for resource management type ResourceManagerInterface interface { // ExecuteDeletion executes a deletion plan ExecuteDeletion(ctx context.Context, plan *DeletionPlan) (*DeletionResult, error) } // EdgeConnectResourceManager implements resource management for EdgeConnect type EdgeConnectResourceManager struct { client EdgeConnectClientInterface logger Logger } // Logger interface for deletion logging type Logger interface { Printf(format string, v ...interface{}) } // ResourceManagerOptions configures the resource manager behavior type ResourceManagerOptions struct { // Logger for deletion operations Logger Logger } // DefaultResourceManagerOptions returns sensible defaults func DefaultResourceManagerOptions() ResourceManagerOptions { return ResourceManagerOptions{ Logger: nil, } } // NewResourceManager creates a new EdgeConnect resource manager func NewResourceManager(client EdgeConnectClientInterface, opts ...func(*ResourceManagerOptions)) ResourceManagerInterface { options := DefaultResourceManagerOptions() for _, opt := range opts { opt(&options) } return &EdgeConnectResourceManager{ client: client, logger: options.Logger, } } // WithLogger sets a logger for deletion operations func WithLogger(logger Logger) func(*ResourceManagerOptions) { return func(opts *ResourceManagerOptions) { opts.Logger = logger } } // ExecuteDeletion executes a deletion plan // Important: Instances must be deleted before the app func (rm *EdgeConnectResourceManager) ExecuteDeletion(ctx context.Context, plan *DeletionPlan) (*DeletionResult, error) { startTime := time.Now() rm.logf("Starting deletion: %s", plan.ConfigName) result := &DeletionResult{ Plan: plan, Success: true, CompletedActions: []DeletionActionResult{}, FailedActions: []DeletionActionResult{}, } // If plan is empty, return success immediately if plan.IsEmpty() { rm.logf("No resources to delete") result.Duration = time.Since(startTime) return result, nil } // Step 1: Delete all instances first for _, instance := range plan.InstancesToDelete { actionStart := time.Now() rm.logf("Deleting instance: %s", instance.Name) instanceKey := edgeconnect.AppInstanceKey{ Organization: instance.Organization, Name: instance.Name, CloudletKey: edgeconnect.CloudletKey{ Organization: instance.CloudletOrg, Name: instance.CloudletName, }, } err := rm.client.DeleteAppInstance(ctx, instanceKey, instance.Region) actionResult := DeletionActionResult{ Type: "instance", Target: instance.Name, Duration: time.Since(actionStart), } if err != nil { rm.logf("Failed to delete instance %s: %v", instance.Name, err) actionResult.Success = false actionResult.Error = err result.FailedActions = append(result.FailedActions, actionResult) result.Success = false result.Error = fmt.Errorf("failed to delete instance %s: %w", instance.Name, err) result.Duration = time.Since(startTime) return result, result.Error } rm.logf("Successfully deleted instance: %s", instance.Name) actionResult.Success = true result.CompletedActions = append(result.CompletedActions, actionResult) } // Step 2: Delete the app (only after all instances are deleted) if plan.AppToDelete != nil { actionStart := time.Now() app := plan.AppToDelete rm.logf("Deleting app: %s version %s", app.Name, app.Version) appKey := edgeconnect.AppKey{ Organization: app.Organization, Name: app.Name, Version: app.Version, } err := rm.client.DeleteApp(ctx, appKey, app.Region) actionResult := DeletionActionResult{ Type: "app", Target: fmt.Sprintf("%s:%s", app.Name, app.Version), Duration: time.Since(actionStart), } if err != nil { rm.logf("Failed to delete app %s: %v", app.Name, err) actionResult.Success = false actionResult.Error = err result.FailedActions = append(result.FailedActions, actionResult) result.Success = false result.Error = fmt.Errorf("failed to delete app %s: %w", app.Name, err) result.Duration = time.Since(startTime) return result, result.Error } rm.logf("Successfully deleted app: %s", app.Name) actionResult.Success = true result.CompletedActions = append(result.CompletedActions, actionResult) } result.Duration = time.Since(startTime) rm.logf("Deletion completed successfully in %v", result.Duration) return result, nil } // logf logs a message if a logger is configured func (rm *EdgeConnectResourceManager) logf(format string, v ...interface{}) { if rm.logger != nil { rm.logger.Printf(format, v...) } }