diff --git a/src/api/polaris.ts b/src/api/polaris.ts index c27e2c6..efd0895 100644 --- a/src/api/polaris.ts +++ b/src/api/polaris.ts @@ -61,6 +61,7 @@ export interface ResultCounts { pass: number; warning: number; danger: number; + skipped: number; } function countResultSet(rs: ResultSet, counts: ResultCounts): void { @@ -69,6 +70,8 @@ function countResultSet(rs: ResultSet, counts: ResultCounts): void { counts.total++; if (msg.Success) { counts.pass++; + } else if (msg.Severity === 'ignore') { + counts.skipped++; } else if (msg.Severity === 'warning') { counts.warning++; } else if (msg.Severity === 'danger') { @@ -78,7 +81,7 @@ function countResultSet(rs: ResultSet, counts: ResultCounts): void { } function countResultItems(results: Result[]): ResultCounts { - const counts: ResultCounts = { total: 0, pass: 0, warning: 0, danger: 0 }; + const counts: ResultCounts = { total: 0, pass: 0, warning: 0, danger: 0, skipped: 0 }; for (const result of results) { countResultSet(result.Results, counts); if (result.PodResult) { @@ -138,6 +141,11 @@ export function setRefreshInterval(seconds: number): void { localStorage.setItem(STORAGE_KEY, String(seconds)); } +// --- Polaris dashboard proxy URL --- + +export const POLARIS_DASHBOARD_PROXY = + '/api/v1/namespaces/polaris/services/polaris-dashboard:80/proxy/'; + // --- Score computation --- export function computeScore(counts: ResultCounts): number { diff --git a/src/components/PolarisView.tsx b/src/components/DashboardView.tsx similarity index 59% rename from src/components/PolarisView.tsx rename to src/components/DashboardView.tsx index fdabce9..24f56c6 100644 --- a/src/components/PolarisView.tsx +++ b/src/components/DashboardView.tsx @@ -6,7 +6,7 @@ import { StatusLabel, } from '@kinvolk/headlamp-plugin/lib/CommonComponents'; import React from 'react'; -import { AuditData, computeScore, countResults, ResultCounts } from '../api/polaris'; +import { AuditData, countResults, ResultCounts } from '../api/polaris'; import { usePolarisDataContext } from '../api/PolarisDataContext'; function scoreStatus(score: number): 'success' | 'warning' | 'error' { @@ -15,10 +15,41 @@ function scoreStatus(score: number): 'success' | 'warning' | 'error' { return 'error'; } -function OverviewSection(props: { data: AuditData; counts: ResultCounts }) { - const score = computeScore(props.counts); +function OverviewSection(props: { + data: AuditData; + counts: ResultCounts; + includeSkipped: boolean; +}) { + const { counts, includeSkipped } = props; + + const displayTotal = includeSkipped ? counts.total : counts.total - counts.skipped; + const displayPass = counts.pass; + const score = displayTotal === 0 ? 0 : Math.round((displayPass / displayTotal) * 100); const status = scoreStatus(score); + const summaryRows: { name: string; value: React.ReactNode }[] = [ + { name: 'Total Checks', value: String(displayTotal) }, + { + name: 'Pass', + value: {counts.pass}, + }, + { + name: 'Warning', + value: {counts.warning}, + }, + { + name: 'Danger', + value: {counts.danger}, + }, + ]; + + if (includeSkipped) { + summaryRows.push({ + name: 'Skipped', + value: {counts.skipped}, + }); + } + return ( <> @@ -32,23 +63,7 @@ function OverviewSection(props: { data: AuditData; counts: ResultCounts }) { /> - {props.counts.pass}, - }, - { - name: 'Warning', - value: {props.counts.warning}, - }, - { - name: 'Danger', - value: {props.counts.danger}, - }, - ]} - /> + ; @@ -75,7 +91,7 @@ export default function PolarisView() { return ( <> - + {error && ( @@ -90,7 +106,9 @@ export default function PolarisView() { )} - {data && counts && } + {data && counts && ( + + )} {!data && !error && ( diff --git a/src/components/DynamicSidebarRegistrar.tsx b/src/components/DynamicSidebarRegistrar.tsx index 6f198b0..7cf8bdf 100644 --- a/src/components/DynamicSidebarRegistrar.tsx +++ b/src/components/DynamicSidebarRegistrar.tsx @@ -16,10 +16,10 @@ export default function DynamicSidebarRegistrar() { if (registeredNamespaces.has(ns)) continue; registeredNamespaces.add(ns); registerSidebarEntry({ - parent: 'polaris', + parent: 'polaris-namespaces', name: `polaris-ns-${ns}`, label: ns, - url: `/polaris/${ns}`, + url: `/polaris/ns/${ns}`, icon: 'mdi:folder-outline', }); } diff --git a/src/components/NamespaceDetailView.tsx b/src/components/NamespaceDetailView.tsx index 12799e6..612724d 100644 --- a/src/components/NamespaceDetailView.tsx +++ b/src/components/NamespaceDetailView.tsx @@ -12,6 +12,7 @@ import { computeScore, countResultsForItems, filterResultsByNamespace, + POLARIS_DASHBOARD_PROXY, Result, ResultCounts, } from '../api/polaris'; @@ -82,6 +83,21 @@ export default function NamespaceDetailView() { <> + + + View in Polaris Dashboard + + ), + }, + ]} + /> + + ( - + ), }); registerRoute({ - path: '/polaris/:namespace', + path: '/polaris/full-audit', + sidebar: 'polaris-full', + name: 'polaris-full-audit', + exact: true, + component: () => ( + + + + + ), +}); + +registerRoute({ + path: '/polaris/ns/:namespace', sidebar: 'polaris', name: 'polaris-namespace', exact: true,