Skip to content

Commit a2b6ec3

Browse files
committed
Enable TLS profile configuration for TektonResult
Activate the TLS profile infrastructure for the Results component: - extension.go: Add injectTLSConfig transformer that injects TLS_MIN_VERSION and TLS_CIPHER_SUITES env vars into the Results API deployment based on cluster APIServer configuration. TLS config is fetched once during Transformers() call, not per-resource. - controller.go: Set up APIServer watch to trigger reconciliation when the cluster TLS security profile changes. The Results API deployment will automatically pick up TLS configuration from the OpenShift APIServer resource and update when it changes.
1 parent 11fdcc4 commit a2b6ec3

File tree

3 files changed

+142
-5
lines changed

3 files changed

+142
-5
lines changed

pkg/reconciler/kubernetes/tektonresult/tektonresult.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,26 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, tr *v1alpha1.TektonResul
320320
} else {
321321
// If target namespace and version are not changed then check if spec
322322
// of TektonResult is changed by checking hash stored as annotation on
323-
// TektonInstallerSet with computing new hash of TektonResult Spec
323+
// TektonInstallerSet with computing new hash of TektonResult Spec.
324+
// Also include external TLS profile state to trigger updates when
325+
// platform TLS configuration changes.
324326
logger.Debug("Checking for spec changes in TektonResult")
325-
// Hash of TektonResult Spec
326-
expectedSpecHash, err := hash.Compute(tr.Spec)
327+
328+
// Get platform TLS profile fingerprint if extension supports it (empty on vanilla k8s)
329+
var tlsFingerprint string
330+
if fp, ok := r.extension.(common.TLSProfileFingerprinter); ok {
331+
tlsFingerprint = fp.GetTLSProfileFingerprint(ctx)
332+
}
333+
334+
// Hash of TektonResult Spec combined with TLS fingerprint
335+
type hashInput struct {
336+
Spec v1alpha1.TektonResultSpec
337+
TLSFingerprint string
338+
}
339+
expectedSpecHash, err := hash.Compute(hashInput{
340+
Spec: tr.Spec,
341+
TLSFingerprint: tlsFingerprint,
342+
})
327343
if err != nil {
328344
logger.Errorw("Failed to compute spec hash", "error", err)
329345
return err

pkg/reconciler/openshift/tektonresult/controller.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,41 @@ package tektonresult
1919
import (
2020
"context"
2121

22+
tektonResultInformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonresult"
23+
"github.com/tektoncd/operator/pkg/reconciler/common"
24+
occommon "github.com/tektoncd/operator/pkg/reconciler/openshift/common"
2225
k8s_ctrl "github.com/tektoncd/operator/pkg/reconciler/kubernetes/tektonresult"
2326
"knative.dev/pkg/configmap"
2427
"knative.dev/pkg/controller"
28+
"knative.dev/pkg/injection"
29+
"knative.dev/pkg/logging"
2530
)
2631

2732
// NewController initializes the controller and is called by the generated code
2833
// Registers eventhandlers to enqueue events
2934
func NewController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
30-
return k8s_ctrl.NewExtendedController(OpenShiftExtension)(ctx, cmw)
35+
return NewExtendedController(OpenShiftExtension)(ctx, cmw)
36+
}
37+
38+
// NewExtendedController wraps the base Kubernetes controller and adds OpenShift-specific watches
39+
func NewExtendedController(generator common.ExtensionGenerator) func(context.Context, configmap.Watcher) *controller.Impl {
40+
return func(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
41+
logger := logging.FromContext(ctx)
42+
43+
// Create the base Kubernetes controller with OpenShift extension
44+
impl := k8s_ctrl.NewExtendedController(generator)(ctx, cmw)
45+
46+
// Setup OpenShift APIServer watch for TLS profile changes.
47+
// This will trigger reconciliation when the cluster TLS policy changes.
48+
// Errors are logged by SetupAPIServerTLSWatch; we don't fail controller startup.
49+
restConfig := injection.GetConfig(ctx)
50+
lister := tektonResultInformer.Get(ctx).Lister()
51+
listerAdapter := occommon.TektonResultListerAdapter{Lister: lister}
52+
53+
if err := occommon.SetupAPIServerTLSWatch(ctx, restConfig, impl, listerAdapter, "TektonResult"); err == nil {
54+
logger.Info("APIServer TLS profile watch enabled")
55+
}
56+
57+
return impl
58+
}
3159
}

pkg/reconciler/openshift/tektonresult/extension.go

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import (
3232
corev1 "k8s.io/api/core/v1"
3333
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3434
k8sruntime "k8s.io/apimachinery/pkg/runtime"
35+
"k8s.io/client-go/rest"
36+
"knative.dev/pkg/injection"
3537
"knative.dev/pkg/logging"
3638
)
3739

@@ -71,11 +73,16 @@ func OpenShiftExtension(ctx context.Context) common.Extension {
7173
logger.Fatalf("Failed to fetch logs RBAC manifest: %v", err)
7274
}
7375

76+
// Get the rest.Config from the context for accessing OpenShift APIServer
77+
restConfig := injection.GetConfig(ctx)
78+
7479
ext := &openshiftExtension{
7580
installerSetClient: client.NewInstallerSetClient(operatorclient.Get(ctx).OperatorV1alpha1().TektonInstallerSets(),
7681
version, "results-ext", v1alpha1.KindTektonResult, nil),
7782
routeManifest: routeManifest,
7883
logsRBACManifest: logsRBACManifest,
84+
restConfig: restConfig,
85+
ctx: ctx,
7986
}
8087
return ext
8188
}
@@ -84,12 +91,22 @@ type openshiftExtension struct {
8491
installerSetClient *client.InstallerSetClient
8592
routeManifest *mf.Manifest
8693
logsRBACManifest *mf.Manifest
94+
restConfig *rest.Config
95+
ctx context.Context
96+
}
97+
98+
// GetTLSProfileFingerprint returns a deterministic string representing the current
99+
// OpenShift TLS security profile state. This is used to detect TLS configuration
100+
// changes that should trigger component reconciliation.
101+
func (oe *openshiftExtension) GetTLSProfileFingerprint(ctx context.Context) string {
102+
return occommon.GetTLSProfileFingerprint(ctx, oe.restConfig)
87103
}
88104

89105
func (oe openshiftExtension) Transformers(comp v1alpha1.TektonComponent) []mf.Transformer {
90106
instance := comp.(*v1alpha1.TektonResult)
107+
logger := logging.FromContext(oe.ctx)
91108

92-
return []mf.Transformer{
109+
transformers := []mf.Transformer{
93110
occommon.RemoveRunAsUser(),
94111
occommon.RemoveRunAsGroup(),
95112
occommon.ApplyCABundlesToDeployment,
@@ -101,6 +118,16 @@ func (oe openshiftExtension) Transformers(comp v1alpha1.TektonComponent) []mf.Tr
101118
injectResultsAPIServiceCACert(instance.Spec.ResultsAPIProperties),
102119
injectPostgresUpgradeSupport(),
103120
}
121+
122+
// Fetch TLS configuration once and create the transformer if available
123+
tlsEnvVars, err := occommon.GetTLSEnvVarsFromAPIServer(oe.ctx, oe.restConfig)
124+
if err != nil {
125+
logger.Warnf("Failed to get TLS configuration from APIServer: %v", err)
126+
} else if tlsEnvVars != nil {
127+
transformers = append(transformers, injectTLSConfig(tlsEnvVars))
128+
}
129+
130+
return transformers
104131
}
105132

106133
func (oe *openshiftExtension) PreReconcile(ctx context.Context, tc v1alpha1.TektonComponent) error {
@@ -470,3 +497,69 @@ func injectPostgresUpgradeSupport() mf.Transformer {
470497
return nil
471498
}
472499
}
500+
501+
// injectTLSConfig injects the TLS configuration as environment variables into the Results API deployment
502+
func injectTLSConfig(tlsEnvVars *occommon.TLSEnvVars) mf.Transformer {
503+
return func(u *unstructured.Unstructured) error {
504+
if u.GetKind() != "Deployment" || u.GetName() != deploymentAPI {
505+
return nil
506+
}
507+
508+
d := &appsv1.Deployment{}
509+
if err := k8sruntime.DefaultUnstructuredConverter.FromUnstructured(u.Object, d); err != nil {
510+
return err
511+
}
512+
513+
for i, container := range d.Spec.Template.Spec.Containers {
514+
if container.Name != apiContainerName {
515+
continue
516+
}
517+
518+
envVars := []corev1.EnvVar{}
519+
if tlsEnvVars.MinVersion != "" {
520+
envVars = append(envVars, corev1.EnvVar{
521+
Name: occommon.TLSMinVersionEnvVar,
522+
Value: tlsEnvVars.MinVersion,
523+
})
524+
}
525+
if tlsEnvVars.CipherSuites != "" {
526+
envVars = append(envVars, corev1.EnvVar{
527+
Name: occommon.TLSCipherSuitesEnvVar,
528+
Value: tlsEnvVars.CipherSuites,
529+
})
530+
}
531+
// CurvePreferences will be populated once openshift/api#2583 is merged
532+
if tlsEnvVars.CurvePreferences != "" {
533+
envVars = append(envVars, corev1.EnvVar{
534+
Name: occommon.TLSCurvePreferencesEnvVar,
535+
Value: tlsEnvVars.CurvePreferences,
536+
})
537+
}
538+
539+
// Merge with existing env vars
540+
existingEnv := container.Env
541+
for _, newEnv := range envVars {
542+
found := false
543+
for j, existing := range existingEnv {
544+
if existing.Name == newEnv.Name {
545+
existingEnv[j] = newEnv
546+
found = true
547+
break
548+
}
549+
}
550+
if !found {
551+
existingEnv = append(existingEnv, newEnv)
552+
}
553+
}
554+
d.Spec.Template.Spec.Containers[i].Env = existingEnv
555+
break
556+
}
557+
558+
uObj, err := k8sruntime.DefaultUnstructuredConverter.ToUnstructured(d)
559+
if err != nil {
560+
return err
561+
}
562+
u.SetUnstructuredContent(uObj)
563+
return nil
564+
}
565+
}

0 commit comments

Comments
 (0)