generated from mathias/template-go-web
feat(atlas): Phase C — live Flux reconcile status on stage 07
Stage 07 now also shows the Flux `apps` Kustomization state — reconciled/failed + last-applied revision (main@shortsha) — read in-cluster (new read-only Role in flux-system). Sits alongside the live deploy node. FluxStatus/FluxNode test-first, fallback-safe. Verified: build/vet/lint(0)/test green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,70 @@ func HostsFromNodes(nodesJSON []byte) ([]Host, error) {
|
||||
return hosts, nil
|
||||
}
|
||||
|
||||
// Flux is the reconciliation state of a Flux Kustomization.
|
||||
type Flux struct {
|
||||
Ready bool
|
||||
Reason string
|
||||
Revision string
|
||||
}
|
||||
|
||||
// FluxStatus parses a Flux Kustomization object into its reconcile state.
|
||||
func FluxStatus(kustJSON []byte) (Flux, error) {
|
||||
var k struct {
|
||||
Status struct {
|
||||
Conditions []struct {
|
||||
Type string `json:"type"`
|
||||
Status string `json:"status"`
|
||||
Reason string `json:"reason"`
|
||||
} `json:"conditions"`
|
||||
LastAppliedRevision string `json:"lastAppliedRevision"`
|
||||
} `json:"status"`
|
||||
}
|
||||
if err := json.Unmarshal(kustJSON, &k); err != nil {
|
||||
return Flux{}, fmt.Errorf("parse kustomization: %w", err)
|
||||
}
|
||||
f := Flux{Revision: shortRev(k.Status.LastAppliedRevision)}
|
||||
for _, c := range k.Status.Conditions {
|
||||
if c.Type == "Ready" {
|
||||
f.Ready = c.Status == "True"
|
||||
f.Reason = c.Reason
|
||||
}
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// FluxNode renders the Flux reconcile state as a stage node.
|
||||
func FluxNode(f Flux) Node {
|
||||
if f.Ready {
|
||||
return Node{
|
||||
Title: "⟳ Flux · reconciled · " + f.Revision,
|
||||
Pill: "var(--green)",
|
||||
Tags: []string{"live · k8s"},
|
||||
}
|
||||
}
|
||||
return Node{
|
||||
Title: "⟳ Flux · " + f.Reason,
|
||||
Pill: "var(--coral)",
|
||||
Tags: []string{"live · k8s"},
|
||||
}
|
||||
}
|
||||
|
||||
// shortRev turns a Flux revision "main@sha1:<full>" into "main@<short>".
|
||||
func shortRev(rev string) string {
|
||||
at := strings.Index(rev, "@")
|
||||
if at < 0 {
|
||||
return rev
|
||||
}
|
||||
branch, sha := rev[:at], rev[at+1:]
|
||||
if c := strings.LastIndex(sha, ":"); c >= 0 {
|
||||
sha = sha[c+1:]
|
||||
}
|
||||
if len(sha) > 7 {
|
||||
sha = sha[:7]
|
||||
}
|
||||
return branch + "@" + sha
|
||||
}
|
||||
|
||||
// Deploy is the live state of a Kubernetes Deployment.
|
||||
type Deploy struct {
|
||||
Image string
|
||||
|
||||
Reference in New Issue
Block a user