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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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) 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).