-
Notifications
You must be signed in to change notification settings - Fork 50
feat(ctl): add a 'check-config' principal/agent commands to argocd-agentctl which will verify the user's configuration #631
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughAdds a new Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User as U
participant CLI as "argocd-agentctl:check-config"
participant Principal as "Principal Cluster API"
participant Agent as "Agent Cluster API"
U->>CLI: check-config principal
activate CLI
CLI->>Principal: Detect Argo CD scope (CR or defaults)
CLI->>Principal: Read CA, principal TLS, proxy TLS, JWT secrets
CLI->>Principal: Parse certs/keys, verify expiry & signature, parse RSA JWT key
alt Route API present
CLI->>Principal: Fetch Route(s), verify host in TLS SANs
end
CLI-->>U: Print aggregated results & exit
deactivate CLI
U->>CLI: check-config agent
activate CLI
CLI->>Agent: Read agent TLS/CA secrets, parse cert (CN/expiry)
CLI->>Principal: Fetch principal CA (cross-cluster)
CLI->>Agent: Verify agent cert signed by principal CA, check principal namespace presence
CLI-->>U: Print aggregated results & exit
deactivate CLI
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related issues
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
c1cdde9 to
67b4ce5
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #631 +/- ##
========================================
Coverage 45.57% 45.58%
========================================
Files 90 91 +1
Lines 9977 10328 +351
========================================
+ Hits 4547 4708 +161
- Misses 4963 5119 +156
- Partials 467 501 +34 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
cmd/ctl/check_config_test.go (1)
95-105: Add a regression test for wildcard Route hostsOnce the Route/SAN check handles wildcards, please add a test case here exercising a certificate with a
*.example.comSAN and a Route host likeargocd-server.example.com. That will lock in the fix and prevent the wildcard-support regression from reappearing.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
cmd/ctl/check_config.go(1 hunks)cmd/ctl/check_config_test.go(1 hunks)cmd/ctl/main.go(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
cmd/ctl/check_config_test.go (5)
internal/kube/client.go (1)
KubernetesClient(37-44)internal/tlsutil/generate.go (3)
GenerateCaCertificate(42-84)GenerateServerCertificate(114-142)GenerateClientCertificate(91-107)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)internal/tlsutil/kubernetes.go (1)
TLSCertFromSecret(44-66)cmd/ctl/check_config.go (2)
RunPrincipalChecks(128-174)RunAgentChecks(178-206)
cmd/ctl/main.go (1)
cmd/ctl/check_config.go (1)
NewCheckConfigCommand(49-61)
cmd/ctl/check_config.go (3)
internal/kube/client.go (2)
NewKubernetesClientFromConfig(58-98)KubernetesClient(37-44)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)internal/tlsutil/kubernetes.go (3)
TLSCertFromSecret(44-66)JWTSigningKeyFromSecret(167-191)X509CertPoolFromSecret(106-128)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Run unit tests
- GitHub Check: Run end-to-end tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (1)
cmd/ctl/check_config.go (1)
83-111: Consider parameter type consistency.This function passes
kubernetes.InterfacetoRunAgentChecks(line 106), whileRunPrincipalChecks(line 105) accepts*kube.KubernetesClient. This inconsistency makes the API less predictable.Consider refactoring
RunAgentChecksto accept*kube.KubernetesClientfor both agent and principal parameters, matching the pattern used byRunPrincipalChecks. This would make the API more consistent and potentially allow agent checks to accessDynamicClientif needed in the future.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
cmd/ctl/check_config.go(1 hunks)cmd/ctl/check_config_test.go(1 hunks)cmd/ctl/main.go(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
cmd/ctl/check_config_test.go (5)
internal/kube/client.go (1)
KubernetesClient(37-44)internal/tlsutil/generate.go (3)
GenerateCaCertificate(42-84)GenerateServerCertificate(114-142)GenerateClientCertificate(91-107)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)internal/tlsutil/kubernetes.go (1)
TLSCertFromSecret(44-66)cmd/ctl/check_config.go (2)
RunPrincipalChecks(128-174)RunAgentChecks(178-206)
cmd/ctl/check_config.go (3)
internal/kube/client.go (2)
NewKubernetesClientFromConfig(58-98)KubernetesClient(37-44)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)internal/tlsutil/kubernetes.go (3)
TLSCertFromSecret(44-66)JWTSigningKeyFromSecret(167-191)X509CertPoolFromSecret(106-128)
cmd/ctl/main.go (1)
cmd/ctl/check_config.go (1)
NewCheckConfigCommand(49-61)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Run end-to-end tests
🔇 Additional comments (9)
cmd/ctl/main.go (1)
52-52: LGTM!The integration of the new
check-configcommand follows the established pattern and correctly wires the new functionality into the CLI.cmd/ctl/check_config_test.go (3)
25-36: LGTM!The test helper correctly uses
t.Helper()and creates properly structured TLS secrets for testing.
38-111: Good happy-path coverage.The test properly validates the principal checks workflow with appropriate test fixtures and fake clients.
113-152: LGTM!The test correctly validates cross-cluster agent checks, including CA signature verification and namespace matching.
cmd/ctl/check_config.go (5)
37-61: LGTM!The
checkResulttype and command constructor follow appropriate patterns for Cobra-based CLIs.
63-81: LGTM!The command properly validates required flags and handles errors appropriately.
176-206: LGTM!The agent checks are well-structured and cover the essential cross-cluster validation scenarios.
208-234: LGTM!These validation helpers are well-focused with appropriate error handling and clear requirements (e.g., RSA-only for JWT keys).
315-395: LGTM!These helper functions implement cross-cluster validation logic correctly, including CA signature verification, certificate expiration checks, and namespace matching. The
x509FromTLSSecretutility function is well-designed and reusable.
67b4ce5 to
7afd305
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (3)
cmd/ctl/check_config.go (1)
356-358: Remove or properly handle the agent namespace check.Lines 357-358 check if the agent's own namespace exists but discard the result with
_, _. This is dead code that serves no purpose.Choose one of these solutions:
Solution 1 (recommended): Remove the dead code:
} - // optional: ensure agent's own namespace exists (sanity) - _, _ = agentKube.CoreV1().Namespaces().Get(ctx, agentNS, metav1.GetOptions{}) return nil }Solution 2: If the sanity check is valuable, handle or log the result:
} - // optional: ensure agent's own namespace exists (sanity) - _, _ = agentKube.CoreV1().Namespaces().Get(ctx, agentNS, metav1.GetOptions{}) + // Verify agent's own namespace exists (sanity check) + if _, err := agentKube.CoreV1().Namespaces().Get(ctx, agentNS, metav1.GetOptions{}); err != nil { + return fmt.Errorf("agent namespace '%s' not found on agent cluster: %w", agentNS, err) + } return nil }cmd/ctl/check_config_test.go (2)
38-111: Consider expanding test coverage for robustness.The test validates the happy path comprehensively but doesn't cover failure scenarios such as:
- Expired or not-yet-valid certificates
- Missing secrets
- Invalid JWT keys (non-RSA)
- Mismatched Route hosts and certificate SANs
- ArgoCD configured in namespaced mode (the test registers the CRD but doesn't create any ArgoCD CR or ConfigMap, so it only tests the "no resources found" path of
verifyArgoCDClusterScoped)Consider adding negative test cases to improve confidence in error handling. For example:
func TestCheckConfigPrincipal_ExpiredCertificate(t *testing.T) { // Create a certificate that expired yesterday // Assert that certSecretValid returns an error } func TestCheckConfigPrincipal_NamespacedMode(t *testing.T) { // Create an ArgoCD CR with spec.applicationNamespaces set // Assert that verifyArgoCDClusterScoped returns an error }
113-152: Consider expanding test coverage for agent checks.Similar to the principal test, this validates only the happy path. Consider adding tests for failure scenarios:
- Expired agent client certificate
- Agent certificate not signed by principal CA
- Missing namespace on principal cluster (mismatched agent CN)
- Missing or invalid agent CA secret
- Invalid ca.crt field in agent CA secret
Example negative test case:
func TestCheckConfigAgent_MismatchedNamespace(t *testing.T) { // Issue client cert with CN "test-cluster" // Don't create namespace "test-cluster" on principal // Assert that namespaceMatchesAgentSubject returns an error }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
cmd/ctl/check_config.go(1 hunks)cmd/ctl/check_config_test.go(1 hunks)cmd/ctl/main.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- cmd/ctl/main.go
🧰 Additional context used
🧬 Code graph analysis (2)
cmd/ctl/check_config_test.go (5)
internal/kube/client.go (1)
KubernetesClient(37-44)internal/tlsutil/generate.go (3)
GenerateCaCertificate(42-84)GenerateServerCertificate(114-142)GenerateClientCertificate(91-107)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)internal/tlsutil/kubernetes.go (1)
TLSCertFromSecret(44-66)cmd/ctl/check_config.go (2)
RunPrincipalChecks(128-168)RunAgentChecks(172-200)
cmd/ctl/check_config.go (3)
internal/kube/client.go (2)
NewKubernetesClientFromConfig(58-98)KubernetesClient(37-44)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)internal/tlsutil/kubernetes.go (3)
TLSCertFromSecret(44-66)JWTSigningKeyFromSecret(167-191)X509CertPoolFromSecret(106-128)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Build and push image
- GitHub Check: Run end-to-end tests
- GitHub Check: Run unit tests
- GitHub Check: Build & cache Go code
- GitHub Check: Lint Go code
- GitHub Check: Analyze (go)
cmd/ctl/check_config.go
Outdated
| return nil | ||
| } | ||
|
|
||
| // verifyArgoCDClusterScoped checks operator CR or argocd-cm to ensure no namespaced mode is configured. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears that this logic is not checking for cluster scoped, but is instead checking if source namespaces field is non-empty. Which is a fine thing to check, but is different from whether the cluster is cluster-scoped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I have added kubectl get applications --all-namespaces logic to check whether it is cluster scoped, please let me know if this is correct or is there any other way we can check this, thank you
ba71141 to
30858d9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
cmd/ctl/check_config_test.go (2)
170-258: Update deprecated API version.Line 180 uses
v1alpha1for the applications API, which is deprecated according to a previous review comment. Usev1beta1instead to align with current API versions.Apply this diff:
dynCl := dynamicfake.NewSimpleDynamicClientWithCustomListKinds(scheme, map[schema.GroupVersionResource]string{ {Group: "argoproj.io", Version: "v1beta1", Resource: "argocds"}: "ArgoCDList", - {Group: "argoproj.io", Version: "v1alpha1", Resource: "applications"}: "ApplicationList", + {Group: "argoproj.io", Version: "v1beta1", Resource: "applications"}: "ApplicationList", {Group: "route.openshift.io", Version: "v1", Resource: "routes"}: "RouteList", })
260-784: Update deprecated API version across all test cases.The
v1alpha1version for the applications API appears throughout all principal test cases (lines 267, 308, 354, 408, 466, 520, 579, 621, 694). This version is deprecated. Update all occurrences to usev1beta1instead.Example for one occurrence (apply similar changes to all):
dynCl := dynamicfake.NewSimpleDynamicClientWithCustomListKinds(scheme, map[schema.GroupVersionResource]string{ {Group: "argoproj.io", Version: "v1beta1", Resource: "argocds"}: "ArgoCDList", - {Group: "argoproj.io", Version: "v1alpha1", Resource: "applications"}: "ApplicationList", + {Group: "argoproj.io", Version: "v1beta1", Resource: "applications"}: "ApplicationList", })
🧹 Nitpick comments (2)
cmd/ctl/check_config_test.go (2)
61-91: Consider erroring on invalid IPs in test helpers.Lines 65-69 silently skip invalid IP addresses. For test clarity, it's better to fail fast when test data is malformed so issues are caught during test setup rather than causing subtle test failures.
Apply this diff:
func createExpiredCertificate(t *testing.T, name string, signerCert *x509.Certificate, signerKey crypto.PrivateKey, ips []string, dns []string) (string, string) { t.Helper() ipAddresses := []net.IP{} for _, ip := range ips { addr := net.ParseIP(ip) - if addr != nil { - ipAddresses = append(ipAddresses, addr) - } + require.NotNil(t, addr, "invalid IP address in test: %s", ip) + ipAddresses = append(ipAddresses, addr) }
93-146: Simplify CA parsing and handle invalid IPs.Lines 100-115 use an indirect approach (creating a fake client and secret) to parse the CA certificate. This can be simplified by parsing the PEM directly. Additionally, lines 118-123 silently skip invalid IPs, which could hide test setup issues.
Apply this diff:
func createCertSignedByDifferentCA(t *testing.T, name string, ips []string, dns []string) (string, string) { t.Helper() - // Create a different CA differentCAPEM, differentCAKeyPEM, err := tlsutil.GenerateCaCertificate("different-ca") require.NoError(t, err, "generate different CA") - // Create a fake client to parse the CA - cl := fake.NewSimpleClientset() - _, err = cl.CoreV1().Secrets("default").Create(context.TODO(), &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{Name: "temp-ca", Namespace: "default"}, - Type: corev1.SecretTypeTLS, - Data: map[string][]byte{ - "tls.crt": []byte(differentCAPEM), - "tls.key": []byte(differentCAKeyPEM), - }, - }, metav1.CreateOptions{}) - require.NoError(t, err, "create temp CA secret") - - differentCA, err := tlsutil.TLSCertFromSecret(context.TODO(), cl, "default", "temp-ca") + // Parse CA cert and key directly + differentCA, err := tls.X509KeyPair([]byte(differentCAPEM), []byte(differentCAKeyPEM)) require.NoError(t, err, "read different CA") differentCASigner, err := x509.ParseCertificate(differentCA.Certificate[0]) require.NoError(t, err, "parse different CA") - // Create certificate signed by different CA ipAddresses := []net.IP{} for _, ip := range ips { addr := net.ParseIP(ip) - if addr != nil { - ipAddresses = append(ipAddresses, addr) - } + require.NotNil(t, addr, "invalid IP address in test: %s", ip) + ipAddresses = append(ipAddresses, addr) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
cmd/ctl/check_config.go(1 hunks)cmd/ctl/check_config_test.go(1 hunks)cmd/ctl/main.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- cmd/ctl/check_config.go
- cmd/ctl/main.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-31T10:37:27.987Z
Learnt from: chetan-rns
Repo: argoproj-labs/argocd-agent PR: 632
File: test/data/pre-sync/pre-sync-job.yaml:2-17
Timestamp: 2025-10-31T10:37:27.987Z
Learning: In the argocd-agent repository, Kubernetes manifests under test/data/ directories are test fixtures for e2e testing and do not require production-grade security hardening such as securityContext settings for runAsNonRoot or allowPrivilegeEscalation.
Applied to files:
cmd/ctl/check_config_test.go
🧬 Code graph analysis (1)
cmd/ctl/check_config_test.go (5)
internal/tlsutil/generate.go (4)
GenerateCertificate(148-177)GenerateCaCertificate(42-84)GenerateServerCertificate(114-142)GenerateClientCertificate(91-107)internal/tlsutil/kubernetes.go (1)
TLSCertFromSecret(44-66)internal/kube/client.go (1)
KubernetesClient(37-44)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)cmd/ctl/check_config.go (2)
RunPrincipalChecks(226-271)RunAgentChecks(275-307)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Run unit tests
- GitHub Check: Run end-to-end tests
- GitHub Check: Build & cache Go code
- GitHub Check: Lint Go code
- GitHub Check: Build and push image
- GitHub Check: Analyze (go)
🔇 Additional comments (4)
cmd/ctl/check_config_test.go (4)
48-59: LGTM!The helper function correctly creates TLS secrets and follows Go testing best practices with
t.Helper()and descriptive error messages.
148-168: LGTM!This helper correctly creates a certificate with an empty CommonName for testing error scenarios.
786-847: LGTM!The valid agent configuration test correctly sets up both agent and principal clusters, creates matching namespaces, and verifies cross-cluster certificate validation.
170-1195: Excellent test coverage addressing previous review feedback.These tests comprehensively cover both success and failure scenarios, directly addressing the previous review comment about checking error cases. Each test validates specific error conditions (missing secrets, expired certificates, mismatched configurations, etc.) and verifies appropriate error messages.
Based on learnings: A previous reviewer requested tests for error cases, and this implementation provides thorough coverage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
cmd/ctl/check_config.go(1 hunks)cmd/ctl/check_config_test.go(1 hunks)cmd/ctl/main.go(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-31T10:37:27.987Z
Learnt from: chetan-rns
Repo: argoproj-labs/argocd-agent PR: 632
File: test/data/pre-sync/pre-sync-job.yaml:2-17
Timestamp: 2025-10-31T10:37:27.987Z
Learning: In the argocd-agent repository, Kubernetes manifests under test/data/ directories are test fixtures for e2e testing and do not require production-grade security hardening such as securityContext settings for runAsNonRoot or allowPrivilegeEscalation.
Applied to files:
cmd/ctl/check_config_test.go
🧬 Code graph analysis (3)
cmd/ctl/check_config.go (3)
internal/kube/client.go (2)
NewKubernetesClientFromConfig(58-98)KubernetesClient(37-44)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)internal/tlsutil/kubernetes.go (3)
TLSCertFromSecret(44-66)JWTSigningKeyFromSecret(167-191)X509CertPoolFromSecret(106-128)
cmd/ctl/main.go (1)
cmd/ctl/check_config.go (1)
NewCheckConfigCommand(49-61)
cmd/ctl/check_config_test.go (5)
internal/tlsutil/generate.go (4)
GenerateCertificate(148-177)GenerateCaCertificate(42-84)GenerateServerCertificate(114-142)GenerateClientCertificate(91-107)internal/tlsutil/kubernetes.go (1)
TLSCertFromSecret(44-66)internal/kube/client.go (1)
KubernetesClient(37-44)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)cmd/ctl/check_config.go (2)
RunPrincipalChecks(226-271)RunAgentChecks(275-307)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Build and push image
- GitHub Check: Run unit tests
- GitHub Check: Run end-to-end tests
- GitHub Check: Lint Go code
- GitHub Check: Analyze (go)
🔇 Additional comments (2)
cmd/ctl/check_config_test.go (1)
170-784: Thorough negative-path coverage keeps regressions in checkThe matrix of principal/agent failure cases (missing secrets, bad certs, mismatched routes, etc.) is exhaustive and mirrors production misconfigurations well. Thanks for putting in this depth of testing.
cmd/ctl/main.go (1)
52-52: Good to see the new command wired inHooking
NewCheckConfigCommand()into the root CLI ensures the new validations are reachable; looks good.
30858d9 to
7cc945d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
cmd/ctl/check_config.go (1)
554-555: Consider removing unused optional check.These lines perform an optional check to ensure the agent's namespace exists, but the result is intentionally ignored. If the check isn't needed, remove it to avoid confusion. If it serves a purpose (e.g., logging side-effects), add a comment explaining why.
Apply this diff to remove the dead code:
} - // optional: ensure agent's own namespace exists - _, _ = agentKube.CoreV1().Namespaces().Get(ctx, agentNS, metav1.GetOptions{}) return nil }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
cmd/ctl/check_config.go(1 hunks)cmd/ctl/check_config_test.go(1 hunks)cmd/ctl/main.go(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-31T10:37:27.987Z
Learnt from: chetan-rns
Repo: argoproj-labs/argocd-agent PR: 632
File: test/data/pre-sync/pre-sync-job.yaml:2-17
Timestamp: 2025-10-31T10:37:27.987Z
Learning: In the argocd-agent repository, Kubernetes manifests under test/data/ directories are test fixtures for e2e testing and do not require production-grade security hardening such as securityContext settings for runAsNonRoot or allowPrivilegeEscalation.
Applied to files:
cmd/ctl/check_config_test.go
🧬 Code graph analysis (3)
cmd/ctl/main.go (1)
cmd/ctl/check_config.go (1)
NewCheckConfigCommand(49-61)
cmd/ctl/check_config.go (3)
internal/kube/client.go (2)
NewKubernetesClientFromConfig(58-98)KubernetesClient(37-44)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)internal/tlsutil/kubernetes.go (3)
TLSCertFromSecret(44-66)JWTSigningKeyFromSecret(167-191)X509CertPoolFromSecret(106-128)
cmd/ctl/check_config_test.go (5)
internal/tlsutil/generate.go (4)
GenerateCertificate(148-177)GenerateCaCertificate(42-84)GenerateServerCertificate(114-142)GenerateClientCertificate(91-107)internal/tlsutil/kubernetes.go (1)
TLSCertFromSecret(44-66)internal/kube/client.go (1)
KubernetesClient(37-44)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)cmd/ctl/check_config.go (2)
RunPrincipalChecks(224-269)RunAgentChecks(273-305)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Lint Go code
- GitHub Check: Run unit tests
- GitHub Check: Run end-to-end tests
- GitHub Check: Build & cache Go code
- GitHub Check: Build and push image
- GitHub Check: Analyze (go)
🔇 Additional comments (2)
cmd/ctl/main.go (1)
52-52: LGTM!Clean integration of the new check-config command into the CLI hierarchy.
cmd/ctl/check_config_test.go (1)
170-1195: Excellent test coverage!The test suite comprehensively covers both success and failure scenarios for principal and agent validation, including edge cases like expired certificates, signature mismatches, empty CNs, and missing secrets. The test helpers effectively reduce duplication.
7cc945d to
87ab1c5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
cmd/ctl/check_config.go(1 hunks)cmd/ctl/check_config_test.go(1 hunks)cmd/ctl/main.go(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-31T10:37:27.987Z
Learnt from: chetan-rns
Repo: argoproj-labs/argocd-agent PR: 632
File: test/data/pre-sync/pre-sync-job.yaml:2-17
Timestamp: 2025-10-31T10:37:27.987Z
Learning: In the argocd-agent repository, Kubernetes manifests under test/data/ directories are test fixtures for e2e testing and do not require production-grade security hardening such as securityContext settings for runAsNonRoot or allowPrivilegeEscalation.
Applied to files:
cmd/ctl/check_config_test.go
🧬 Code graph analysis (3)
cmd/ctl/main.go (1)
cmd/ctl/check_config.go (1)
NewCheckConfigCommand(49-61)
cmd/ctl/check_config_test.go (5)
internal/tlsutil/generate.go (4)
GenerateCertificate(148-177)GenerateCaCertificate(42-84)GenerateServerCertificate(114-142)GenerateClientCertificate(91-107)internal/tlsutil/kubernetes.go (1)
TLSCertFromSecret(44-66)internal/kube/client.go (1)
KubernetesClient(37-44)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)cmd/ctl/check_config.go (2)
RunPrincipalChecks(224-275)RunAgentChecks(279-311)
cmd/ctl/check_config.go (3)
internal/kube/client.go (2)
NewKubernetesClientFromConfig(58-98)KubernetesClient(37-44)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)internal/tlsutil/kubernetes.go (3)
TLSCertFromSecret(44-66)JWTSigningKeyFromSecret(167-191)X509CertPoolFromSecret(106-128)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Build & cache Go code
- GitHub Check: Run end-to-end tests
- GitHub Check: Run unit tests
- GitHub Check: Lint Go code
- GitHub Check: Build and push image
- GitHub Check: Analyze (go)
7f9bd1c to
6dcc31a
Compare
…entctl which will verify the user's configuration Assisted-by: Cursor Signed-off-by: Rizwana777 <[email protected]>
6dcc31a to
527d8e9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
cmd/ctl/check_config.go(1 hunks)cmd/ctl/check_config_test.go(1 hunks)cmd/ctl/main.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- cmd/ctl/main.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-31T10:37:28.008Z
Learnt from: chetan-rns
Repo: argoproj-labs/argocd-agent PR: 632
File: test/data/pre-sync/pre-sync-job.yaml:2-17
Timestamp: 2025-10-31T10:37:28.008Z
Learning: In the argocd-agent repository, Kubernetes manifests under test/data/ directories are test fixtures for e2e testing and do not require production-grade security hardening such as securityContext settings for runAsNonRoot or allowPrivilegeEscalation.
Applied to files:
cmd/ctl/check_config_test.go
🧬 Code graph analysis (2)
cmd/ctl/check_config_test.go (5)
internal/tlsutil/generate.go (4)
GenerateCertificate(148-177)GenerateCaCertificate(42-84)GenerateServerCertificate(114-142)GenerateClientCertificate(91-107)internal/tlsutil/kubernetes.go (1)
TLSCertFromSecret(44-66)internal/kube/client.go (1)
KubernetesClient(37-44)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)cmd/ctl/check_config.go (2)
RunPrincipalChecks(221-292)RunAgentChecks(296-345)
cmd/ctl/check_config.go (3)
internal/kube/client.go (2)
NewKubernetesClientFromConfig(58-98)KubernetesClient(37-44)internal/config/constants.go (6)
SecretNamePrincipalCA(9-9)SecretNamePrincipalTLS(17-17)SecretNameProxyTLS(21-21)SecretNameJWT(29-29)SecretNameAgentCA(13-13)SecretNameAgentClientCert(25-25)internal/tlsutil/kubernetes.go (3)
TLSCertFromSecret(44-66)JWTSigningKeyFromSecret(167-191)X509CertPoolFromSecret(106-128)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Build & cache Go code
- GitHub Check: Lint Go code
- GitHub Check: Run end-to-end tests
- GitHub Check: Run unit tests
- GitHub Check: Build and push image
- GitHub Check: Analyze (go)
| if len(cert.Certificate) == 0 || cert.Certificate[0] == nil { | ||
| return nil, fmt.Errorf("%s/%s: secret does not contain certificate data", ns, name) | ||
| } | ||
| if len(cert.Certificate) > 1 { | ||
| return nil, fmt.Errorf("%s/%s: secret contains %d certificates, expected exactly one", ns, name, len(cert.Certificate)) | ||
| } | ||
| parsed, err := x509.ParseCertificate(cert.Certificate[0]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the single-certificate restriction in x509FromTLSSecret.
Rejecting secrets that contain more than one certificate will flag perfectly valid Kubernetes TLS secrets, because tls.crt commonly bundles the full chain (leaf + intermediates). Operators routinely store chains this way (see the ingress/TLS docs and cert-manager guidance). Our CLI will therefore fail even when the secret is healthy. Please drop the len(cert.Certificate) > 1 guard and just parse the first entry, optionally keeping the rest for follow-up validation.
- if len(cert.Certificate) == 0 || cert.Certificate[0] == nil {
- return nil, fmt.Errorf("%s/%s: secret does not contain certificate data", ns, name)
- }
- if len(cert.Certificate) > 1 {
- return nil, fmt.Errorf("%s/%s: secret contains %d certificates, expected exactly one", ns, name, len(cert.Certificate))
- }
+ if len(cert.Certificate) == 0 || cert.Certificate[0] == nil {
+ return nil, fmt.Errorf("%s/%s: secret does not contain certificate data", ns, name)
+ }
parsed, err := x509.ParseCertificate(cert.Certificate[0])📝 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.
| if len(cert.Certificate) == 0 || cert.Certificate[0] == nil { | |
| return nil, fmt.Errorf("%s/%s: secret does not contain certificate data", ns, name) | |
| } | |
| if len(cert.Certificate) > 1 { | |
| return nil, fmt.Errorf("%s/%s: secret contains %d certificates, expected exactly one", ns, name, len(cert.Certificate)) | |
| } | |
| parsed, err := x509.ParseCertificate(cert.Certificate[0]) | |
| if len(cert.Certificate) == 0 || cert.Certificate[0] == nil { | |
| return nil, fmt.Errorf("%s/%s: secret does not contain certificate data", ns, name) | |
| } | |
| parsed, err := x509.ParseCertificate(cert.Certificate[0]) |
🤖 Prompt for AI Agents
In cmd/ctl/check_config.go around lines 610 to 616, the function
x509FromTLSSecret incorrectly rejects secrets with more than one certificate
(tls.crt often contains a chain). Remove the guard that returns an error when
len(cert.Certificate) > 1 so the function no longer fails for valid chained
certificates; keep parsing cert.Certificate[0] as the leaf as currently done
and, if desired, retain cert.Certificate slice for any downstream chain
validation or logging rather than rejecting the secret outright.
JIRA - https://issues.redhat.com/browse/GITOPS-7958
Commands implemented via cobra
Implemented check-config with principal and agent subcommands
Principal: requires --principal-namespace; --principal-context is available and optional.
Agent: requires all four flags (--agent-context, --agent-namespace, --principal-context, --principal-namespace).
Principal checks implemented:
Verify CA secret exists and is valid: argocd-agent-ca
Verify principal gRPC TLS secret exists and is valid: argocd-agent-principal-tls
Verify resource proxy TLS secret exists and is valid: argocd-agent-resource-proxy-tls
Verify JWT signing key secret exists and parses: argocd-agent-jwt
Argo CD cluster-scoped, apps-any-namespace, OpenShift Route host matches IPS/DNS.
Agent checks implemented:
Verify agent CA secret with ca.crt exists: argocd-agent-ca
Verify agent client TLS secret exists, not expired, and signed by principal CA: argocd-agent-client-tls
Verify a namespace on principal matches agent cert CN (e.g., CN jonathans-cluster => namespace jonathans-cluster)
Also runs all principal checks (above) using provided principal context/namespace
Steps to verify this -
make setup-e2e
make cli
principal -
argocd-agentctl check-config principal --principal-namespace argocd --principal-context
agent -
argocd-agentctl check-config agent --agent-context --agent-namespace argocd --principal-context --principal-namespace argocd
Summary by CodeRabbit
New Features
Tests