2025-10-20 15:15:23 +02:00
|
|
|
// 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"
|
|
|
|
|
|
2025-10-21 11:40:35 +02:00
|
|
|
"edp.buildth.ing/DevFW-CICD/edge-connect-client/v2/sdk/edgeconnect"
|
2025-10-20 15:15:23 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// 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...)
|
|
|
|
|
}
|
|
|
|
|
}
|