diff --git a/cmd/kubernetes/proxy-webhook/main.go b/cmd/kubernetes/proxy-webhook/main.go index 393630b7a8..e3eba26e75 100644 --- a/cmd/kubernetes/proxy-webhook/main.go +++ b/cmd/kubernetes/proxy-webhook/main.go @@ -17,15 +17,39 @@ limitations under the License. package main import ( + "os" + "github.com/tektoncd/operator/pkg/reconciler/proxy" "knative.dev/pkg/injection" "knative.dev/pkg/injection/sharedmain" + "knative.dev/pkg/signals" + kwebhook "knative.dev/pkg/webhook" "knative.dev/pkg/webhook/certificates" ) func main() { - sharedmain.WebhookMainWithConfig(proxy.Getctx(), "webhook-operator", - injection.ParseAndGetRESTConfigOrDie(), + serviceName := os.Getenv("WEBHOOK_SERVICE_NAME") + if serviceName == "" { + serviceName = "tekton-operator-proxy-webhook" + } + secretName := os.Getenv("WEBHOOK_SECRET_NAME") + if secretName == "" { + secretName = "proxy-webhook-certs" + } + systemNamespace := os.Getenv("SYSTEM_NAMESPACE") + + cfg := injection.ParseAndGetRESTConfigOrDie() + ctx := kwebhook.WithOptions( + injection.WithNamespaceScope(signals.NewContext(), systemNamespace), + kwebhook.Options{ + ServiceName: serviceName, + Port: 8443, + SecretName: secretName, + }, + ) + + sharedmain.WebhookMainWithConfig(ctx, "webhook-operator", + cfg, certificates.NewController, proxy.NewProxyDefaultingAdmissionController, ) diff --git a/cmd/openshift/operator/kodata/webhook/webhook.yaml b/cmd/openshift/operator/kodata/webhook/webhook.yaml index 3732d74916..58e8e8f720 100644 --- a/cmd/openshift/operator/kodata/webhook/webhook.yaml +++ b/cmd/openshift/operator/kodata/webhook/webhook.yaml @@ -29,6 +29,10 @@ rules: - apiGroups: ["security.openshift.io"] resources: ["securitycontextconstraints"] verbs: ["get", "list", "watch"] + # Required to read the OpenShift APIServer TLS profile at startup + - apiGroups: ["config.openshift.io"] + resources: ["apiservers"] + verbs: ["get", "list", "watch"] --- diff --git a/cmd/openshift/proxy-webhook/main.go b/cmd/openshift/proxy-webhook/main.go index 0c6325981a..eb9a21bed1 100644 --- a/cmd/openshift/proxy-webhook/main.go +++ b/cmd/openshift/proxy-webhook/main.go @@ -18,14 +18,19 @@ package main import ( "context" + "log" + "os" "github.com/tektoncd/operator/pkg/reconciler/openshift/annotation" + occommon "github.com/tektoncd/operator/pkg/reconciler/openshift/common" "github.com/tektoncd/operator/pkg/reconciler/openshift/namespace" "github.com/tektoncd/operator/pkg/reconciler/proxy" "knative.dev/pkg/configmap" "knative.dev/pkg/controller" "knative.dev/pkg/injection" "knative.dev/pkg/injection/sharedmain" + "knative.dev/pkg/signals" + kwebhook "knative.dev/pkg/webhook" "knative.dev/pkg/webhook/certificates" ) @@ -50,8 +55,64 @@ func newAnnotationDefaultingAdmissionController(ctx context.Context, cmw configm } func main() { - sharedmain.WebhookMainWithConfig(proxy.Getctx(), "webhook-operator", - injection.ParseAndGetRESTConfigOrDie(), + serviceName := os.Getenv("WEBHOOK_SERVICE_NAME") + if serviceName == "" { + serviceName = "tekton-operator-proxy-webhook" + } + secretName := os.Getenv("WEBHOOK_SECRET_NAME") + if secretName == "" { + secretName = "proxy-webhook-certs" + } + + cfg := injection.ParseAndGetRESTConfigOrDie() + signalCtx := signals.NewContext() + + if err := occommon.SetupAPIServerTLSWatch(signalCtx, cfg, func() { + log.Println("APIServer TLS profile changed — restarting proxy webhook to apply updated settings") + os.Exit(1) + }); err != nil { + if os.Getenv(occommon.SkipAPIServerTLSWatch) == "true" { + log.Printf("WARNING: APIServer TLS watch not available, using Knative defaults: %v", err) + } else { + log.Fatalf("Failed to set up APIServer TLS watch: %v", err) + } + } + + if tlsProfile, err := occommon.GetTLSProfileFromAPIServer(signalCtx); err != nil { + log.Printf("WARNING: could not read APIServer TLS profile, using Knative defaults: %v", err) + } else if tlsProfile != nil { + if envVars, err := occommon.TLSEnvVarsFromProfile(tlsProfile); err != nil { + log.Printf("WARNING: could not convert TLS profile, using Knative defaults: %v", err) + } else if envVars != nil { + // Knative only accepts "1.2" or "1.3"; skip if the profile allows older versions + // (e.g. OpenShift "Old" profile uses VersionTLS10). The webhook will then fall + // back to Knative's default minimum of 1.2, which is always safe for admission webhooks. + if envVars.MinVersion == "1.2" || envVars.MinVersion == "1.3" { + os.Setenv("WEBHOOK_TLS_MIN_VERSION", envVars.MinVersion) + } + if envVars.CipherSuites != "" { + os.Setenv("WEBHOOK_TLS_CIPHER_SUITES", envVars.CipherSuites) + } + if envVars.CurvePreferences != "" { + os.Setenv("WEBHOOK_TLS_CURVE_PREFERENCES", envVars.CurvePreferences) + } + } + } + + // Inline the context setup (same as proxy.Getctx but reuses the signal + // context already created above instead of calling signals.NewContext again). + systemNamespace := os.Getenv("SYSTEM_NAMESPACE") + ctx := kwebhook.WithOptions( + injection.WithNamespaceScope(signalCtx, systemNamespace), + kwebhook.Options{ + ServiceName: serviceName, + Port: 8443, + SecretName: secretName, + }, + ) + + sharedmain.WebhookMainWithConfig(ctx, "webhook-operator", + cfg, certificates.NewController, proxy.NewProxyDefaultingAdmissionController, newAnnotationDefaultingAdmissionController, diff --git a/cmd/openshift/webhook/main.go b/cmd/openshift/webhook/main.go index 5b413d5fd3..14c2a5c52a 100644 --- a/cmd/openshift/webhook/main.go +++ b/cmd/openshift/webhook/main.go @@ -18,8 +18,10 @@ package main import ( "context" + "log" "os" + occommon "github.com/tektoncd/operator/pkg/reconciler/openshift/common" "github.com/tektoncd/operator/pkg/webhook" "knative.dev/pkg/injection" "knative.dev/pkg/injection/sharedmain" @@ -39,13 +41,60 @@ func main() { secretName = "tekton-operator-webhook-certs" } - //Set up a signal context with our webhook options - ctx := kwebhook.WithOptions(signals.NewContext(), kwebhook.Options{ + // cfg is obtained before signals.NewContext so it's available for the TLS watch setup. + cfg := injection.ParseAndGetRESTConfigOrDie() + signalCtx := signals.NewContext() + + // Set up the APIServer TLS watch using the same helper as the TektonConfig controller. + // - Populates the shared lister so GetTLSProfileFromAPIServer works below. + // - Calls os.Exit(1) when the TLS profile changes; Kubernetes restartPolicy: Always + // restarts the container so the new instance picks up the updated profile. + if err := occommon.SetupAPIServerTLSWatch(signalCtx, cfg, func() { + log.Println("APIServer TLS profile changed — restarting webhook to apply updated settings") + os.Exit(1) + }); err != nil { + // On OpenShift clusters the APIServer resource should always exist. + // SKIP_APISERVER_TLS_WATCH=true is an escape hatch for tests/edge cases — + // same pattern as the TektonConfig controller. + if os.Getenv(occommon.SkipAPIServerTLSWatch) == "true" { + log.Printf("WARNING: APIServer TLS watch not available, using Knative defaults: %v", err) + } else { + log.Fatalf("Failed to set up APIServer TLS watch: %v", err) + } + } + + // Read the current TLS profile and inject as WEBHOOK_TLS_* env vars. + // Knative's DefaultConfigFromEnv("WEBHOOK_") inside webhook.New() reads these automatically. + // TLSEnvVarsFromProfile produces "1.2"/"1.3" and comma-separated IANA cipher names — + // exactly the format Knative expects. + if tlsProfile, err := occommon.GetTLSProfileFromAPIServer(signalCtx); err != nil { + log.Printf("WARNING: could not read APIServer TLS profile, using Knative defaults: %v", err) + } else if tlsProfile != nil { + if envVars, err := occommon.TLSEnvVarsFromProfile(tlsProfile); err != nil { + log.Printf("WARNING: could not convert TLS profile, using Knative defaults: %v", err) + } else if envVars != nil { + // Knative only accepts "1.2" or "1.3"; skip if the profile allows older versions + // (e.g. OpenShift "Old" profile uses VersionTLS10). The webhook will then fall + // back to Knative's default minimum of 1.2, which is always safe for admission webhooks. + if envVars.MinVersion == "1.2" || envVars.MinVersion == "1.3" { + os.Setenv("WEBHOOK_TLS_MIN_VERSION", envVars.MinVersion) + } + if envVars.CipherSuites != "" { + os.Setenv("WEBHOOK_TLS_CIPHER_SUITES", envVars.CipherSuites) + } + if envVars.CurvePreferences != "" { + os.Setenv("WEBHOOK_TLS_CURVE_PREFERENCES", envVars.CurvePreferences) + } + } + } + + // kwebhook.Options is unchanged — no TLS fields needed. + // Knative reads the WEBHOOK_TLS_* env vars we just set inside webhook.New(). + ctx := kwebhook.WithOptions(signalCtx, kwebhook.Options{ ServiceName: serviceName, Port: 8443, SecretName: secretName, }) - cfg := injection.ParseAndGetRESTConfigOrDie() ctx, _ = injection.EnableInjectionOrDie(ctx, cfg) webhook.CreateWebhookResources(ctx) webhook.SetTypes("openshift") diff --git a/pkg/reconciler/openshift/common/apiserver_watch.go b/pkg/reconciler/openshift/common/apiserver_watch.go new file mode 100644 index 0000000000..d0fa1e2698 --- /dev/null +++ b/pkg/reconciler/openshift/common/apiserver_watch.go @@ -0,0 +1,135 @@ +/* +Copyright 2026 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "context" + "fmt" + "time" + + configv1 "github.com/openshift/api/config/v1" + openshiftconfigclient "github.com/openshift/client-go/config/clientset/versioned" + configinformers "github.com/openshift/client-go/config/informers/externalversions" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/cache" + "knative.dev/pkg/logging" +) + +// SkipAPIServerTLSWatch is the env var name used as an escape hatch to suppress +// a fatal error when the APIServer resource is unreachable (e.g. in tests). +// Both the operator controller and the webhook check this variable. +const SkipAPIServerTLSWatch = "SKIP_APISERVER_TLS_WATCH" + +// SetupAPIServerTLSWatch creates an OpenShift APIServer informer, registers +// onTLSChange to be called whenever the TLS security profile changes, waits for +// the informer cache to sync, and then sets the shared APIServer lister so that +// GetTLSProfileFromAPIServer works in the calling process. +// +// This function is intentionally generic so it can be used by any process: +// - The operator controller passes impl.EnqueueKey(...) as onTLSChange. +// - The webhook binary passes os.Exit(1) as onTLSChange (restarts to pick up new TLS config). +func SetupAPIServerTLSWatch(ctx context.Context, cfg *rest.Config, onTLSChange func()) error { + logger := logging.FromContext(ctx) + + configClient, err := openshiftconfigclient.NewForConfig(cfg) + if err != nil { + return fmt.Errorf("creating OpenShift config client: %w", err) + } + + // Verify we can access the APIServer resource before starting the informer. + if _, err := configClient.ConfigV1().APIServers().Get(ctx, "cluster", metav1.GetOptions{}); err != nil { + return fmt.Errorf("accessing APIServer resource: %w", err) + } + + // 30-minute resync is sufficient; the watch mechanism handles real-time updates. + factory := configinformers.NewSharedInformerFactory(configClient, 30*time.Minute) + apiServerInformer := factory.Config().V1().APIServers() + + if _, err := apiServerInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + UpdateFunc: func(oldObj, newObj interface{}) { + oldAPIServer, ok := oldObj.(*configv1.APIServer) + if !ok { + return + } + newAPIServer, ok := newObj.(*configv1.APIServer) + if !ok { + return + } + if !APIServerTLSProfileChanged(oldAPIServer, newAPIServer) { + return + } + logger.Info("APIServer TLS security profile changed") + onTLSChange() + }, + }); err != nil { + return fmt.Errorf("adding APIServer event handler: %w", err) + } + + factory.Start(ctx.Done()) + + if !cache.WaitForCacheSync(ctx.Done(), apiServerInformer.Informer().HasSynced) { + return fmt.Errorf("failed to sync APIServer informer cache") + } + + // Populate the shared lister so GetTLSProfileFromAPIServer works in this process. + SetSharedAPIServerLister(apiServerInformer.Lister(), configClient) + return nil +} + +// APIServerTLSProfileChanged reports whether the TLS security profile has changed +// between two APIServer resources. +func APIServerTLSProfileChanged(old, new *configv1.APIServer) bool { + oldProfile := old.Spec.TLSSecurityProfile + newProfile := new.Spec.TLSSecurityProfile + + if oldProfile == nil && newProfile == nil { + return false + } + if (oldProfile == nil) != (newProfile == nil) { + return true + } + if oldProfile.Type != newProfile.Type { + return true + } + if oldProfile.Type == configv1.TLSProfileCustomType { + return !customTLSProfilesEqual(oldProfile.Custom, newProfile.Custom) + } + return false +} + +// customTLSProfilesEqual compares two custom TLS profile specs for equality. +func customTLSProfilesEqual(old, new *configv1.CustomTLSProfile) bool { + if old == nil && new == nil { + return true + } + if (old == nil) != (new == nil) { + return false + } + if old.MinTLSVersion != new.MinTLSVersion { + return false + } + if len(old.Ciphers) != len(new.Ciphers) { + return false + } + for i := range old.Ciphers { + if old.Ciphers[i] != new.Ciphers[i] { + return false + } + } + return true +} diff --git a/pkg/reconciler/openshift/common/apiserver_watch_test.go b/pkg/reconciler/openshift/common/apiserver_watch_test.go new file mode 100644 index 0000000000..41bc2a0a18 --- /dev/null +++ b/pkg/reconciler/openshift/common/apiserver_watch_test.go @@ -0,0 +1,87 @@ +/* +Copyright 2026 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "testing" + + configv1 "github.com/openshift/api/config/v1" +) + +func TestAPIServerTLSProfileChanged_BothNil(t *testing.T) { + old := &configv1.APIServer{} + new := &configv1.APIServer{} + if APIServerTLSProfileChanged(old, new) { + t.Error("expected no change when both TLS profiles are nil") + } +} + +func TestAPIServerTLSProfileChanged_TypeChange(t *testing.T) { + old := &configv1.APIServer{Spec: configv1.APIServerSpec{ + TLSSecurityProfile: &configv1.TLSSecurityProfile{Type: configv1.TLSProfileIntermediateType}, + }} + new := &configv1.APIServer{Spec: configv1.APIServerSpec{ + TLSSecurityProfile: &configv1.TLSSecurityProfile{Type: configv1.TLSProfileModernType}, + }} + if !APIServerTLSProfileChanged(old, new) { + t.Error("expected change when profile type differs") + } +} + +func TestAPIServerTLSProfileChanged_NilToNonNil(t *testing.T) { + old := &configv1.APIServer{} + new := &configv1.APIServer{Spec: configv1.APIServerSpec{ + TLSSecurityProfile: &configv1.TLSSecurityProfile{Type: configv1.TLSProfileModernType}, + }} + if !APIServerTLSProfileChanged(old, new) { + t.Error("expected change when old is nil and new is non-nil") + } +} + +func TestAPIServerTLSProfileChanged_SameType(t *testing.T) { + old := &configv1.APIServer{Spec: configv1.APIServerSpec{ + TLSSecurityProfile: &configv1.TLSSecurityProfile{Type: configv1.TLSProfileIntermediateType}, + }} + new := &configv1.APIServer{Spec: configv1.APIServerSpec{ + TLSSecurityProfile: &configv1.TLSSecurityProfile{Type: configv1.TLSProfileIntermediateType}, + }} + if APIServerTLSProfileChanged(old, new) { + t.Error("expected no change for same named profile type") + } +} + +func TestAPIServerTLSProfileChanged_CustomCipherChange(t *testing.T) { + customOld := &configv1.TLSSecurityProfile{ + Type: configv1.TLSProfileCustomType, + Custom: &configv1.CustomTLSProfile{TLSProfileSpec: configv1.TLSProfileSpec{ + MinTLSVersion: configv1.VersionTLS12, + Ciphers: []string{"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"}, + }}, + } + customNew := &configv1.TLSSecurityProfile{ + Type: configv1.TLSProfileCustomType, + Custom: &configv1.CustomTLSProfile{TLSProfileSpec: configv1.TLSProfileSpec{ + MinTLSVersion: configv1.VersionTLS12, + Ciphers: []string{"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"}, + }}, + } + old := &configv1.APIServer{Spec: configv1.APIServerSpec{TLSSecurityProfile: customOld}} + new := &configv1.APIServer{Spec: configv1.APIServerSpec{TLSSecurityProfile: customNew}} + if !APIServerTLSProfileChanged(old, new) { + t.Error("expected change when custom cipher differs") + } +} diff --git a/pkg/reconciler/openshift/tektonconfig/controller.go b/pkg/reconciler/openshift/tektonconfig/controller.go index 454503d788..d873f265f3 100644 --- a/pkg/reconciler/openshift/tektonconfig/controller.go +++ b/pkg/reconciler/openshift/tektonconfig/controller.go @@ -18,19 +18,13 @@ package tektonconfig import ( "context" - "fmt" "os" - "time" - configv1 "github.com/openshift/api/config/v1" - openshiftconfigclient "github.com/openshift/client-go/config/clientset/versioned" - configinformers "github.com/openshift/client-go/config/informers/externalversions" "github.com/tektoncd/operator/pkg/apis/operator/v1alpha1" openshiftpipelinesascodeinformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/openshiftpipelinesascode" tektonAddoninformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonaddon" occommon "github.com/tektoncd/operator/pkg/reconciler/openshift/common" "github.com/tektoncd/operator/pkg/reconciler/shared/tektonconfig" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/tools/cache" "knative.dev/pkg/configmap" @@ -59,11 +53,10 @@ func NewController(ctx context.Context, cmw configmap.Watcher) *controller.Impl // Setup APIServer TLS profile watcher // When the cluster's TLS security profile changes, enqueue TektonConfig for reconciliation - const skipAPIServerWatch = "SKIP_APISERVER_TLS_WATCH" if err := setupAPIServerTLSWatch(ctx, ctrl); err != nil { // On OpenShift clusters the APIServer resource should always exist. // This env var is an escape hatch for edge cases and must be explicitly enabled. - if os.Getenv(skipAPIServerWatch) == "true" { + if os.Getenv(occommon.SkipAPIServerTLSWatch) == "true" { logger.Warnf("APIServer TLS profile watch not enabled: %v", err) } else { logger.Panicf("Couldn't setup APIServer TLS profile watch: %v", err) @@ -73,121 +66,13 @@ func NewController(ctx context.Context, cmw configmap.Watcher) *controller.Impl return ctrl } -// setupAPIServerTLSWatch sets up a watch on the OpenShift APIServer resource -// to monitor TLS security profile changes. When changes are detected, it enqueues +// setupAPIServerTLSWatch sets up a watch on the OpenShift APIServer resource to +// monitor TLS security profile changes. When changes are detected, it enqueues // TektonConfig for reconciliation so TLS config can be propagated to components. func setupAPIServerTLSWatch(ctx context.Context, impl *controller.Impl) error { logger := logging.FromContext(ctx) - restConfig := injection.GetConfig(ctx) - - // Create OpenShift config client - configClient, err := openshiftconfigclient.NewForConfig(restConfig) - if err != nil { - return err - } - - // Check if we can access the APIServer resource - _, err = configClient.ConfigV1().APIServers().Get(ctx, "cluster", metav1.GetOptions{}) - if err != nil { - return err - } - - // Create a shared informer factory for OpenShift config resources. - // 30 minute resync is sufficient since the APIServer resource rarely changes - // and the watch mechanism handles real-time updates. - configInformerFactory := configinformers.NewSharedInformerFactory(configClient, 30*time.Minute) - - // Get the APIServer informer - apiServerInformer := configInformerFactory.Config().V1().APIServers() - - // Add event handler to watch for APIServer changes - if _, err := apiServerInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - UpdateFunc: func(oldObj, newObj interface{}) { - oldAPIServer, ok := oldObj.(*configv1.APIServer) - if !ok { - return - } - newAPIServer, ok := newObj.(*configv1.APIServer) - if !ok { - return - } - - // Check if TLS security profile actually changed - if !tlsProfileChanged(oldAPIServer, newAPIServer) { - return - } - - logger.Info("APIServer TLS security profile changed, triggering TektonConfig reconciliation") - impl.EnqueueKey(types.NamespacedName{Name: v1alpha1.ConfigResourceName}) - }, - }); err != nil { - return err - } - - // Start the informer factory - configInformerFactory.Start(ctx.Done()) - - // Wait for caches to sync - if !cache.WaitForCacheSync(ctx.Done(), apiServerInformer.Informer().HasSynced) { - return fmt.Errorf("failed to sync APIServer informer cache") - } - - // Share the lister with other components so they don't need to create their own informers - occommon.SetSharedAPIServerLister(apiServerInformer.Lister(), configClient) - - return nil -} - -// tlsProfileChanged checks if the TLS security profile has changed between two APIServer resources -func tlsProfileChanged(old, new *configv1.APIServer) bool { - oldProfile := old.Spec.TLSSecurityProfile - newProfile := new.Spec.TLSSecurityProfile - - // Both nil - no change - if oldProfile == nil && newProfile == nil { - return false - } - - // One nil, one not - changed - if (oldProfile == nil) != (newProfile == nil) { - return true - } - - // Different types - changed - if oldProfile.Type != newProfile.Type { - return true - } - - // For custom profiles, check the actual settings - if oldProfile.Type == configv1.TLSProfileCustomType { - return !customProfilesEqual(oldProfile.Custom, newProfile.Custom) - } - - // For predefined profiles (Old, Intermediate, Modern), type change is sufficient - return false -} - -// customProfilesEqual checks if two custom TLS profiles are equal -func customProfilesEqual(old, new *configv1.CustomTLSProfile) bool { - if old == nil && new == nil { - return true - } - if (old == nil) != (new == nil) { - return false - } - - if old.MinTLSVersion != new.MinTLSVersion { - return false - } - - if len(old.Ciphers) != len(new.Ciphers) { - return false - } - for i := range old.Ciphers { - if old.Ciphers[i] != new.Ciphers[i] { - return false - } - } - - return true + return occommon.SetupAPIServerTLSWatch(ctx, injection.GetConfig(ctx), func() { + logger.Info("APIServer TLS security profile changed, triggering TektonConfig reconciliation") + impl.EnqueueKey(types.NamespacedName{Name: v1alpha1.ConfigResourceName}) + }) } diff --git a/pkg/reconciler/openshift/tektonconfig/controller_test.go b/pkg/reconciler/openshift/tektonconfig/controller_test.go index 44c715e632..be35df8bb3 100644 --- a/pkg/reconciler/openshift/tektonconfig/controller_test.go +++ b/pkg/reconciler/openshift/tektonconfig/controller_test.go @@ -20,6 +20,7 @@ import ( "testing" configv1 "github.com/openshift/api/config/v1" + occommon "github.com/tektoncd/operator/pkg/reconciler/openshift/common" "gotest.tools/v3/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -198,7 +199,7 @@ func TestTlsProfileChanged(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "cluster"}, Spec: configv1.APIServerSpec{TLSSecurityProfile: tt.new}, } - assert.Equal(t, tlsProfileChanged(old, new), tt.expected) + assert.Equal(t, occommon.APIServerTLSProfileChanged(old, new), tt.expected) }) } } diff --git a/pkg/reconciler/openshift/tektonpipeline/extension.go b/pkg/reconciler/openshift/tektonpipeline/extension.go index 0e6d3322d3..c01e14ab8a 100644 --- a/pkg/reconciler/openshift/tektonpipeline/extension.go +++ b/pkg/reconciler/openshift/tektonpipeline/extension.go @@ -72,6 +72,7 @@ func (oe openshiftExtension) Transformers(comp v1alpha1.TektonComponent) []mf.Tr occommon.RemoveRunAsUserForStatefulSet(tektonRemoteResolversControllerName), occommon.ApplyCABundlesForStatefulSet(tektonPipelinesControllerName), occommon.ApplyCABundlesForStatefulSet(tektonRemoteResolversControllerName), + common.ReplaceNamespaceInClusterRoleBinding(comp.GetSpec().GetTargetNamespace()), } return trns } diff --git a/pkg/reconciler/proxy/controller.go b/pkg/reconciler/proxy/controller.go index 39512e11e2..78641eff02 100644 --- a/pkg/reconciler/proxy/controller.go +++ b/pkg/reconciler/proxy/controller.go @@ -18,13 +18,9 @@ package proxy import ( "context" - "os" "knative.dev/pkg/configmap" - "knative.dev/pkg/injection" - "knative.dev/pkg/signals" - // Injection stuff "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/tools/cache" @@ -100,29 +96,6 @@ func NewAdmissionController( return c } -func Getctx() context.Context { - serviceName := os.Getenv("WEBHOOK_SERVICE_NAME") - if serviceName == "" { - serviceName = "tekton-operator-proxy-webhook" - } - - secretName := os.Getenv("WEBHOOK_SECRET_NAME") - if secretName == "" { - secretName = "proxy-webhook-certs" - } - systemNamespace := os.Getenv("SYSTEM_NAMESPACE") - - // Scope informers to the webhook's namespace instead of cluster-wide - ctx := injection.WithNamespaceScope(signals.NewContext(), systemNamespace) - - // Set up a signal context with our webhook options - ctx = webhook.WithOptions(ctx, webhook.Options{ - ServiceName: serviceName, - Port: 8443, - SecretName: secretName, - }) - return ctx -} func NewProxyDefaultingAdmissionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {