@@ -68,6 +68,7 @@ import (
6868 "github.com/operator-framework/operator-controller/internal/operator-controller/controllers"
6969 "github.com/operator-framework/operator-controller/internal/operator-controller/features"
7070 "github.com/operator-framework/operator-controller/internal/operator-controller/finalizers"
71+ "github.com/operator-framework/operator-controller/internal/operator-controller/proxy"
7172 "github.com/operator-framework/operator-controller/internal/operator-controller/resolve"
7273 "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/preflights/crdupgradesafety"
7374 "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/render"
@@ -219,6 +220,7 @@ func validateMetricsFlags() error {
219220 }
220221 return nil
221222}
223+
222224func run () error {
223225 setupLog .Info ("starting up the controller" , "version info" , version .String ())
224226
@@ -474,11 +476,26 @@ func run() error {
474476 }
475477
476478 certProvider := getCertificateProvider ()
479+
480+ // Read proxy configuration from environment variables
481+ var proxyConfig * proxy.Proxy
482+ httpProxy := os .Getenv ("HTTP_PROXY" )
483+ httpsProxy := os .Getenv ("HTTPS_PROXY" )
484+ noProxy := os .Getenv ("NO_PROXY" )
485+ if httpProxy != "" || httpsProxy != "" || noProxy != "" {
486+ proxyConfig = & proxy.Proxy {
487+ HTTPProxy : httpProxy ,
488+ HTTPSProxy : httpsProxy ,
489+ NoProxy : noProxy ,
490+ }
491+ }
492+
477493 regv1ManifestProvider := & applier.RegistryV1ManifestProvider {
478494 BundleRenderer : registryv1 .Renderer ,
479495 CertificateProvider : certProvider ,
480496 IsWebhookSupportEnabled : certProvider != nil ,
481497 IsSingleOwnNamespaceEnabled : features .OperatorControllerFeatureGate .Enabled (features .SingleOwnNamespaceInstallSupport ),
498+ Proxy : proxyConfig ,
482499 }
483500 var cerCfg reconcilerConfigurator
484501 if features .OperatorControllerFeatureGate .Enabled (features .BoxcutterRuntime ) {
@@ -540,6 +557,50 @@ func run() error {
540557 return err
541558 }
542559
560+ // Add a runnable to trigger reconciliation of all ClusterExtensions on startup.
561+ // This ensures existing deployments get updated when proxy configuration changes
562+ // (added, modified, or removed).
563+ if err := mgr .Add (manager .RunnableFunc (func (ctx context.Context ) error {
564+ // Wait for the cache to sync
565+ if ! mgr .GetCache ().WaitForCacheSync (ctx ) {
566+ return fmt .Errorf ("failed to wait for cache sync" )
567+ }
568+
569+ // Always trigger reconciliation on startup to handle proxy config changes
570+ if proxyConfig != nil {
571+ setupLog .Info ("proxy configuration detected, triggering reconciliation of all ClusterExtensions" ,
572+ "httpProxy" , proxy .SanitizeURL (proxyConfig .HTTPProxy ), "httpsProxy" , proxy .SanitizeURL (proxyConfig .HTTPSProxy ), "noProxy" , proxyConfig .NoProxy )
573+ } else {
574+ setupLog .Info ("no proxy configuration detected, triggering reconciliation to remove proxy vars from existing deployments" )
575+ }
576+
577+ extList := & ocv1.ClusterExtensionList {}
578+ if err := cl .List (ctx , extList ); err != nil {
579+ setupLog .Error (err , "failed to list ClusterExtensions for proxy update" )
580+ return nil // Don't fail startup
581+ }
582+
583+ for i := range extList .Items {
584+ ext := & extList .Items [i ]
585+ // Trigger reconciliation by adding an annotation
586+ if ext .Annotations == nil {
587+ ext .Annotations = make (map [string ]string )
588+ }
589+ ext .Annotations ["olm.operatorframework.io/proxy-reconcile" ] = time .Now ().Format (time .RFC3339 )
590+ if err := cl .Update (ctx , ext ); err != nil {
591+ setupLog .Error (err , "failed to trigger reconciliation for ClusterExtension" , "name" , ext .Name )
592+ // Continue with other ClusterExtensions
593+ }
594+ }
595+
596+ setupLog .Info ("triggered reconciliation for existing ClusterExtensions" , "count" , len (extList .Items ))
597+
598+ return nil
599+ })); err != nil {
600+ setupLog .Error (err , "unable to add startup reconciliation trigger" )
601+ return err
602+ }
603+
543604 setupLog .Info ("starting manager" )
544605 ctx := ctrl .SetupSignalHandler ()
545606 if err := mgr .Start (ctx ); err != nil {
@@ -625,13 +686,18 @@ func (c *boxcutterReconcilerConfigurator) Configure(ceReconciler *controllers.Cl
625686 ActionClientGetter : acg ,
626687 RevisionGenerator : rg ,
627688 }
689+ // Get the ManifestProvider to extract proxy fingerprint
690+ regv1Provider , ok := c .regv1ManifestProvider .(* applier.RegistryV1ManifestProvider )
691+ if ! ok {
692+ return fmt .Errorf ("manifest provider is not of type *applier.RegistryV1ManifestProvider" )
693+ }
628694 ceReconciler .ReconcileSteps = []controllers.ReconcileStepFunc {
629695 controllers .HandleFinalizers (c .finalizers ),
630696 controllers .MigrateStorage (storageMigrator ),
631697 controllers .RetrieveRevisionStates (revisionStatesGetter ),
632698 controllers .ResolveBundle (c .resolver , c .mgr .GetClient ()),
633699 controllers .UnpackBundle (c .imagePuller , c .imageCache ),
634- controllers .ApplyBundleWithBoxcutter (appl .Apply ),
700+ controllers .ApplyBundleWithBoxcutter (appl .Apply , regv1Provider . ProxyFingerprint ),
635701 }
636702
637703 baseDiscoveryClient , err := discovery .NewDiscoveryClientForConfig (c .mgr .GetConfig ())
0 commit comments