Skip to content

patterns-operator copies git auth secret into Application *name* as a *namespace* (breaks singleArgoCD + tokenSecret) #838

Description

@cjeanner

Summary

When spec.gitSpec.tokenSecret is set, the patterns-operator copies the bootstrap git credentials twice:

  1. Into the real ArgoCD namespace (vp-gitops / getClusterWideArgoNamespace()) as vp-private-repo-credentials — correct.
  2. Into a namespace named {pattern}-{clusterGroupName} via applicationName(pattern) — incorrect under single ArgoCD.

Under global.singleArgoCD: true, that string is only the ClusterGroup Application name (e.g. rhoso-gitops-standalone). The Application lives in vp-gitops; the namespace rhoso-gitops-standalone does not exist by default. Reconcile fails with:

Reconcile step "copying clusterwide git auth secret to namespaced argo" failed:
namespaces "rhoso-gitops-standalone" not found

until an empty namespace with that name is created by hand.

This looks like a leftover from the legacy per-pattern ArgoCD layout (namespace == application name), not updated for single-ArgoCD.

Environment

  • patterns-operator: v0.0.80 (community-operators fast)
  • Pattern: rhoso-gitops in patterns-operator
  • spec.clusterGroupName: standalone
  • global.singleArgoCD: true (pattern values)
  • ArgoCD instance: vp-gitops / namespace vp-gitops
  • ClusterGroup Application: rhoso-gitops-standalone in namespace vp-gitops (name ≠ namespace)
  • Git auth: SSH (git@…) via Argo-shaped Secret + tokenSecret / tokenSecretNamespace

Steps to reproduce

  1. Deploy a pattern with singleArgoCD: true.

  2. Provide git credentials via Secret (e.g. openshift-operators/private-repo with sshPrivateKey / url / type=git and label argocd.argoproj.io/secret-type: repository).

  3. Set on the Pattern CR:

    spec:
      clusterGroupName: standalone
      gitSpec:
        targetRepo: git@…   # or https
        tokenSecret: private-repo
        tokenSecretNamespace: openshift-operators
  4. Do not pre-create namespace rhoso-gitops-standalone.

  5. Watch Pattern status / operator logs.

Actual behavior

  • Operator successfully clones with the secret (SSH/HTTPS auth for local checkout works).

  • First copy of credentials into vp-gitops as vp-private-repo-credentials succeeds.

  • Second copy targets namespace rhoso-gitops-standalone and fails:

    namespaces "rhoso-gitops-standalone" not found
    lastStep: copying clusterwide git auth secret to namespaced argo
    
  • Reconcile loops until that namespace exists.

  • Creating an empty Namespace/rhoso-gitops-standalone unblocks reconcile (lastStep: reconcile complete), but leaves a useless namespace that is not the ArgoCD instance namespace.

Expected behavior

Under single ArgoCD (vp-gitops):

  • Git auth secret should be copied only into the ArgoCD namespace (getClusterWideArgoNamespace() → vp-gitops), not into a namespace derived from applicationName().
  • Reconcile should complete without requiring a namespace whose name happens to equal the ClusterGroup Application name.
  • Optionally: if a second copy remains for legacy multi-Argo mode, it should only run when a namespaced Argo instance actually exists in {pattern}-{clusterGroup}.

Code references

applicationName is pattern + clusterGroup (Application name):

// internal/controller/argo.go
func applicationName(p *api.Pattern) string {
    return fmt.Sprintf("%s-%s", p.Name, p.Spec.ClusterGroupName)
}

Two copy sites in reconcile (internal/controller/pattern_controller.go):

// 1) Correct for single ArgoCD — destination = Argo namespace (vp-gitops)
r.copyAuthGitSecret(
    qualifiedInstance.Spec.GitConfig.TokenSecretNamespace,
    qualifiedInstance.Spec.GitConfig.TokenSecret,
    getClusterWideArgoNamespace(),
    "vp-private-repo-credentials")

// … later, after reconcileApplication …

// 2) Bug under single ArgoCD — destination = Application *name* used as *namespace*
r.copyAuthGitSecret(
    qualifiedInstance.Spec.GitConfig.TokenSecretNamespace,
    qualifiedInstance.Spec.GitConfig.TokenSecret,
    applicationName(qualifiedInstance),  // e.g. "rhoso-gitops-standalone"
    "vp-private-repo-credentials")

copyAuthGitSecret treats the third argument as destNamespace and Create/Update’s the Secret there (pattern_controller.go).

Lab confirmation:

  • Pattern: clusterGroupName=standalone → applicationName = rhoso-gitops-standalone
  • Application object: name=rhoso-gitops-standalone, namespace=vp-gitops
  • No Pattern CR field redirects the second copy destination (tokenSecret / tokenSecretNamespace only control the source).

Workaround

oc create namespace rhoso-gitops-standalone   # or {pattern}-{clusterGroupName}

Reconcile then completes; Argo still uses credentials in vp-gitops.

Suggested fix

  • Prefer: second copyAuthGitSecret should also use getClusterWideArgoNamespace() when single-ArgoCD / cluster-wide instance is active; or drop the second copy if redundant with the first.
  • Legacy path: only copy into applicationName(p) if that namespace hosts a namespaced ArgoCD instance (multi-Argo mode).
  • Add a regression test: Pattern with tokenSecret + single ArgoCD in vp-gitops, Application named {pattern}-{clusterGroup} in vp-gitops, no namespace {pattern}-{clusterGroup} → reconcile succeeds and Secret exists in vp-gitops only.

Impact

  • Blocks Pattern reconcile whenever tokenSecret is used with single ArgoCD until a dummy namespace is created.
  • Affects private-repo / SSH / HTTPS token bootstrap flows documented for Validated Patterns (TOKEN_SECRET / tokenSecret).
  • Easy to misdiagnose as a secrets or Argo config problem.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions