deploy

package
v1.801.60 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

actions.go — the two GitOps write actions.

POST /v1/deploy/{name}/rollback — pin the CR image tag to a prior clean semver.
  It REUSES the P1 release seam (cloud.OnServiceRelease → clients/paas
  releaseService), so the clean-semver gate + idempotent spec.image patch live
  in exactly ONE place; the operator reconciles the rollout.
POST /v1/deploy/{name}/sync — request an operator reconcile now by touching the
  CR (an annotation bump the operator's watch observes). Today the CR is the
  desired source, so sync = nudge-reconcile; when git.hanzo.ai is the source it
  becomes apply-desired-from-git, same endpoint.

applications.go — GET /v1/deploy/applications: the fleet list. Each operator Service CR is one Application row: its declared image version, the running version observed from the live Deployment, the reconciled health, and the sync verdict (declared == running ⇒ Synced, else OutOfSync). The console renders this as the ArgoCD application list.

Package gitops mounts the native GitOps control plane at /v1/deploy — the ArgoCD-grade deploy dashboard for the operator-managed fleet, made native to the cloud binary and parallel to /v1/git (the native git server).

Each operator hanzo.ai/v1 App CR IS a GitOps Application: the desired state declared for one workload, which the Hanzo operator reconciles into a Deployment + Service + Ingress (+ HPA/PDB/Pods). This plane OBSERVES that reconciliation the way ArgoCD observes a synced Application —

GET  /v1/deploy/applications        — the fleet list: name, declared version,
                                      health, sync, per app.
GET  /v1/deploy/{name}/tree         — the owned-resource tree (ownerRef edges)
                                      with per-node health + sync.
GET  /v1/deploy/{name}/resource/{ref} — one node's live manifest + a
                                      desired-vs-live diff.
GET  /v1/deploy/{name}/logs         — the app's current pod logs.
POST /v1/deploy/{name}/rollback     — pin the CR image tag to a prior semver
                                      (the operator reconciles the rollout).
POST /v1/deploy/{name}/sync         — request an operator reconcile now.

SECURITY — every route is SUPERADMIN ONLY, fail-closed, on the SAME predicate the rest of cloud uses (c.IsAdmin()): the plane reads and mutates SYSTEM Service CRs across the whole fleet, so a tenant must never reach it. Secret objects are never surfaced (no node, no manifest) so the tree can never leak materialized env. The user-facing per-org PaaS is /v1/platform; this is the platform-operator console the admin dashboard consumes.

GitOps note (the follow-on seam): today the CR is the desired-state source and a rollback/rollout PATCHES it directly (P1's RegisterServiceReleaser), so deploys work now. The end-state is true GitOps on OUR native git — RegisterPushBuilder commits the CR image-tag change to the manifest repo on git.hanzo.ai (github.com/hanzoai/git) and this engine syncs that repo → cluster with self-heal. The desired-vs-live diff below is already structured for that: it reads a desired source that is "cluster last-applied" now and becomes the git.hanzo.ai manifest later, with no shape change. See deployDesiredTODO.

health.go — per-resource health, the ArgoCD `pkg/health` vocabulary made native (Healthy / Progressing / Degraded / Suspended / Missing / Unknown). It is a PURE function over one live object, so the list + tree derive an honest per-node health with no cluster round-trip beyond the object already read.

P2b swaps the internals for github.com/argoproj/gitops-engine pkg/health (health.GetResourceHealth) for exact ArgoCD parity; the CODES emitted here are already those strings, so the wire contract the console consumes does not change.

logs.go — GET /v1/deploy/{name}/logs: the app's current pod logs, streamed from the newest running pod via the typed CoreV1 GetLogs subresource. The operator labels the workload it renders for an App CR with app.kubernetes.io/instance=<name>, so that selects the app's pods; the most-recently-started pod is read (the current rollout). Optional ?container= selects a container; ?tail= bounds the lines. Never fabricates output — an unreachable cluster or absent pod yields an honest 200 with an empty tail + the reason, not invented logs.

resource.go — GET /v1/deploy/{name}/resource/{ref}: one tree node's live manifest plus a desired-vs-live diff.

{ref} is the canonical "group:kind:namespace:name" token the tree emits on each node, so the console round-trips it back verbatim. The kind must be in the closed registry (kindGVR) and the namespace a platform namespace, and the object must belong to {name}'s tree (it IS the CR, or carries an ownerRef/label tying it to the app) — so the endpoint can never be steered at an arbitrary cluster object. Secrets are not in the registry, so their manifests are never returned.

desiredSource: today "last-applied" (the object's kubectl last-applied-config annotation) or "none". When git.hanzo.ai becomes the manifest source of truth (RegisterPushBuilder → commit → engine sync), desiredSource becomes "git" with the SAME diff shape. P2b replaces the field-strip diff with gitops-engine pkg/diff (three-way) for exact ArgoCD parity.

tree.go — GET /v1/deploy/{name}/tree: the owned-resource tree for one Application, the ArgoCD ApplicationTree shape (a FLAT node list with parentRefs edges; the console renders the DAG). The root is the Service CR; depth-1 nodes are the operator-owned Deployment/Service/Ingress/HPA/PDB/ConfigMap; depth-2 are the Deployment's ReplicaSets and their Pods. Ownership is by ownerReferences.uid with a name-equals-app fallback (some operator-rendered children are named after the CR). Secret objects are never included — the tree cannot leak env.

P2b swaps buildTree's cluster walk for github.com/argoproj/gitops-engine pkg/cache (ClusterCache.GetManagedLiveObjs / hierarchy) for a watch-backed tree; the Node shape the console consumes does not change.

Index

Constants

View Source
const (
	SyncSynced    = "synced"
	SyncOutOfSync = "out-of-sync"
	SyncUnknown   = "unknown"
)

Sync codes — the ArgoCD sync vocabulary, lowercased for the wire.

View Source
const (
	HealthHealthy     = "healthy"
	HealthProgressing = "progressing"
	HealthDegraded    = "degraded"
	HealthSuspended   = "suspended"
	HealthMissing     = "missing"
	HealthUnknown     = "unknown"
)

Health codes — the ArgoCD health vocabulary, lowercased for the wire.

Variables

This section is empty.

Functions

func Mount

func Mount(app *zip.App, deps cloud.Deps) error

Mount wires /v1/deploy/* onto app. Every handler gates on c.IsAdmin() first.

Types

type Application

type Application struct {
	Name           string   `json:"name"`
	Namespace      string   `json:"namespace"`
	Env            string   `json:"env"`            // main|test|dev
	Role           string   `json:"role,omitempty"` // spec.role after the kind collapse (App)
	Repository     string   `json:"repository"`
	Version        string   `json:"version"`        // declared: spec.image.tag
	RunningVersion string   `json:"runningVersion"` // observed from the Deployment
	Health         string   `json:"health"`         // healthy|progressing|degraded|suspended|missing|unknown
	HealthMessage  string   `json:"healthMessage,omitempty"`
	Sync           string   `json:"sync"` // synced|out-of-sync|unknown
	Phase          string   `json:"phase,omitempty"`
	Endpoints      []string `json:"endpoints"`
}

Application is one fleet row. Shapes the exact fields the console list consumes.

type Node

type Node struct {
	ResourceRef
	UID           string        `json:"uid,omitempty"`
	CreatedAt     string        `json:"createdAt,omitempty"`
	Health        string        `json:"health"`
	HealthMessage string        `json:"healthMessage,omitempty"`
	Sync          string        `json:"sync,omitempty"`
	Version       string        `json:"version,omitempty"` // image tag for a workload node
	ParentRefs    []ResourceRef `json:"parentRefs,omitempty"`
}

Node is one resource in the tree: its ref, ownerRef parents, and derived health/sync (+ image version for a workload). ArgoCD ResourceNode shape.

type ResourceRef

type ResourceRef struct {
	Group     string `json:"group"`
	Version   string `json:"version"`
	Kind      string `json:"kind"`
	Namespace string `json:"namespace"`
	Name      string `json:"name"`
	Ref       string `json:"ref"`
}

ResourceRef identifies one node — the round-trip token the resource endpoint parses. Ref is the canonical "group:kind:namespace:name" string.

Jump to

Keyboard shortcuts

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