package templates import ( "fmt" "vetting/internal/model" ) // HostDetailData is the full payload the detail handler hands to the // HostDetail template. Tile carries host + latest-run enrichment (same // shape the dashboard tile uses), Stages/SpecDiffs drive the pipeline // and diff list. type HostDetailData struct { Tile TileData Stages []model.Stage SpecDiffs []model.SpecDiff } templ HostDetail(d HostDetailData) { @Layout(d.Tile.Host.Name) {

{ d.Tile.Host.Name }

{ lastSeenLabel(d.Tile.LastSeenAt) } { tileStatus(d.Tile.Latest) }
MAC
{ d.Tile.Host.MAC }
WoL
{ fmt.Sprintf("%s:%d", d.Tile.Host.WoLBroadcastIP, d.Tile.Host.WoLPort) }
if d.Tile.Latest != nil && d.Tile.Latest.FailedStage != "" {
Failed at
{ d.Tile.Latest.FailedStage }
} if d.Tile.SpecDiffCritical > 0 {
Spec diffs
{ fmt.Sprintf("%d critical", d.Tile.SpecDiffCritical) }
}
if d.Tile.Latest != nil {

Pipeline

@Pipeline(BuildPipeline(d.Tile.Latest, d.Stages))
} else {

Pipeline

@Pipeline(BuildPipeline(nil, nil))
} if d.Tile.Latest != nil && d.Tile.Latest.State == model.StateFailedHolding && d.Tile.Latest.HoldIP != "" {

Host is holding — SSH available

{ sshInvocation(d.Tile.HoldKeyPath, d.Tile.Latest.HoldIP) }
}

Actions

if canStart(d.Tile.Latest) {
} else { } if canOverrideWipe(d.Tile.Latest) {
} if hasReport(d.Tile.Latest) { View report }
if len(d.SpecDiffs) > 0 {

Spec diffs ({ fmt.Sprintf("%d", len(d.SpecDiffs)) })

    for _, diff := range d.SpecDiffs {
  • { diff.Field }
    expected: { diff.Expected }
    actual: { diff.Actual }
  • }
} if d.Tile.Latest != nil {

Log

}

Host details

if d.Tile.Host.Notes != "" {

Notes

{ d.Tile.Host.Notes }

}

Expected spec

{ d.Tile.Host.ExpectedSpecYAML }
} } // hasCriticalDiff opens the spec-diff
by default when any // diff is critical — operator shouldn't have to click to see the blocker. func hasCriticalDiff(diffs []model.SpecDiff) bool { for _, d := range diffs { if d.Severity == "critical" && !d.Ignored { return true } } return false }