Skip to content

feat(gitops-console-plugin): Configure SSL protocol and ciphersuites for plugin component#1224

Open
akhilnittala wants to merge 2 commits into
redhat-developer:masterfrom
akhilnittala:usr/akhil/GITOPS-10473
Open

feat(gitops-console-plugin): Configure SSL protocol and ciphersuites for plugin component#1224
akhilnittala wants to merge 2 commits into
redhat-developer:masterfrom
akhilnittala:usr/akhil/GITOPS-10473

Conversation

@akhilnittala

@akhilnittala akhilnittala commented Jul 18, 2026

Copy link
Copy Markdown
Member

What type of PR is this?
/kind enhancement

What does this PR do / why we need it:
Configure SSL Protocol and cipher suites based on apiserver tls minversion and ciphersuites
Have you updated the necessary documentation?

  • Documentation update is required by this PR.
  • Documentation has been updated.

Which issue(s) this PR fixes:

Fixes #?
https://redhat.atlassian.net/browse/GITOPS-10473
Test acceptance criteria:

  • Unit Test
  • E2E Test

How to test changes / Special notes to the reviewer:
deploy gitops operator and verify the ssl connection with apiserver tls minversion and ciphers

…for plugin component

Signed-off-by: akhil nittala <nakhil@redhat.com>
@openshift-ci openshift-ci Bot added the kind/enhancement New feature or request label Jul 18, 2026
@openshift-ci
openshift-ci Bot requested review from chetan-rns and svghadi July 18, 2026 11:27
@openshift-ci

openshift-ci Bot commented Jul 18, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign wtam2018 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • GitOps plugin deployments now honor the cluster’s minimum TLS version and configured cipher suites.
    • Plugin-generated configuration now reflects the selected TLS settings.
    • Configuration changes automatically trigger pod template refreshes to roll out updates.
  • Tests
    • Added coverage for TLS-to-plugin mapping, generated plugin configuration behavior, deterministic config hashing, and deployment refresh when configuration changes.

Walkthrough

TLS settings now flow from the cluster TLS profile into the GitOps service controller, which generates a TLS-aware plugin ConfigMap. ConfigMap content is hashed into Deployment pod-template annotations to trigger updates when plugin configuration changes.

Changes

TLS-aware console plugin configuration

Layer / File(s) Summary
TLS settings propagation
controllers/gitopsservice_controller.go, cmd/main.go
ReconcileGitopsService stores TLS minimum version and cipher settings, populated from the cluster TLS profile during controller initialization.
TLS-aware plugin configuration
controllers/consoleplugin.go, controllers/consoleplugin_test.go
Plugin httpd.conf generation maps TLS versions and conditionally adds protocol and cipher directives, with tests covering configuration generation and TLS mapping.
ConfigMap hashing and Deployment reconciliation
controllers/consoleplugin.go, controllers/consoleplugin_test.go
The generated ConfigMap is shared by reconciliation paths, hashed from its data, and tracked in the Deployment pod-template annotation; tests cover updated reconciliation calls and hash changes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ClusterTLSProfile
  participant ReconcileGitopsService
  participant PluginConfigMap
  participant Deployment
  ClusterTLSProfile->>ReconcileGitopsService: Provide TLSMinVersion and TLSCiphers
  ReconcileGitopsService->>PluginConfigMap: Generate TLS-aware httpd.conf
  PluginConfigMap-->>ReconcileGitopsService: Return generated ConfigMap
  ReconcileGitopsService->>Deployment: Set httpd-cfg-hash on pod template
Loading

Suggested reviewers: chetan-rns, svghadi, anandrkskd

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the change to configure SSL protocol and ciphersuites for the GitOps console plugin.
Description check ✅ Passed The description accurately describes the TLS min version and cipher suite configuration changes in the plugin.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@controllers/consoleplugin.go`:
- Around line 539-540: In ReconcileGitopsService.reconcileConfigMap, update the
existing ConfigMap after copying Data and Labels by passing
existingPluginConfigMap to r.Client.Update instead of the newly generated
newPluginConfigMap, preserving its ResourceVersion.
- Line 437: Initialize existingSpecTemplate.ObjectMeta.Annotations as a writable
map when it is nil before assigning the "httpd-cfg-hash" entry, while preserving
the existing annotation update behavior.
- Around line 529-540: Replace the crypto/md5 import with crypto/sha256 in
controllers/consoleplugin.go at lines 5-5. Update getConfigMapHash at lines
529-540 to create a SHA-256 hash, collect and lexicographically sort cm.Data
keys before writing each key and value, and preserve the existing hexadecimal
string return format.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 23fb09a2-e4fc-4318-898d-224970c23815

📥 Commits

Reviewing files that changed from the base of the PR and between 8695d85 and 5bc4027.

📒 Files selected for processing (3)
  • cmd/main.go
  • controllers/consoleplugin.go
  • controllers/gitopsservice_controller.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • argoproj-labs/argocd-operator (manual)

existingPluginDeployment.Spec.Replicas = newPluginDeployment.Spec.Replicas
existingPluginDeployment.Spec.Selector = newPluginDeployment.Spec.Selector
existingSpecTemplate.Labels = newSpecTemplate.Labels
existingSpecTemplate.ObjectMeta.Annotations["httpd-cfg-hash"] = newSpecTemplate.ObjectMeta.Annotations["httpd-cfg-hash"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🔴 Critical | ⚡ Quick win

Prevent nil-map panic when updating annotations.

If the existing Deployment's pod template does not have any annotations, existingSpecTemplate.ObjectMeta.Annotations will be nil. Attempting to write to a nil map will cause a runtime panic that crashes the reconciliation loop.

🛡️ Proposed fix
+			if existingSpecTemplate.ObjectMeta.Annotations == nil {
+				existingSpecTemplate.ObjectMeta.Annotations = make(map[string]string)
+			}
			existingSpecTemplate.ObjectMeta.Annotations["httpd-cfg-hash"] = newSpecTemplate.ObjectMeta.Annotations["httpd-cfg-hash"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
existingSpecTemplate.ObjectMeta.Annotations["httpd-cfg-hash"] = newSpecTemplate.ObjectMeta.Annotations["httpd-cfg-hash"]
if existingSpecTemplate.ObjectMeta.Annotations == nil {
existingSpecTemplate.ObjectMeta.Annotations = make(map[string]string)
}
existingSpecTemplate.ObjectMeta.Annotations["httpd-cfg-hash"] = newSpecTemplate.ObjectMeta.Annotations["httpd-cfg-hash"]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controllers/consoleplugin.go` at line 437, Initialize
existingSpecTemplate.ObjectMeta.Annotations as a writable map when it is nil
before assigning the "httpd-cfg-hash" entry, while preserving the existing
annotation update behavior.

Comment on lines +529 to 540
// getConfigMapHash returns MD5 hash of ConfigMap data for change detection
func getConfigMapHash(cm *corev1.ConfigMap) string {
hash := md5.New()
for key, value := range cm.Data {
io.WriteString(hash, key)
io.WriteString(hash, value)
}
return fmt.Sprintf("%x", hash.Sum(nil))
}

func (r *ReconcileGitopsService) reconcileConfigMap(instance *pipelinesv1alpha1.GitopsService, request reconcile.Request, newPluginConfigMap *corev1.ConfigMap) (reconcile.Result, error) {
reqLogger := logs.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Replace MD5 with SHA256 to ensure FIPS compliance and fix non-deterministic hashing.

The crypto/md5 package is not FIPS-compliant and can cause panics or be blocked in FIPS-enabled OpenShift clusters. Additionally, Go map iteration order is random; if cm.Data ever contains more than one key, the hash will change randomly on every reconciliation and cause continuous unwanted Deployment rollouts.

  • controllers/consoleplugin.go#L529-L540: update getConfigMapHash to use sha256.New() and sort the map keys before iterating to guarantee a deterministic hash.
  • controllers/consoleplugin.go#L5-L5: replace the "crypto/md5" import with "crypto/sha256".
🛠️ Proposed fixes

For the import (controllers/consoleplugin.go#L5-L5):

-	"crypto/md5"
+	"crypto/sha256"

For the function (controllers/consoleplugin.go#L529-L540):

-func getConfigMapHash(cm *corev1.ConfigMap) string {
-	hash := md5.New()
-	for key, value := range cm.Data {
-		io.WriteString(hash, key)
-		io.WriteString(hash, value)
-	}
-	return fmt.Sprintf("%x", hash.Sum(nil))
-}
+func getConfigMapHash(cm *corev1.ConfigMap) string {
+	hash := sha256.New()
+	keys := make([]string, 0, len(cm.Data))
+	for k := range cm.Data {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	for _, k := range keys {
+		io.WriteString(hash, k)
+		io.WriteString(hash, cm.Data[k])
+	}
+	return fmt.Sprintf("%x", hash.Sum(nil))
+}
🧰 Tools
🪛 ast-grep (0.44.1)

[warning] 530-530: Detected use of the 'crypto/md5' package (md5.New / md5.Sum). MD5 is a cryptographically broken, collision-prone hash and must not be used for security purposes such as integrity checks, signatures, or password hashing. Use a strong hash from 'crypto/sha256' (sha256.New / sha256.Sum256) or 'crypto/sha512' instead; for passwords use a dedicated KDF such as golang.org/x/crypto/bcrypt or argon2.
Context: md5.New
Note: [CWE-327] Use of a Broken or Risky Cryptographic Algorithm.

(weak-hash-md5-go)

📍 Affects 1 file
  • controllers/consoleplugin.go#L529-L540 (this comment)
  • controllers/consoleplugin.go#L5-L5
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controllers/consoleplugin.go` around lines 529 - 540, Replace the crypto/md5
import with crypto/sha256 in controllers/consoleplugin.go at lines 5-5. Update
getConfigMapHash at lines 529-540 to create a SHA-256 hash, collect and
lexicographically sort cm.Data keys before writing each key and value, and
preserve the existing hexadecimal string return format.

Source: Linters/SAST tools

Comment on lines +539 to 540
func (r *ReconcileGitopsService) reconcileConfigMap(instance *pipelinesv1alpha1.GitopsService, request reconcile.Request, newPluginConfigMap *corev1.ConfigMap) (reconcile.Result, error) {
reqLogger := logs.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Fix r.Client.Update target to avoid missing ResourceVersion error.

Although not directly modified in this PR, the unchanged block at the end of this function incorrectly updates newPluginConfigMap instead of existingPluginConfigMap. Because newPluginConfigMap is freshly generated and lacks a ResourceVersion, Kubernetes will reject the update.

To ensure ConfigMap updates succeed, please fix the target in the existing code block:

// ... in the unchanged code below ...
			existingPluginConfigMap.Data = newPluginConfigMap.Data
			existingPluginConfigMap.Labels = newPluginConfigMap.Labels
-			return reconcile.Result{}, r.Client.Update(context.TODO(), newPluginConfigMap)
+			return reconcile.Result{}, r.Client.Update(context.TODO(), existingPluginConfigMap)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controllers/consoleplugin.go` around lines 539 - 540, In
ReconcileGitopsService.reconcileConfigMap, update the existing ConfigMap after
copying Data and Labels by passing existingPluginConfigMap to r.Client.Update
instead of the newly generated newPluginConfigMap, preserving its
ResourceVersion.

…for plugin component

Signed-off-by: akhil nittala <nakhil@redhat.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@controllers/consoleplugin_test.go`:
- Around line 2000-2020: Update getConfigMapHash to sort the keys of cm.Data
before writing key-value pairs into the hash, ensuring identical ConfigMaps
always produce the same hash and avoiding unnecessary rollouts.
- Around line 1931-1938: Update the TLS configuration logic exercised by the
“TLS 1.2 with cipher suites” test so TLSMinVersion VersionTLS12 emits an
additive protocol range including TLSv1.2 and TLSv1.3, rather than selecting
TLSv1.2 exclusively. Preserve the cipher-suite configuration and existing
behavior for other minimum versions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 0729c3de-2de9-4c16-8c30-ff1b5044daa6

📥 Commits

Reviewing files that changed from the base of the PR and between 5bc4027 and a5d00ac.

📒 Files selected for processing (1)
  • controllers/consoleplugin_test.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • argoproj-labs/argocd-operator (manual)

Comment on lines +1931 to +1938
{
name: "TLS 1.2 with cipher suites",
minVersion: "VersionTLS12",
ciphers: []string{"ECDHE-RSA-AES256-GCM-SHA384", "ECDHE-RSA-AES128-GCM-SHA256"},
wantProtocol: true,
wantCipherSuite: true,
protocol: "TLSv1.2",
cipherSuite: "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
ast-grep outline controllers/consoleplugin.go --match TLSVersionToPlugin --view expanded
rg -n -C4 'SSLProtocol|TLSVersionToPlugin' controllers/consoleplugin.go controllers/consoleplugin_test.go
curl -fsSL https://httpd.apache.org/docs/2.4/mod/mod_ssl.html |
  grep -A40 -B5 'id="sslprotocol"' | head -n 80

Repository: redhat-developer/gitops-operator

Length of output: 6411


Treat VersionTLS12 as a floor, not a fixed protocol.
SSLProtocol TLSv1.2 only enables TLS 1.2 here, so TLSMinVersion still behaves like an exact version and can exclude TLS 1.3 clients. Use an additive range such as SSLProtocol -all +TLSv1.2 +TLSv1.3.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controllers/consoleplugin_test.go` around lines 1931 - 1938, Update the TLS
configuration logic exercised by the “TLS 1.2 with cipher suites” test so
TLSMinVersion VersionTLS12 emits an additive protocol range including TLSv1.2
and TLSv1.3, rather than selecting TLSv1.2 exclusively. Preserve the
cipher-suite configuration and existing behavior for other minimum versions.

Comment on lines +2000 to +2020
func TestGetConfigMapHash(t *testing.T) {
t.Run("same configmap returns same hash", func(t *testing.T) {
cm1 := &corev1.ConfigMap{
Data: map[string]string{
"config": "value",
"foo": "bar",
},
}

cm2 := &corev1.ConfigMap{
Data: map[string]string{
"config": "value",
"foo": "bar",
},
}

hash1 := getConfigMapHash(cm1)
hash2 := getConfigMapHash(cm2)

assert.Equal(t, hash1, hash2)
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
ast-grep outline controllers/consoleplugin.go --match getConfigMapHash --view expanded
rg -n -A15 -B3 '^func getConfigMapHash' controllers/consoleplugin.go

Repository: redhat-developer/gitops-operator

Length of output: 1053


🏁 Script executed:

#!/bin/bash
set -euo pipefail

cat > /tmp/hash_order_check.go <<'EOF'
package main

import (
	"crypto/md5"
	"fmt"
	"io"
	"sort"
)

func hashUnsorted(m map[string]string) string {
	h := md5.New()
	for k, v := range m {
		io.WriteString(h, k)
		io.WriteString(h, v)
	}
	return fmt.Sprintf("%x", h.Sum(nil))
}

func hashSorted(m map[string]string) string {
	h := md5.New()
	keys := make([]string, 0, len(m))
	for k := range m {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		io.WriteString(h, k)
		io.WriteString(h, m[k])
	}
	return fmt.Sprintf("%x", h.Sum(nil))
}

func main() {
	m := map[string]string{"config": "value", "foo": "bar"}

	seen := map[string]int{}
	for i := 0; i < 1000; i++ {
		seen[hashUnsorted(m)]++
	}
	fmt.Println("unsorted distinct hashes:", len(seen))
	for h, n := range seen {
		fmt.Printf("%s %d\n", h, n)
	}
	fmt.Println("sorted hash:", hashSorted(m))
}
EOF

go run /tmp/hash_order_check.go

Repository: redhat-developer/gitops-operator

Length of output: 318


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n -A5 -B5 'getConfigMapHash\(' controllers/consoleplugin.go

Repository: redhat-developer/gitops-operator

Length of output: 1032


Make ConfigMap hashing deterministic.
Iterating over cm.Data directly can produce different hashes for identical ConfigMaps, which will churn the pod-template annotation and trigger unnecessary rollouts. Sort the keys before writing them into the hash.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@controllers/consoleplugin_test.go` around lines 2000 - 2020, Update
getConfigMapHash to sort the keys of cm.Data before writing key-value pairs into
the hash, ensuring identical ConfigMaps always produce the same hash and
avoiding unnecessary rollouts.

@openshift-ci

openshift-ci Bot commented Jul 18, 2026

Copy link
Copy Markdown

@akhilnittala: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/unit a5d00ac link true /test unit

Full PR test history. Your PR dashboard.

Details

Instructions 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-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant