add auth support
continuous-integration/drone/push Build is passing

This commit is contained in:
nathan committed 2026-04-17 13:19:08 +10:00
1 parent 9a561f3b07
commit ae3e2be89a
22 files changed
+2479 -40

No files matched your search

+7 -1
View File
@@ -21,7 +21,7 @@ templ Index(info BuildInfo) {
<div>
<div class="web2-pill">vCTP Console</div>
<h1 class="mt-3 text-4xl font-bold">Chargeback Intelligence Dashboard</h1>
<p class="mt-2 text-sm text-slate-600">Point in time snapshots of consumption.</p>
<p class="mt-2 text-sm text-slate-600">Point in time snapshots of consumption with LDAP/JWT protected API access.</p>
</div>
<div class="web2-button-group">
<a class="web2-button" href="/snapshots/hourly">Hourly Snapshots</a>
@@ -58,6 +58,12 @@ templ Index(info BuildInfo) {
<p class="mt-2 text-sm text-slate-600">
Use fast vCenter totals views (Daily Aggregated and Hourly Detail 45d) and VM Trace views (Hourly Detail and Daily Aggregated) to move between long-range trends and granular timelines.
</p>
<p class="mt-2 text-sm text-slate-600">
When authentication is enabled, obtain a token from <code class="web2-code">POST /api/auth/login</code> and send it as <code class="web2-code">Authorization: Bearer &lt;token&gt;</code>.
</p>
<p class="mt-2 text-sm text-slate-600">
Role policy: <code class="web2-code">viewer</code> role covers read/report APIs, and <code class="web2-code">admin</code> role covers mutating/admin APIs (<code class="web2-code">admin</code> also grants viewer access). UI pages and <code class="web2-code">/metrics</code> remain public.
</p>
</div>
<div class="web2-card">
<h2 class="text-lg font-semibold mb-2">Snapshots and Reports</h2>
+2 -2
View File
@@ -47,7 +47,7 @@ func Index(info BuildInfo) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<body class=\"flex flex-col min-h-screen web2-bg\"><main class=\"flex-grow web2-shell space-y-8\"><section class=\"web2-header\"><div class=\"flex flex-col gap-4 md:flex-row md:items-center md:justify-between\"><div><div class=\"web2-pill\">vCTP Console</div><h1 class=\"mt-3 text-4xl font-bold\">Chargeback Intelligence Dashboard</h1><p class=\"mt-2 text-sm text-slate-600\">Point in time snapshots of consumption.</p></div><div class=\"web2-button-group\"><a class=\"web2-button\" href=\"/snapshots/hourly\">Hourly Snapshots</a> <a class=\"web2-button\" href=\"/snapshots/daily\">Daily Snapshots</a> <a class=\"web2-button\" href=\"/snapshots/monthly\">Monthly Snapshots</a> <a class=\"web2-button\" href=\"/vm/trace\">VM Trace</a> <a class=\"web2-button\" href=\"/vcenters\">vCenters</a> <a class=\"web2-button\" href=\"/swagger/\">Swagger UI</a></div></div></section><section class=\"grid gap-6 md:grid-cols-3\"><div class=\"web2-card\"><p class=\"text-xs uppercase tracking-[0.2em] text-slate-400\">Build Time</p><p class=\"mt-3 text-xl font-semibold\">")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<body class=\"flex flex-col min-h-screen web2-bg\"><main class=\"flex-grow web2-shell space-y-8\"><section class=\"web2-header\"><div class=\"flex flex-col gap-4 md:flex-row md:items-center md:justify-between\"><div><div class=\"web2-pill\">vCTP Console</div><h1 class=\"mt-3 text-4xl font-bold\">Chargeback Intelligence Dashboard</h1><p class=\"mt-2 text-sm text-slate-600\">Point in time snapshots of consumption with LDAP/JWT protected API access.</p></div><div class=\"web2-button-group\"><a class=\"web2-button\" href=\"/snapshots/hourly\">Hourly Snapshots</a> <a class=\"web2-button\" href=\"/snapshots/daily\">Daily Snapshots</a> <a class=\"web2-button\" href=\"/snapshots/monthly\">Monthly Snapshots</a> <a class=\"web2-button\" href=\"/vm/trace\">VM Trace</a> <a class=\"web2-button\" href=\"/vcenters\">vCenters</a> <a class=\"web2-button\" href=\"/swagger/\">Swagger UI</a></div></div></section><section class=\"grid gap-6 md:grid-cols-3\"><div class=\"web2-card\"><p class=\"text-xs uppercase tracking-[0.2em] text-slate-400\">Build Time</p><p class=\"mt-3 text-xl font-semibold\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -86,7 +86,7 @@ func Index(info BuildInfo) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</p></div></section><section class=\"grid gap-6 lg:grid-cols-3\"><div class=\"web2-card\"><h2 class=\"text-lg font-semibold mb-2\">Overview</h2><p class=\"mt-2 text-sm text-slate-600\">vCTP is a vSphere Chargeback Tracking Platform.</p><p class=\"mt-2 text-sm text-slate-600\">Use fast vCenter totals views (Daily Aggregated and Hourly Detail 45d) and VM Trace views (Hourly Detail and Daily Aggregated) to move between long-range trends and granular timelines.</p></div><div class=\"web2-card\"><h2 class=\"text-lg font-semibold mb-2\">Snapshots and Reports</h2><div class=\"mt-3 text-sm text-slate-600 web2-paragraphs\"><p>Hourly snapshots capture inventory per vCenter (concurrency via <code class=\"web2-code\">hourly_snapshot_concurrency</code>), then daily and monthly summaries are derived from those snapshots.</p><p><strong>Hourly tracks:</strong> VM identity (<code class=\"web2-code\">InventoryId</code>, <code class=\"web2-code\">Name</code>, <code class=\"web2-code\">VmId</code>, <code class=\"web2-code\">VmUuid</code>, <code class=\"web2-code\">Vcenter</code>, <code class=\"web2-code\">EventKey</code>, <code class=\"web2-code\">CloudId</code>), lifecycle (<code class=\"web2-code\">CreationTime</code>, <code class=\"web2-code\">DeletionTime</code>, <code class=\"web2-code\">SnapshotTime</code>), placement (<code class=\"web2-code\">Datacenter</code>, <code class=\"web2-code\">Cluster</code>, <code class=\"web2-code\">Folder</code>, <code class=\"web2-code\">ResourcePool</code>), and sizing/state (<code class=\"web2-code\">VcpuCount</code>, <code class=\"web2-code\">RamGB</code>, <code class=\"web2-code\">ProvisionedDisk</code>, <code class=\"web2-code\">PoweredOn</code>, <code class=\"web2-code\">IsTemplate</code>, <code class=\"web2-code\">SrmPlaceholder</code>).</p><p><strong>Daily tracks:</strong> <code class=\"web2-code\">SamplesPresent</code>, <code class=\"web2-code\">TotalSamples</code>, <code class=\"web2-code\">AvgIsPresent</code>, <code class=\"web2-code\">AvgVcpuCount</code>, <code class=\"web2-code\">AvgRamGB</code>, <code class=\"web2-code\">AvgProvisionedDisk</code>, <code class=\"web2-code\">PoolTinPct</code>, <code class=\"web2-code\">PoolBronzePct</code>, <code class=\"web2-code\">PoolSilverPct</code>, <code class=\"web2-code\">PoolGoldPct</code>, plus chargeback totals columns <code class=\"web2-code\">Tin</code>, <code class=\"web2-code\">Bronze</code>, <code class=\"web2-code\">Silver</code>, <code class=\"web2-code\">Gold</code>.</p><p><strong>Monthly tracks:</strong> the same daily aggregate fields, with monthly values weighted by per-day sample volume so partial-day VMs and config changes stay proportional.</p><p>Snapshots are registered in <code class=\"web2-code\">snapshot_registry</code> so regeneration via <code class=\"web2-code\">/api/snapshots/aggregate</code> can locate the correct tables (fallback scanning is also supported).</p><p>vCenter totals pages are accelerated by compact cache tables: <code class=\"web2-code\">vcenter_latest_totals</code> and <code class=\"web2-code\">vcenter_aggregate_totals</code>.</p><p>VM Trace daily mode uses the <code class=\"web2-code\">vm_daily_rollup</code> cache when available, and falls back to daily summary tables if needed.</p><p>Reports (XLSX with totals/charts) are generated automatically after hourly, daily, and monthly jobs and written to a reports directory.</p><p>Hourly totals are interval-based: each row represents <code class=\"web2-code\">[HH:00, HH+1:00)</code> and uses the first snapshot at or after the hour end (including cross-day snapshots) to prorate VM presence.</p><p>Monthly aggregation reports include a Daily Totals sheet with full-day interval labels (YYYY-MM-DD to YYYY-MM-DD) and prorated totals.</p></div></div><div class=\"web2-card\"><h2 class=\"text-lg font-semibold mb-2\">Prorating and Aggregation</h2><div class=\"mt-3 space-y-2 text-sm text-slate-600 web2-paragraphs\"><p><code class=\"web2-code\">SamplesPresent</code> is the count of snapshots in which the VM appears; <code class=\"web2-code\">TotalSamples</code> is the count of unique snapshot times for that vCenter/day.</p><p><code class=\"web2-code\">AvgIsPresent = SamplesPresent / TotalSamples</code> (0 when <code class=\"web2-code\">TotalSamples</code> is 0).</p><p>Daily <code class=\"web2-code\">AvgVcpuCount</code>, <code class=\"web2-code\">AvgRamGB</code>, and <code class=\"web2-code\">AvgProvisionedDisk</code> are per-sample sums divided by <code class=\"web2-code\">TotalSamples</code> (time-weighted).</p><p>Daily pool percentages (<code class=\"web2-code\">PoolTinPct</code>/<code class=\"web2-code\">PoolBronzePct</code>/<code class=\"web2-code\">PoolSilverPct</code>/<code class=\"web2-code\">PoolGoldPct</code>) use pool-hit counts divided by <code class=\"web2-code\">SamplesPresent</code>.</p><p>Monthly aggregation converts each day into weighted sums using sample volume, then recLine truncated
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</p></div></section><section class=\"grid gap-6 lg:grid-cols-3\"><div class=\"web2-card\"><h2 class=\"text-lg font-semibold mb-2\">Overview</h2><p class=\"mt-2 text-sm text-slate-600\">vCTP is a vSphere Chargeback Tracking Platform.</p><p class=\"mt-2 text-sm text-slate-600\">Use fast vCenter totals views (Daily Aggregated and Hourly Detail 45d) and VM Trace views (Hourly Detail and Daily Aggregated) to move between long-range trends and granular timelines.</p><p class=\"mt-2 text-sm text-slate-600\">When authentication is enabled, obtain a token from <code class=\"web2-code\">POST /api/auth/login</code> and send it as <code class=\"web2-code\">Authorization: Bearer &lt;token&gt;</code>.</p><p class=\"mt-2 text-sm text-slate-600\">Role policy: <code class=\"web2-code\">viewer</code> role covers read/report APIs, and <code class=\"web2-code\">admin</code> role covers mutating/admin APIs (<code class=\"web2-code\">admin</code> also grants viewer access). UI pages and <code class=\"web2-code\">/metrics</code> remain public.</p></div><div class=\"web2-card\"><h2 class=\"text-lg font-semibold mb-2\">Snapshots and Reports</h2><div class=\"mt-3 text-sm text-slate-600 web2-paragraphs\"><p>Hourly snapshots capture inventory per vCenter (concurrency via <code class=\"web2-code\">hourly_snapshot_concurrency</code>), then daily and monthly summaries are derived from those snapshots.</p><p><strong>Hourly tracks:</strong> VM identity (<code class=\"web2-code\">InventoryId</code>, <code class=\"web2-code\">Name</code>, <code class=\"web2-code\">VmId</code>, <code class=\"web2-code\">VmUuid</code>, <code class=\"web2-code\">Vcenter</code>, <code class=\"web2-code\">EventKey</code>, <code class=\"web2-code\">CloudId</code>), lifecycle (<code class=\"web2-code\">CreationTime</code>, <code class=\"web2-code\">DeletionTime</code>, <code class=\"web2-code\">SnapshotTime</code>), placement (<code class=\"web2-code\">Datacenter</code>, <code class=\"web2-code\">Cluster</code>, <code class=\"web2-code\">Folder</code>, <code class=\"web2-code\">ResourcePool</code>), and sizing/state (<code class=\"web2-code\">VcpuCount</code>, <code class=\"web2-code\">RamGB</code>, <code class=\"web2-code\">ProvisionedDisk</code>, <code class=\"web2-code\">PoweredOn</code>, <code class=\"web2-code\">IsTemplate</code>, <code class=\"web2-code\">SrmPlaceholder</code>).</p><p><strong>Daily tracks:</strong> <code class=\"web2-code\">SamplesPresent</code>, <code class=\"web2-code\">TotalSamples</code>, <code class=\"web2-code\">AvgIsPresent</code>, <code class=\"web2-code\">AvgVcpuCount</code>, <code class=\"web2-code\">AvgRamGB</code>, <code class=\"web2-code\">AvgProvisionedDisk</code>, <code class=\"web2-code\">PoolTinPct</code>, <code class=\"web2-code\">PoolBronzePct</code>, <code class=\"web2-code\">PoolSilverPct</code>, <code class=\"web2-code\">PoolGoldPct</code>, plus chargeback totals columns <code class=\"web2-code\">Tin</code>, <code class=\"web2-code\">Bronze</code>, <code class=\"web2-code\">Silver</code>, <code class=\"web2-code\">Gold</code>.</p><p><strong>Monthly tracks:</strong> the same daily aggregate fields, with monthly values weighted by per-day sample volume so partial-day VMs and config changes stay proportional.</p><p>Snapshots are registered in <code class=\"web2-code\">snapshot_registry</code> so regeneration via <code class=\"web2-code\">/api/snapshots/aggregate</code> can locate the correct tables (fallback scanning is also supported).</p><p>vCenter totals pages are accelerated by compact cache tables: <code class=\"web2-code\">vcenter_latest_totals</code> and <code class=\"web2-code\">vcenter_aggregate_totals</code>.</p><p>VM Trace daily mode uses the <code class=\"web2-code\">vm_daily_rollup</code> cache when available, and falls back to daily summary tables if needed.</p><p>Reports (XLSX with totals/charts) are generated automatically after hourly, daily, and monthly jobs and written to a reports directory.</p><p>Hourly totals are interval-based: each row represents <code class=\"web2-code\">[HH:00, HH+1:00)</code> and uses the first snapshot at or after the hour end (including cross-day snapshots) to prorate VM presence.</p><p>Monthly aggregation reports include a Daily Totals sheet with full-day interval labels (YYYY-MM-DD to YYYY-MM-DD) and prorated totals.</p></div></div><div class=\"web2-card\"><h2 class=\"text-lg font-semibold mb-2\">Prorating and Aggregation</h2><div class=\"mt-3 space-y-2 text-sm text-slate-600 web2-paragraphs\"><p><code class=\"web2-code\">SamplesPresent</code> is the count of snapshots in which the VM appears; <code class=\"web2-code\">TotalSamples</code> is the count of unique snapshot times for that vCenter/day.</p><p><code class=\"web2-code\">AvgIsPresent = SamplesPresent / TotalSamples</code> (0 when <code class=\"web2-code\">TotalSamples</code> is 0).</p><p>Daily <code class=\"web2-code\">AvgVcpuCount</code>, <codLine truncated
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}