Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion pkg/reconciler/kubernetes/tektoninstallerset/client/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func verifyMeta(resourceKind, isType string, logger *zap.SugaredLogger, set v1al
// Spec Hash Check
logger.Debugf("%v/%v: spec hash check", resourceKind, isType)

expectedHash, err := hash.Compute(comp.GetSpec())
expectedHash, err := hash.Compute(specHashInput(comp))
if err != nil {
return err
}
Expand All @@ -149,3 +149,17 @@ func verifyMeta(resourceKind, isType string, logger *zap.SugaredLogger, set v1al

return nil
}

// specHashInput is the canonical input for computing an InstallerSet's spec hash.
// Including PlatformDataHashKey means that operator-injected platform config
// (e.g. OpenShift APIServer TLS profile) causes InstallerSets to be refreshed
// when that config changes, without requiring the component's spec to change.
func specHashInput(comp v1alpha1.TektonComponent) interface{} {
return struct {
Spec interface{}
PlatformData string
}{
Spec: comp.GetSpec(),
PlatformData: comp.GetAnnotations()[v1alpha1.PlatformDataHashKey],
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func buildTriggerComponent(disabled bool) *v1alpha1.TektonTrigger {
}

func computeHash(comp *v1alpha1.TektonTrigger) string {
h, err := hash.Compute(comp.GetSpec())
h, err := hash.Compute(specHashInput(comp))
if err != nil {
panic("failed to compute hash: " + err.Error())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func (i *InstallerSetClient) waitForStatus(ctx context.Context, set *v1alpha1.Te
}

func (i *InstallerSetClient) makeInstallerSet(ctx context.Context, comp v1alpha1.TektonComponent, manifest *mf.Manifest, isName, isType string, customLabels map[string]string) (*v1alpha1.TektonInstallerSet, error) {
specHash, err := hash.Compute(comp.GetSpec())
specHash, err := hash.Compute(specHashInput(comp))
if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func (i *InstallerSetClient) updateSet(ctx context.Context, comp v1alpha1.Tekton
return err
}

specHash, err := hash.Compute(comp.GetSpec())
specHash, err := hash.Compute(specHashInput(comp))
if err != nil {
return err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestInstallerSetClient_Update(t *testing.T) {
},
}

expectedHash, err := hash.Compute(comp.GetSpec())
expectedHash, err := hash.Compute(specHashInput(comp))
assert.NilError(t, err)

tests := []struct {
Expand Down
21 changes: 15 additions & 6 deletions pkg/reconciler/openshift/common/tlsprofile.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ const (
// TLS_CURVE_PREFERENCES: comma-separated elliptic curve names (not yet populated;
// defaults to Go standard library values until openshift/api#2583 is merged)
TLSCurvePreferencesEnvVar = "TLS_CURVE_PREFERENCES"

// WebhookEnvVarPrefix is prepended to the TLS env var names when injecting into
// deployments that use the Knative webhook framework. The Knative webhook binary calls
// knativetls.DefaultConfigFromEnv("WEBHOOK_"), so it reads WEBHOOK_TLS_MIN_VERSION,
// WEBHOOK_TLS_CIPHER_SUITES, and WEBHOOK_TLS_CURVE_PREFERENCES.
// Components that read the env vars directly (e.g. Results API) use no prefix.
WebhookEnvVarPrefix = "WEBHOOK_"
)

// TLSEnvVars holds TLS configuration as environment variable values
Expand Down Expand Up @@ -263,13 +270,15 @@ func convertTLSVersionToEnvFormat(version string) (string, error) {

// InjectTLSEnvVars returns a transformer that injects TLS environment variables into
// the specified containers of a Deployment or StatefulSet matched by name.
func InjectTLSEnvVars(tlsEnvVars *TLSEnvVars, kind string, resourceName string, containerNames []string) mf.Transformer {
// envVarPrefix is prepended to each env var name. Use WebhookEnvVarPrefix ("WEBHOOK_") for
// deployments that run the Knative webhook binary, and "" for all other components.
func InjectTLSEnvVars(tlsEnvVars *TLSEnvVars, kind string, resourceName string, containerNames []string, envVarPrefix string) mf.Transformer {
return func(u *unstructured.Unstructured) error {
if u.GetKind() != kind || u.GetName() != resourceName {
return nil
}

envVars := buildTLSEnvVarList(tlsEnvVars)
envVars := buildTLSEnvVarList(tlsEnvVars, envVarPrefix)
if len(envVars) == 0 {
return nil
}
Expand All @@ -284,16 +293,16 @@ func InjectTLSEnvVars(tlsEnvVars *TLSEnvVars, kind string, resourceName string,
}
}

func buildTLSEnvVarList(tlsEnvVars *TLSEnvVars) []corev1.EnvVar {
func buildTLSEnvVarList(tlsEnvVars *TLSEnvVars, prefix string) []corev1.EnvVar {
var envVars []corev1.EnvVar
if tlsEnvVars.MinVersion != "" {
envVars = append(envVars, corev1.EnvVar{Name: TLSMinVersionEnvVar, Value: tlsEnvVars.MinVersion})
envVars = append(envVars, corev1.EnvVar{Name: prefix + TLSMinVersionEnvVar, Value: tlsEnvVars.MinVersion})
}
if tlsEnvVars.CipherSuites != "" {
envVars = append(envVars, corev1.EnvVar{Name: TLSCipherSuitesEnvVar, Value: tlsEnvVars.CipherSuites})
envVars = append(envVars, corev1.EnvVar{Name: prefix + TLSCipherSuitesEnvVar, Value: tlsEnvVars.CipherSuites})
}
if tlsEnvVars.CurvePreferences != "" {
envVars = append(envVars, corev1.EnvVar{Name: TLSCurvePreferencesEnvVar, Value: tlsEnvVars.CurvePreferences})
envVars = append(envVars, corev1.EnvVar{Name: prefix + TLSCurvePreferencesEnvVar, Value: tlsEnvVars.CurvePreferences})
}
return envVars
}
Expand Down
39 changes: 32 additions & 7 deletions pkg/reconciler/openshift/tektonpipeline/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
mf "github.com/manifestival/manifestival"
"github.com/tektoncd/operator/pkg/apis/operator/v1alpha1"
operatorclient "github.com/tektoncd/operator/pkg/client/injection/client"
tektonConfiginformer "github.com/tektoncd/operator/pkg/client/injection/informers/operator/v1alpha1/tektonconfig"
"github.com/tektoncd/operator/pkg/reconciler/common"
"github.com/tektoncd/operator/pkg/reconciler/kubernetes/tektoninstallerset/client"
occommon "github.com/tektoncd/operator/pkg/reconciler/openshift/common"
Expand All @@ -40,6 +41,8 @@ const (

tektonPipelinesControllerName = "tekton-pipelines-controller"
tektonRemoteResolversControllerName = "tekton-pipelines-remote-resolvers"
tektonPipelinesWebhookDeployment = "tekton-pipelines-webhook"
webhookContainerName = "webhook"
)

func OpenShiftExtension(ctx context.Context) common.Extension {
Expand All @@ -49,22 +52,25 @@ func OpenShiftExtension(ctx context.Context) common.Extension {
logger.Fatal("Failed to find version from env")
}

ext := openshiftExtension{
ext := &openshiftExtension{
// component version is used for metrics, passing a dummy
// value through extension not going to affect execution
installerSetClient: client.NewInstallerSetClient(operatorclient.Get(ctx).OperatorV1alpha1().TektonInstallerSets(),
version, "pipelines-ext", v1alpha1.KindTektonPipeline, nil),
kubeClientSet: kubeclient.Get(ctx),
kubeClientSet: kubeclient.Get(ctx),
tektonConfigLister: tektonConfiginformer.Get(ctx).Lister(),
}
return ext
}

type openshiftExtension struct {
installerSetClient *client.InstallerSetClient
kubeClientSet kubernetes.Interface
tektonConfigLister occommon.TektonConfigLister
resolvedTLSConfig *occommon.TLSEnvVars
}

func (oe openshiftExtension) Transformers(comp v1alpha1.TektonComponent) []mf.Transformer {
func (oe *openshiftExtension) Transformers(comp v1alpha1.TektonComponent) []mf.Transformer {
trns := []mf.Transformer{
occommon.ApplyCABundlesToDeployment,
occommon.RemoveRunAsUser(),
Expand All @@ -74,9 +80,28 @@ func (oe openshiftExtension) Transformers(comp v1alpha1.TektonComponent) []mf.Tr
occommon.ApplyCABundlesForStatefulSet(tektonRemoteResolversControllerName),
common.ReplaceNamespaceInClusterRoleBinding(comp.GetSpec().GetTargetNamespace()),
}

// Inject APIServer TLS profile env vars into the webhook so that it applies
// the cluster-wide TLS version and cipher suite policy (PQC readiness).
if oe.resolvedTLSConfig != nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

webhook's env vars are prefixed with WEBHOOK_. please consider having a prefix based extension for this.

trns = append(trns, occommon.InjectTLSEnvVars(oe.resolvedTLSConfig, "Deployment", tektonPipelinesWebhookDeployment, []string{webhookContainerName}, occommon.WebhookEnvVarPrefix))
}

return trns
}
func (oe openshiftExtension) PreReconcile(ctx context.Context, comp v1alpha1.TektonComponent) error {

func (oe *openshiftExtension) PreReconcile(ctx context.Context, comp v1alpha1.TektonComponent) error {
logger := logging.FromContext(ctx)

resolvedTLS, err := occommon.ResolveCentralTLSToEnvVars(ctx, oe.tektonConfigLister)
if err != nil {
return err
}
oe.resolvedTLSConfig = resolvedTLS
if oe.resolvedTLSConfig != nil {
logger.Infof("Injecting central TLS config into webhook: MinVersion=%s", oe.resolvedTLSConfig.MinVersion)
}

manifest, err := preManifest()
if err != nil {
return err
Expand All @@ -103,7 +128,7 @@ func (oe openshiftExtension) PreReconcile(ctx context.Context, comp v1alpha1.Tek
return common.ReconcileTargetNamespace(ctx, labels, nil, comp, oe.kubeClientSet)
}

func (oe openshiftExtension) PostReconcile(ctx context.Context, comp v1alpha1.TektonComponent) error {
func (oe *openshiftExtension) PostReconcile(ctx context.Context, comp v1alpha1.TektonComponent) error {
pipeline := comp.(*v1alpha1.TektonPipeline)

// Install monitoring if metrics is enabled
Expand All @@ -125,7 +150,7 @@ func (oe openshiftExtension) PostReconcile(ctx context.Context, comp v1alpha1.Te

return nil
}
func (oe openshiftExtension) Finalize(ctx context.Context, comp v1alpha1.TektonComponent) error {
func (oe *openshiftExtension) Finalize(ctx context.Context, comp v1alpha1.TektonComponent) error {
if err := oe.installerSetClient.CleanupPostSet(ctx); err != nil {
return err
}
Expand All @@ -135,7 +160,7 @@ func (oe openshiftExtension) Finalize(ctx context.Context, comp v1alpha1.TektonC
return nil
}

func (oe openshiftExtension) GetPlatformData() string {
func (oe *openshiftExtension) GetPlatformData() string {
return ""
}

Expand Down
Loading
Loading