mirror of
https://github.com/open-cluster-management-io/ocm.git
synced 2026-05-08 10:17:17 +00:00
* 🌱 Add TLS profile configuration support via flags and ConfigMap Add pkg/common/tls library to support TLS profile compliance for OCM components. This enables components to receive TLS configuration via command-line flags (--tls-min-version and --tls-cipher-suites) from operators, aligning with the upstream enhancement proposal for TLS profile configuration. Key features: - TLS version and cipher suite parsing from flags or ConfigMap - ConfigMap-based TLS configuration for operator use - ConfigMap watcher for operators to detect profile changes - OpenSSL cipher name mapping to Go crypto/tls constants - Safe defaults (TLS 1.2) when no configuration provided Updated pkg/common/options/webhook.go to use TLS library instead of hardcoded TLS 1.2, enabling webhook components to respect TLS flags injected by operators. This is the foundation for OCM TLS profile compliance, keeping upstream code OpenShift-agnostic while supporting dynamic TLS configuration. Related: open-cluster-management-io/enhancements#175 Signed-off-by: Jia Zhu <jiazhu@redhat.com> Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> Signed-off-by: zhujian <jiazhu@redhat.com> * 🌱 Add TLS ConfigMap watch and restart to cluster-manager operator Implement ConfigMap-based TLS profile compliance for cluster-manager operator with hash comparison to prevent infinite restart loops. Changes: - Add TLS ConfigMap informer to watch ocm-tls-profile ConfigMap - Load current TLS config at startup and compute hash - Add event handlers that compare ConfigMap hash with current hash - Only restart if ConfigMap content actually differs from current config - Add comprehensive logging for all scenarios Scenarios handled: ✅ ConfigMap exists at startup (hash matches) → no restart ✅ ConfigMap created after startup (hash differs) → restart to apply ✅ ConfigMap updated (new hash differs) → restart to apply ✅ ConfigMap deleted (was using it) → restart to use defaults Leader election behavior: - This code only runs on the leader pod (due to controllercmd framework) - Non-leader pods wait idle until they acquire leadership - New leaders load current ConfigMap state when they start, ensuring latest config - Only the active leader monitors ConfigMap changes and restarts 🤖 Generated with Claude Code Signed-off-by: zhujian <jiazhu@redhat.com> * 🌱 Inject TLS config flags into addon-webhook deployment Implement Case 2 pattern for addon-webhook TLS configuration: cluster-manager-operator loads TLS config from ConfigMap and injects it as flags into the addon-webhook deployment. Changes: - Add AddonWebhookTLSMinVersion and AddonWebhookTLSCipherSuites fields to HubConfig - Load TLS config once when creating ClusterManagerController - Pass TLS config strings as parameters to controller - Inject --tls-min-version and --tls-cipher-suites flags into addon-webhook deployment template This approach ensures addon-webhook receives TLS configuration via flags without needing to watch the ConfigMap itself. When the ConfigMap changes, cluster-manager-operator restarts, reloads the config, and updates the deployment with new flags. 🤖 Generated with Claude Code Signed-off-by: zhujian <jiazhu@redhat.com> * 🌱 Log TLS min version and cipher suites on startup Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: zhujian <jiazhu@redhat.com> * 🌱 Move TLS library to sdk-go and update vendor dependencies Relocates TLS config and cipher helpers from pkg/common/tls into the vendored open-cluster-management.io/sdk-go/pkg/tls package, adds a generic watcher utility, and updates all import references accordingly. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: zhujian <jiazhu@redhat.com> * 🌱 Inject TLS flags into all hub component deployments Extend TLS flag injection from addon-webhook-only to all seven hub deployments managed by cluster-manager-operator: Manifests (operator → deployment args): - Rename HubConfig.AddonWebhookTLS* → TLS* so the same fields drive all deployments rather than only the addon webhook - Add {{- if .TLSMinVersion }} blocks to all six remaining deployment manifests (registration/work/placement controllers and registration/work webhook servers) Controller binaries (registration, work, placement, addon-manager): - Add --tls-min-version and --tls-cipher-suites flags to the common Options struct so the binaries accept the injected flags without failing; the flags are stored for future use Note: library-go's NewCommandWithContext uses cmd.Run (not RunE), so there is no clean programmatic hook to inject TLS into the 8443 health server without bypassing library-go's own boilerplate (signal handling, log init, profiling). Upstream library-go also has no native TLS configuration API on ControllerCommandConfig or ControllerBuilder. The 8443 health server defaults to TLS 1.2 via SetRecommendedHTTPServingInfoDefaults; configuring it further requires an upstream library-go enhancement. Webhook binaries already fully support these flags via WebhookOptions; no binary changes are needed there. Signed-off-by: Jian Zhu <zhujian@redhat.com> Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: zhujian <jiazhu@redhat.com> * 🌱 Wire --tls-min-version to library-go 8443 health server via WithServingTLSConfig Now that library-go has WithServingTLSConfig (ServingMinTLSVersion / ServingCipherSuites fields + injection in StartController before WithServer is called), wire the --tls-min-version and --tls-cipher-suites flags from Options into it. ApplyTLSToCommand installs a PersistentPreRunE hook that calls CmdConfig.WithServingTLSConfig after cobra flag parsing completes. PersistentPreRunE runs before cmd.Run, so all library-go boilerplate (signal handling, logging, profiling) is preserved - unlike the previous approach of replacing RunE which silently bypassed it. Uses go mod replace → /Users/jiazhu/go/src/github.com/openshift/library-go for local development/testing; replace directive to be removed once the library-go PR is merged and vendored. Signed-off-by: Jian Zhu <zhujian@redhat.com> Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: zhujian <jiazhu@redhat.com> * 🌱 Switch to --config file for controller 8443 TLS configuration Replace the WithServingTLSConfig approach with library-go's native --config flag mechanism: ApplyTLSToCommand now installs a PersistentPreRunE hook that: 1. Writes a minimal GenericOperatorConfig YAML to a temp file under /tmp (which is mounted as an emptyDir in all hub controller deployments, so writing is safe even with readOnlyRootFilesystem) 2. Sets --config to point at the temp file before cmd.Run executes All library-go boilerplate in cmd.Run (signal handling, log init, profiling, basicFlags.Validate) is fully preserved because PersistentPreRunE runs before Run, not replacing it. Inside StartController, Config() reads the temp file; the TLS values survive SetRecommendedHTTPServingInfoDefaults because DefaultString only sets fields that are currently empty. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: zhujian <jiazhu@redhat.com> * 🌱 Add tests for TLS profile compliance Unit tests (pkg/common/options): - TestApplyTLSToCommand: table-driven test covering all flag combinations: no flags (no-op), min-version only, cipher-suites only, both set, and --config pre-set by user (injection skipped). Unit tests (clustermanager_controller): - TestSyncDeployWithTLSConfig: verifies that when tlsMinVersion / tlsCipherSuites are set on the controller, the --tls-min-version and --tls-cipher-suites flags appear in the args of every managed hub deployment (registration, registration-webhook, placement, work-webhook). Also verifies the flags are absent when TLS config is not set. Integration tests (test/integration/operator): - "should inject tls-min-version into all hub deployments when ocm-tls-profile ConfigMap exists": creates the ocm-tls-profile ConfigMap with minTLSVersion=VersionTLS13 in the operator namespace and verifies all six hub deployments gain --tls-min-version=VersionTLS13 in their container args. Signed-off-by: Jian Zhu <zhujian@redhat.com> Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: zhujian <jiazhu@redhat.com> * 🌱 Switch TLS cipher suite format from OpenSSL to IANA Update vendored sdk-go to use IANA cipher suite names (e.g. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) instead of OpenSSL names (e.g. ECDHE-RSA-AES128-GCM-SHA256). IANA is the canonical format used by Go's crypto/tls, the Kubernetes apiserver --tls-cipher-suites flag, and library-go's ServingInfo.CipherSuites. Using IANA names end-to-end eliminates the format mismatch that caused library-go's 8443 health server to reject cipher suite names written by ApplyTLSToCommand. The ocm-tls-profile ConfigMap now accepts IANA names only. The downstream tls-profile-sync sidecar is responsible for converting OpenShift TLSSecurityProfile (OpenSSL-style) names to IANA before writing the ConfigMap. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: zhujian <jiazhu@redhat.com> * 🌱 Fix TLS ConfigMap test: create ConfigMap before operator startup The previous test created ocm-tls-profile ConfigMap after the operator started, which triggered the watcher's hash-change detection and called os.Exit(0), killing the test process. Move the test into a dedicated Describe with BeforeEach that creates the ConfigMap before starting the operator so the watcher seeds its hash at startup and no restart is triggered. Also add hubWorkControllerDeployment to the tlsDeployments list since its manifest includes tls-min-version injection. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: zhujian <jiazhu@redhat.com> --------- Signed-off-by: Jia Zhu <jiazhu@redhat.com> Signed-off-by: zhujian <jiazhu@redhat.com> Signed-off-by: Jian Zhu <zhujian@redhat.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>