|
| 1 | +package migration |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "fmt" |
| 6 | + |
| 7 | + apierrors "k8s.io/apimachinery/pkg/api/errors" |
| 8 | + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
| 9 | + "k8s.io/client-go/kubernetes" |
| 10 | + "k8s.io/klog/v2" |
| 11 | + |
| 12 | + "github.com/openshift/library-go/pkg/controller/factory" |
| 13 | + "github.com/openshift/library-go/pkg/operator/events" |
| 14 | + |
| 15 | + "github.com/openshift/console-operator/pkg/api" |
| 16 | +) |
| 17 | + |
| 18 | +const ( |
| 19 | + ConversionWebhookDeploymentName = "console-conversion-webhook" |
| 20 | + ConversionWebhookServiceName = "webhook" |
| 21 | + ConversionWebhookSecretName = "webhook-serving-cert" |
| 22 | +) |
| 23 | + |
| 24 | +type MigrationCleanupController struct { |
| 25 | + kubeClient kubernetes.Interface |
| 26 | + recorder events.Recorder |
| 27 | + cleanupCompleted bool |
| 28 | +} |
| 29 | + |
| 30 | +func NewMigrationCleanupController( |
| 31 | + kubeClient kubernetes.Interface, |
| 32 | + recorder events.Recorder, |
| 33 | +) factory.Controller { |
| 34 | + c := &MigrationCleanupController{ |
| 35 | + kubeClient: kubeClient, |
| 36 | + recorder: recorder, |
| 37 | + } |
| 38 | + |
| 39 | + return factory.New(). |
| 40 | + WithSync(c.Sync). |
| 41 | + WithPostStartHooks(c.runCleanupOnce). |
| 42 | + ToController("MigrationCleanupController", recorder) |
| 43 | +} |
| 44 | + |
| 45 | +// runCleanupOnce is a post-start hook that runs the cleanup once when the controller starts |
| 46 | +func (c *MigrationCleanupController) runCleanupOnce(ctx context.Context, syncContext factory.SyncContext) error { |
| 47 | + klog.V(2).Infof("MigrationCleanupController: checking for console-conversion-webhook resources in namespace %s from 4.16 → 4.xx migration", api.OpenShiftConsoleOperatorNamespace) |
| 48 | + |
| 49 | + // Perform cleanup |
| 50 | + if err := c.cleanupConversionWebhookResources(ctx); err != nil { |
| 51 | + klog.Errorf("MigrationCleanupController: failed to cleanup conversion webhook resources: %v", err) |
| 52 | + return fmt.Errorf("failed to cleanup conversion webhook resources: %w", err) |
| 53 | + } |
| 54 | + |
| 55 | + // Mark cleanup as completed |
| 56 | + c.cleanupCompleted = true |
| 57 | + klog.V(2).Info("MigrationCleanupController: cleanup completed successfully") |
| 58 | + |
| 59 | + return nil |
| 60 | +} |
| 61 | + |
| 62 | +func (c *MigrationCleanupController) Sync(ctx context.Context, controllerContext factory.SyncContext) error { |
| 63 | + // This Sync function is kept minimal since cleanup runs via post-start hook |
| 64 | + // It will only be called if something manually adds to the queue |
| 65 | + if c.cleanupCompleted { |
| 66 | + klog.V(4).Info("MigrationCleanupController: cleanup already completed, skipping") |
| 67 | + return nil |
| 68 | + } |
| 69 | + |
| 70 | + // If for some reason the post-start hook didn't run, run cleanup here |
| 71 | + klog.V(2).Info("MigrationCleanupController: running cleanup via Sync") |
| 72 | + return c.runCleanupOnce(ctx, controllerContext) |
| 73 | +} |
| 74 | + |
| 75 | +func (c *MigrationCleanupController) cleanupConversionWebhookResources(ctx context.Context) error { |
| 76 | + var errs []error |
| 77 | + var deletedResources []string |
| 78 | + |
| 79 | + // Delete Deployment |
| 80 | + err := c.kubeClient.AppsV1().Deployments(api.OpenShiftConsoleOperatorNamespace).Delete( |
| 81 | + ctx, ConversionWebhookDeploymentName, metav1.DeleteOptions{}) |
| 82 | + if err != nil && !apierrors.IsNotFound(err) { |
| 83 | + errs = append(errs, fmt.Errorf("failed to delete deployment %s: %w", ConversionWebhookDeploymentName, err)) |
| 84 | + } else if err == nil { |
| 85 | + klog.V(4).Infof("Deleted deployment: %s/%s", api.OpenShiftConsoleOperatorNamespace, ConversionWebhookDeploymentName) |
| 86 | + deletedResources = append(deletedResources, "deployment/"+ConversionWebhookDeploymentName) |
| 87 | + } |
| 88 | + |
| 89 | + // Delete Service |
| 90 | + err = c.kubeClient.CoreV1().Services(api.OpenShiftConsoleOperatorNamespace).Delete( |
| 91 | + ctx, ConversionWebhookServiceName, metav1.DeleteOptions{}) |
| 92 | + if err != nil && !apierrors.IsNotFound(err) { |
| 93 | + errs = append(errs, fmt.Errorf("failed to delete service %s: %w", ConversionWebhookServiceName, err)) |
| 94 | + } else if err == nil { |
| 95 | + klog.V(4).Infof("Deleted service: %s/%s", api.OpenShiftConsoleOperatorNamespace, ConversionWebhookServiceName) |
| 96 | + deletedResources = append(deletedResources, "service/"+ConversionWebhookServiceName) |
| 97 | + } |
| 98 | + |
| 99 | + // Delete Secret |
| 100 | + err = c.kubeClient.CoreV1().Secrets(api.OpenShiftConsoleOperatorNamespace).Delete( |
| 101 | + ctx, ConversionWebhookSecretName, metav1.DeleteOptions{}) |
| 102 | + if err != nil && !apierrors.IsNotFound(err) { |
| 103 | + errs = append(errs, fmt.Errorf("failed to delete secret %s: %w", ConversionWebhookSecretName, err)) |
| 104 | + } else if err == nil { |
| 105 | + klog.V(4).Infof("Deleted secret: %s/%s", api.OpenShiftConsoleOperatorNamespace, ConversionWebhookSecretName) |
| 106 | + deletedResources = append(deletedResources, "secret/"+ConversionWebhookSecretName) |
| 107 | + } |
| 108 | + |
| 109 | + // Log summary and emit event if any resources were actually deleted |
| 110 | + if len(deletedResources) > 0 { |
| 111 | + klog.Infof("MigrationCleanupController: successfully deleted console-conversion-webhook resources from namespace %s: %v", api.OpenShiftConsoleOperatorNamespace, deletedResources) |
| 112 | + c.recorder.Eventf("MigrationCleanupCompleted", "Successfully cleaned up console-conversion-webhook resources from namespace %s: %v", api.OpenShiftConsoleOperatorNamespace, deletedResources) |
| 113 | + } else { |
| 114 | + klog.V(4).Infof("MigrationCleanupController: no console-conversion-webhook resources found to clean up in namespace %s", api.OpenShiftConsoleOperatorNamespace) |
| 115 | + } |
| 116 | + |
| 117 | + if len(errs) > 0 { |
| 118 | + return fmt.Errorf("cleanup errors: %v", errs) |
| 119 | + } |
| 120 | + |
| 121 | + return nil |
| 122 | +} |
0 commit comments