Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
This is still missing documentation, maybe add few more tests, but in general it's tested working and ready for review. |
c641544 to
bded46d
Compare
|
@enarha Please add PR deescrtipion with changes, architecture diagram, |
| @@ -0,0 +1,229 @@ | |||
| /* | |||
| Copyright 2024 The Tekton Authors | |||
There was a problem hiding this comment.
Question: Should it not be 2026?
| @@ -0,0 +1,167 @@ | |||
| /* | |||
| Copyright 2024 The Tekton Authors | |||
| @@ -0,0 +1,229 @@ | |||
| /* | |||
| Copyright 2024 The Tekton Authors | |||
| @@ -0,0 +1,167 @@ | |||
| /* | |||
| Copyright 2024 The Tekton Authors | |||
| // GetTLSEnvVarsFromAPIServer fetches the TLS security profile from the OpenShift APIServer | ||
| // resource and converts it to environment variable values that can be used by Tekton components. | ||
| // Returns nil if the APIServer has no TLS profile configured or if the shared lister is not initialized. | ||
| func GetTLSEnvVarsFromAPIServer(ctx context.Context, _ *rest.Config) (*TLSEnvVars, error) { |
There was a problem hiding this comment.
Can we return tls.config here from crypto/tls
We Could need other configration in the future
We could use then func TLSEnvVarsFromConfig(cfg *tls.Config) *TLSEnvVars to turn it to envvars
There was a problem hiding this comment.
We can. But we'll need to do the conversation twice APIServer string -> tls.Config -> env var strings instead of APIServer string -> env var strings. If you think we can immediately use the tls.Config with a specific consumer in mind (webhooks, nginx or whatever), then I'll follow your suggestion. If we do not have specific case immediately waiting for that, then I'll suggest we add this when we need it.
Please let me know what do you think.
| recorder := events.NewLoggingEventRecorder("tekton-operator") | ||
| observedConfig, errs := apiserver.ObserveTLSSecurityProfile(listers, recorder, existingConfig) | ||
| if len(errs) > 0 { | ||
| logger.Warnf("Errors observing TLS security profile: %v", errs) |
There was a problem hiding this comment.
Good question. It is a matter of policy - what do we want to happen in the case of a failure. I encountered two types of errors. In the first case we are able to read the APIServer, but failed to populate the map existingConfig with values. It was a bug in the way library-go handles this case in the older version we use, which I fixed, thus we have that two level check. The second case is we fail to read the APIServer resource. If we return an error and bubble it up, we'll break the reconciliation of the operands (e.g. TektonResult). The current behavior is to log a warning, degrade the TLS funcitonality (centralized TLS configuration does not have an effect), but operands continue working. The question is if we prefer that harder or softer form of failure. I believe with the hard failure, the Tekton administrator can still disable the centralized TLS configuration by disabling it through the TektonConfig and if that's the case I'm inclined to agree with a hard failure. WDYT?
|
|
||
| // If no TLS configuration is present, return nil | ||
| if minVersion == "" && len(cipherSuites) == 0 { | ||
| return nil, nil |
There was a problem hiding this comment.
should we log and return error ?
| return &TLSEnvVars{ | ||
| MinVersion: convertTLSVersionToEnvFormat(minVersion), | ||
| CipherSuites: strings.Join(cipherSuites, ","), | ||
| CurvePreferences: "", // Will be populated once openshift/api#2583 is merged |
There was a problem hiding this comment.
can we mention this in PR description openshift/api#2583
because empty curve preferences means go defaults
|
|
||
| // convertTLSVersionToEnvFormat converts library-go TLS version format (VersionTLSxx) to | ||
| // the format expected by Go's crypto/tls (1.x) | ||
| func convertTLSVersionToEnvFormat(version string) string { |
There was a problem hiding this comment.
We should consider parse TLSVversion to go format, webhook for example are expecting this in go native constant , I suppose the same thing for go apis using tls
https://github.com/knative/pkg/blob/main/webhook/webhook.go#L53
A conversion in this format feels more suitable to error prone constant
func parseTLSVersion(version string) (uint16, error) {
switch version {
case "VersionTLS10", "TLSv1.0":
return tls.VersionTLS10, nil
case "VersionTLS11", "TLSv1.1":
return tls.VersionTLS11, nil
case "VersionTLS12", "TLSv1.2":
return tls.VersionTLS12, nil
case "VersionTLS13", "TLSv1.3":
return tls.VersionTLS13, nil
default:
return 0, fmt.Errorf("unknown TLS version: %s", version)
}
}
There was a problem hiding this comment.
Switched to function which returns an error if unknown tls version is set through the apiserver record. Also split the retrieval of the tls configuration from the transformation. If we need to add more transformations in the future (e.g. to tsl.Config) we can do that without affecting existing code.
| if oe.resolvedTLSConfig == nil { | ||
| return "" | ||
| } | ||
| return fmt.Sprintf("%s:%s:%s", oe.resolvedTLSConfig.MinVersion, oe.resolvedTLSConfig.CipherSuites, oe.resolvedTLSConfig.CurvePreferences) |
There was a problem hiding this comment.
can we use a real hash function for the fingerprint like sha256, the ":" thingy cna be present in ciphers ro curves
There was a problem hiding this comment.
Ok first look, thaught that this function is calculating a hash, but hte hash is calculted in isntallerset code
mm I think the name is misleading here, could we called GetPlatformData rather than GetHash Data
| } | ||
| } | ||
|
|
||
| // injectTLSConfig injects the TLS configuration as environment variables into the Results API deployment |
| 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("SKIP_APISERVER_TLS_WATCH") == "true" { |
bded46d to
2de7f83
Compare
| // and check with annotation, if they are same then we skip updating the object | ||
| // otherwise we update the manifest | ||
| specHash, err := hash.Compute(tr.Spec) | ||
| hashInput := struct { |
There was a problem hiding this comment.
This seems redudant and duplciate for all component
Can we have a common function that computes Hash give spec and common extension
Would make thing clear when redaing
There was a problem hiding this comment.
I kept it per component for now. Each component has specific deployments to update. I considered a separate function which takes a resource type (e.g. deployment/statefulset) and resource object (e.g. tekton-results-api), but it requires any type params and extra import of the common package, so I think for now the advantages are not much bigger than the disadvantages.
| if oe.resolvedTLSConfig == nil { | ||
| return "" | ||
| } | ||
| return fmt.Sprintf("%s:%s:%s", oe.resolvedTLSConfig.MinVersion, oe.resolvedTLSConfig.CipherSuites, oe.resolvedTLSConfig.CurvePreferences) |
There was a problem hiding this comment.
Ok first look, thaught that this function is calculating a hash, but hte hash is calculted in isntallerset code
mm I think the name is misleading here, could we called GetPlatformData rather than GetHash Data
b744aba to
63a684f
Compare
|
@enarha can we add in this PR transformation for other components |
|
|
||
| ### 3. Extension Interface Enhancement | ||
|
|
||
| - Added `GetHashData() string` method to the Extension interface |
There was a problem hiding this comment.
can you use the new function name GetPlatformData
|
|
||
| // Wait for caches to sync | ||
| if !cache.WaitForCacheSync(ctx.Done(), apiServerInformer.Informer().HasSynced) { | ||
| logger.Warn("Failed to sync APIServer informer cache") |
There was a problem hiding this comment.
What happens if the cache is not synced (because of network issue or ai server not reachable), is the code safe on this ? We should probably retrigger a reconcile if cache is not synced, but that will be more complex as for now, let just verify code is safe nothing will panic just after, may be we need to add unit test
There was a problem hiding this comment.
From what I see, nothing will panic if the cluster apiserver resource is not found in the cache. The reconciliation of the operand (e.g. tektonresult) will fail repeatedly though. There will be some very rapid reconcile retries with an exponential backoff. The same goes for the cache sync. The admin can still disable the central TLS configuration. If they opt-in into that feature, then I think louder failure without a panic makes sense. If you prefer we do not affect the operand reconciliation, then we can ignore that error and threat it like "no TLS config available" in the APIServer resource and just log some warning.
| func ResolveCentralTLSToEnvVars(ctx context.Context, lister TektonConfigLister) (*TLSEnvVars, error) { | ||
| tc, err := lister.Get(v1alpha1.ConfigResourceName) | ||
| if err != nil { | ||
| return nil, nil |
There was a problem hiding this comment.
Here we should propagate the error: failed to get tektonconfig
| } | ||
|
|
||
| // TLS 1.3 cipher suite names (IANA names) | ||
| tls13Ciphers := map[string]bool{ |
There was a problem hiding this comment.
should we add this
As per this https://go.dev/blog/tls-cipher-suites#:~:text=Go%20does%20allow%20configuring%20cipher,order%20by%20default%2C%20unless%20Config.
ciphers are not configrable. with tls 1.3, because they are considered as safe
Now the issue if we add them here, that may procude issues, right ?
There was a problem hiding this comment.
The reason this was included in the first place is that the newer version of library-go does the same. They are commented out in the 2023 version, but in the newer ones they are not.
They are not configurable indeed and not required for golang based operands. But we have some non golang based dependencies like PostgreSQL and Nginx maybe more. I'm not sure how will these handle the 1.3 ciphers if we do not explicitly specify them. So that's one reason to include them. For Tekton Results we already have the code which handles the ciphers list and there the 1.3 ciphers are simply ignored. To me it makes more sense to keep these for now. WDYT?
|
@pratap0007 @anithapriyanatarajan @mbpavan Can you review please ? |
Add support for centralized TLS configuration derived from the OpenShift APIServer TLS security profile. This enables Tekton components to inherit cluster-wide TLS settings (minimum version, cipher suites) via the TektonConfig CR. Key changes: - Watch the APIServer resource for TLS profile changes and enqueue TektonConfig for reconciliation - Add GetTLSProfileFromAPIServer and TLSEnvVarsFromProfile to extract and convert TLS profiles to environment variables - Add ResolveCentralTLSToEnvVars and InjectTLSEnvVars as reusable helpers for component extensions - Add EnableCentralTLSConfig flag in TektonConfig OpenShift platform spec (opt-in, default false) - Add GetPlatformData to the Extension interface for platform-specific hash data (e.g., TLS config fingerprint) - Add RBAC permissions for reading the APIServer resource Note: curve preferences (CurvePreferences) are currently omitted and default to Go's standard library values until openshift/api#2583 is merged. Assisted-by: Cursor
Activate the centralized TLS configuration infrastructure for the TektonResult component: - Resolve TLS config from APIServer via ResolveCentralTLSToEnvVars in PreReconcile - Inject TLS env vars into the results-api deployment using the generic InjectTLSEnvVars transformer - Include TLS config fingerprint in GetPlatformData for installer set hash computation, triggering updates on TLS profile changes - Log injected TLS config at Info level for observability Assisted-by: Cursor
63a684f to
6137592
Compare
|
@enarha: PR needs rebase. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
Changes
Submitter Checklist
These are the criteria that every PR should meet, please check them off as you
review them:
make test lintbefore submitting a PRSee the contribution guide for more details.
Release Notes