Skip to content

Commit af7145f

Browse files
jkhelilcursoragent
andcommitted
feat(proxy-webhook/tls): read OpenShift APIServer TLS profile at startup, inject as WEBHOOK_TLS_* env vars
Same pattern as cmd/openshift/webhook/main.go: cfg and signalCtx are created first, SetupAPIServerTLSWatch populates the shared lister and watches for TLS profile changes (os.Exit(1) on change), then GetTLSProfileFromAPIServer + TLSEnvVarsFromProfile inject WEBHOOK_TLS_* env vars before Knative bootstraps. Both openshift and kubernetes proxy-webhook/main.go now inline the context setup (namespace scope + kwebhook.WithOptions) directly, the same way the regular webhooks do. proxy.Getctx() is removed from controller.go — it was only a thin wrapper around signals.NewContext() + webhook.WithOptions and is no longer needed. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 413609b commit af7145f

6 files changed

Lines changed: 98 additions & 32 deletions

File tree

cmd/kubernetes/proxy-webhook/main.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,39 @@ limitations under the License.
1717
package main
1818

1919
import (
20+
"os"
21+
2022
"github.com/tektoncd/operator/pkg/reconciler/proxy"
2123
"knative.dev/pkg/injection"
2224
"knative.dev/pkg/injection/sharedmain"
25+
"knative.dev/pkg/signals"
26+
kwebhook "knative.dev/pkg/webhook"
2327
"knative.dev/pkg/webhook/certificates"
2428
)
2529

2630
func main() {
27-
sharedmain.WebhookMainWithConfig(proxy.Getctx(), "webhook-operator",
28-
injection.ParseAndGetRESTConfigOrDie(),
31+
serviceName := os.Getenv("WEBHOOK_SERVICE_NAME")
32+
if serviceName == "" {
33+
serviceName = "tekton-operator-proxy-webhook"
34+
}
35+
secretName := os.Getenv("WEBHOOK_SECRET_NAME")
36+
if secretName == "" {
37+
secretName = "proxy-webhook-certs"
38+
}
39+
systemNamespace := os.Getenv("SYSTEM_NAMESPACE")
40+
41+
cfg := injection.ParseAndGetRESTConfigOrDie()
42+
ctx := kwebhook.WithOptions(
43+
injection.WithNamespaceScope(signals.NewContext(), systemNamespace),
44+
kwebhook.Options{
45+
ServiceName: serviceName,
46+
Port: 8443,
47+
SecretName: secretName,
48+
},
49+
)
50+
51+
sharedmain.WebhookMainWithConfig(ctx, "webhook-operator",
52+
cfg,
2953
certificates.NewController,
3054
proxy.NewProxyDefaultingAdmissionController,
3155
)

cmd/openshift/operator/kodata/webhook/webhook.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ rules:
2929
- apiGroups: ["security.openshift.io"]
3030
resources: ["securitycontextconstraints"]
3131
verbs: ["get", "list", "watch"]
32+
# Required to read the OpenShift APIServer TLS profile at startup
33+
- apiGroups: ["config.openshift.io"]
34+
resources: ["apiservers"]
35+
verbs: ["get", "list", "watch"]
3236

3337
---
3438

cmd/openshift/proxy-webhook/main.go

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,19 @@ package main
1818

1919
import (
2020
"context"
21+
"log"
22+
"os"
2123

2224
"github.com/tektoncd/operator/pkg/reconciler/openshift/annotation"
25+
occommon "github.com/tektoncd/operator/pkg/reconciler/openshift/common"
2326
"github.com/tektoncd/operator/pkg/reconciler/openshift/namespace"
2427
"github.com/tektoncd/operator/pkg/reconciler/proxy"
2528
"knative.dev/pkg/configmap"
2629
"knative.dev/pkg/controller"
2730
"knative.dev/pkg/injection"
2831
"knative.dev/pkg/injection/sharedmain"
32+
"knative.dev/pkg/signals"
33+
kwebhook "knative.dev/pkg/webhook"
2934
"knative.dev/pkg/webhook/certificates"
3035
)
3136

@@ -50,8 +55,64 @@ func newAnnotationDefaultingAdmissionController(ctx context.Context, cmw configm
5055
}
5156

5257
func main() {
53-
sharedmain.WebhookMainWithConfig(proxy.Getctx(), "webhook-operator",
54-
injection.ParseAndGetRESTConfigOrDie(),
58+
serviceName := os.Getenv("WEBHOOK_SERVICE_NAME")
59+
if serviceName == "" {
60+
serviceName = "tekton-operator-proxy-webhook"
61+
}
62+
secretName := os.Getenv("WEBHOOK_SECRET_NAME")
63+
if secretName == "" {
64+
secretName = "proxy-webhook-certs"
65+
}
66+
67+
cfg := injection.ParseAndGetRESTConfigOrDie()
68+
signalCtx := signals.NewContext()
69+
70+
if err := occommon.SetupAPIServerTLSWatch(signalCtx, cfg, func() {
71+
log.Println("APIServer TLS profile changed — restarting proxy webhook to apply updated settings")
72+
os.Exit(1)
73+
}); err != nil {
74+
if os.Getenv(occommon.SkipAPIServerTLSWatch) == "true" {
75+
log.Printf("WARNING: APIServer TLS watch not available, using Knative defaults: %v", err)
76+
} else {
77+
log.Fatalf("Failed to set up APIServer TLS watch: %v", err)
78+
}
79+
}
80+
81+
if tlsProfile, err := occommon.GetTLSProfileFromAPIServer(signalCtx); err != nil {
82+
log.Printf("WARNING: could not read APIServer TLS profile, using Knative defaults: %v", err)
83+
} else if tlsProfile != nil {
84+
if envVars, err := occommon.TLSEnvVarsFromProfile(tlsProfile); err != nil {
85+
log.Printf("WARNING: could not convert TLS profile, using Knative defaults: %v", err)
86+
} else if envVars != nil {
87+
// Knative only accepts "1.2" or "1.3"; skip if the profile allows older versions
88+
// (e.g. OpenShift "Old" profile uses VersionTLS10). The webhook will then fall
89+
// back to Knative's default minimum of 1.2, which is always safe for admission webhooks.
90+
if envVars.MinVersion == "1.2" || envVars.MinVersion == "1.3" {
91+
os.Setenv("WEBHOOK_TLS_MIN_VERSION", envVars.MinVersion)
92+
}
93+
if envVars.CipherSuites != "" {
94+
os.Setenv("WEBHOOK_TLS_CIPHER_SUITES", envVars.CipherSuites)
95+
}
96+
if envVars.CurvePreferences != "" {
97+
os.Setenv("WEBHOOK_TLS_CURVE_PREFERENCES", envVars.CurvePreferences)
98+
}
99+
}
100+
}
101+
102+
// Inline the context setup (same as proxy.Getctx but reuses the signal
103+
// context already created above instead of calling signals.NewContext again).
104+
systemNamespace := os.Getenv("SYSTEM_NAMESPACE")
105+
ctx := kwebhook.WithOptions(
106+
injection.WithNamespaceScope(signalCtx, systemNamespace),
107+
kwebhook.Options{
108+
ServiceName: serviceName,
109+
Port: 8443,
110+
SecretName: secretName,
111+
},
112+
)
113+
114+
sharedmain.WebhookMainWithConfig(ctx, "webhook-operator",
115+
cfg,
55116
certificates.NewController,
56117
proxy.NewProxyDefaultingAdmissionController,
57118
newAnnotationDefaultingAdmissionController,

cmd/openshift/webhook/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,10 @@ func main() {
7373
if envVars, err := occommon.TLSEnvVarsFromProfile(tlsProfile); err != nil {
7474
log.Printf("WARNING: could not convert TLS profile, using Knative defaults: %v", err)
7575
} else if envVars != nil {
76-
if envVars.MinVersion != "" {
76+
// Knative only accepts "1.2" or "1.3"; skip if the profile allows older versions
77+
// (e.g. OpenShift "Old" profile uses VersionTLS10). The webhook will then fall
78+
// back to Knative's default minimum of 1.2, which is always safe for admission webhooks.
79+
if envVars.MinVersion == "1.2" || envVars.MinVersion == "1.3" {
7780
os.Setenv("WEBHOOK_TLS_MIN_VERSION", envVars.MinVersion)
7881
}
7982
if envVars.CipherSuites != "" {

pkg/reconciler/openshift/tektonpipeline/extension.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ func (oe openshiftExtension) Transformers(comp v1alpha1.TektonComponent) []mf.Tr
7272
occommon.RemoveRunAsUserForStatefulSet(tektonRemoteResolversControllerName),
7373
occommon.ApplyCABundlesForStatefulSet(tektonPipelinesControllerName),
7474
occommon.ApplyCABundlesForStatefulSet(tektonRemoteResolversControllerName),
75+
common.ReplaceNamespaceInClusterRoleBinding(comp.GetSpec().GetTargetNamespace()),
7576
}
7677
return trns
7778
}

pkg/reconciler/proxy/controller.go

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,9 @@ package proxy
1818

1919
import (
2020
"context"
21-
"os"
2221

2322
"knative.dev/pkg/configmap"
2423

25-
"knative.dev/pkg/injection"
26-
"knative.dev/pkg/signals"
27-
2824
// Injection stuff
2925
"k8s.io/apimachinery/pkg/types"
3026
"k8s.io/client-go/tools/cache"
@@ -100,29 +96,6 @@ func NewAdmissionController(
10096
return c
10197
}
10298

103-
func Getctx() context.Context {
104-
serviceName := os.Getenv("WEBHOOK_SERVICE_NAME")
105-
if serviceName == "" {
106-
serviceName = "tekton-operator-proxy-webhook"
107-
}
108-
109-
secretName := os.Getenv("WEBHOOK_SECRET_NAME")
110-
if secretName == "" {
111-
secretName = "proxy-webhook-certs"
112-
}
113-
systemNamespace := os.Getenv("SYSTEM_NAMESPACE")
114-
115-
// Scope informers to the webhook's namespace instead of cluster-wide
116-
ctx := injection.WithNamespaceScope(signals.NewContext(), systemNamespace)
117-
118-
// Set up a signal context with our webhook options
119-
ctx = webhook.WithOptions(ctx, webhook.Options{
120-
ServiceName: serviceName,
121-
Port: 8443,
122-
SecretName: secretName,
123-
})
124-
return ctx
125-
}
12699

127100
func NewProxyDefaultingAdmissionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
128101

0 commit comments

Comments
 (0)