argo

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 6, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package argo drives Argo CD entirely through the Kubernetes API: the dynamic client against the Application custom resource (argoproj.io/v1alpha1), never Argo's own REST/gRPC server and never an Argo API token (AGENTS.md §4.7, docs/repo-map.md's Kubernetes API row). Refresh merge-patches exactly one thing — the argocd.argoproj.io/refresh annotation — and Get only reads the object's own status subresource; nothing here imports argo-cd/v3 or k8s.io/kubectl. Every dynamic-client error goes through the same pkg/redact boundary pkg/k8s established (kubeconfig.go): the API server host, in every spelling a client error could echo, is scrubbed before the error leaves this package; only the kube context *name* may reach output (AGENTS.md §4.4).

Application.Namespace is where the Application custom resource itself lives on the cluster (RepoConfig.Kube.ArgoNamespace) — a control-plane namespace, conventionally "argocd" but never assumed to be (invariant 1 of the M5 brief). This is a different thing from spec.destination.namespace, which is the workload's own target env (see gitops.Env's doc comment): this repo's own fixtures already set both, distinctly, on every Application wrapper (metadata.namespace: argocd; spec.destination.namespace: <env>) — pkg/gitops reads only the latter (it has no reason to read the former, and is out of scope for this milestone), so the former comes from config here instead.

Index

Constants

View Source
const (
	SyncStatusSynced     = "Synced"
	HealthStatusHealthy  = "Healthy"
	HealthStatusDegraded = "Degraded"
	OperationFailed      = "Failed"
	OperationError       = "Error"
)

The status literals this package compares against — copied by value from github.com/argoproj/argo-cd's pkg/apis/application/v1alpha1/types.go (Apache License 2.0), not guessed (invariant 3 of the M5 brief: "confirm the real enum ... do not guess a made-up string"). hoist imports none of that module (AGENTS.md §4.7's 83-dependency refusal); these are the same strings the Application CR's status fields actually carry, without the import.

Variables

View Source
var ErrNotFound = errors.New("argo: application not found")

ErrNotFound is wrapped by Get and Refresh when the named Application does not exist — distinct from a transient plumbing error (a 404 here means "check kube.argo_namespace and the repo's Application wrappers", not "retry").

Functions

This section is empty.

Types

type Application

type Application struct {
	Namespace string
	Name      string
}

Application identifies one Argo CD Application custom resource: its own name and the namespace it lives in on the cluster. See the package doc for why Namespace is not spec.destination.namespace.

func (Application) String

func (a Application) String() string

type Argo

type Argo interface {
	// Refresh merge-patches app's annotations with argocd.argoproj.io/refresh: normal — the
	// sole write this package performs. Argo's own controller treats a refresh request as
	// idempotent and clears the annotation once it has processed it, which is exactly why
	// ArgoRefreshedStep does not try to detect "already refreshed" from the annotation's own
	// presence (see its doc comment in internal/engine).
	Refresh(ctx context.Context, app Application) error
	// Get reads app's current status. A missing Application wraps ErrNotFound.
	Get(ctx context.Context, app Application) (Status, error)
}

Argo is what internal/engine's ArgoRefreshedStep/ArgoSyncedStep need from Argo CD, driven entirely through the Kubernetes API (AGENTS.md §4.7). Both methods work on exactly one Application at a time; a promotion touching several calls this once per Application.

func FromDynamicClient

func FromDynamicClient(dyn dynamic.Interface, hide ...string) Argo

FromDynamicClient wraps an existing dynamic client — the dynamic fake in tests. Every string in hide is scrubbed from every error message the returned Argo produces.

func NewFromKubeconfig

func NewFromKubeconfig(kubeconfigContext string) (Argo, string, error)

NewFromKubeconfig builds an Argo over the user's kubeconfig ($KUBECONFIG or ~/.kube/config) using the named context, or the file's current context when kubeconfigContext is "" — the same loading rules k8s.NewCluster uses (pkg/k8s/kubeconfig.go), duplicated rather than shared: pkg/argo is its own self-contained activity-shaped adaptor (AGENTS.md §4.3), and nine lines of clientcmd wiring is cheaper than a cross-package dependency between two adaptors that otherwise share nothing. The second result is the context actually in use, for the caller to print (AGENTS.md §4.4). Nothing is contacted here; the first request happens in Refresh or Get.

type Fake

type Fake struct {
	Statuses map[Application]Status
	// GetErr and RefreshErr, when set, are returned by every call to the matching method
	// instead of the configured/not-found behavior — simulating a transient plumbing error a
	// caller must retry rather than treat as authoritative.
	GetErr, RefreshErr error
	// OnRefresh, when set, runs on every Refresh — see Refresh's own doc comment.
	OnRefresh func(app Application)

	Calls []string
	// contains filtered or unexported fields
}

Fake is an in-memory Argo for tests in other packages (internal/engine's step tests in particular — invariant 7 of the M5 brief: engine-level step tests use a hand-rolled fake Argo interface, mirroring pkg/forge.Fake/pkg/git's test doubles, not the dynamic fake directly). Statuses is keyed by Application; an app absent from it reports ErrNotFound from Get, exactly like a real cluster with no such Application — mirroring pkg/k8s.Fake's DockerConfigSecret (a named object either exists or it doesn't), not its RunningImages (a list that can legitimately be empty). Calls records every method invocation, in order, for a test asserting call counts or their absence — "hoist watch never calls Refresh" in particular.

func (*Fake) Get

func (f *Fake) Get(_ context.Context, app Application) (Status, error)

Get implements Argo.

func (*Fake) Refresh

func (f *Fake) Refresh(_ context.Context, app Application) error

Refresh implements Argo. It never mutates Statuses itself — a test that wants Refresh to have an observable effect calls SetStatus afterward, exactly as the real controller's own reconcile (not this call) is what actually changes status.

func (*Fake) SetStatus

func (f *Fake) SetStatus(app Application, st Status)

SetStatus records app's current status, thread-safely — the way a test simulates Argo reconciling to a new state between polls.

type Status

type Status struct {
	SyncStatus     string    // status.sync.status: "Synced", "OutOfSync", "Unknown", ...
	SyncRevision   string    // status.sync.revision: the commit sha Argo last compared/synced against
	HealthStatus   string    // status.health.status: "Healthy", "Degraded", "Progressing", ...
	OperationPhase string    // status.operationState.phase: "", "Running", "Succeeded", "Failed", "Error", "Terminating"
	ReconciledAt   time.Time // status.reconciledAt; zero when absent or unparsable
}

Status is the subset of an Application's .status this package reads, straight off the unstructured object with no local caching — every Get is a fresh read (AGENTS.md §4.1).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL