feat: add human-readable endpoint labels to policy table with workload/network/security group prefix detection
Add endpointLabel helper to format policy endpoints with type-specific prefixes (VM/LXC, Network, Security Group) by parsing workload:/network:/sg: prefixes and resolving workload IDs to names, implement policyEndpoint wrapper to apply endpoint labeling to policy definition fields, fetch workloads query in Policies component for endpoint resolution, update DataTable source/destination columns
This commit is contained in:
@@ -2,7 +2,7 @@ import { FormEvent, useState } from "react";
|
|||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { AlertTriangle, CheckCircle2, Clock3, Eye, GitBranch, Pencil, Play, Plus, Shield, Trash2 } from "lucide-react";
|
import { AlertTriangle, CheckCircle2, Clock3, Eye, GitBranch, Pencil, Play, Plus, Shield, Trash2 } from "lucide-react";
|
||||||
|
|
||||||
import { api, Policy, Project, ServiceCatalogItem } from "../api/client";
|
import { api, Policy, Project, ServiceCatalogItem, Workload } from "../api/client";
|
||||||
import { DataTable } from "../components/DataTable";
|
import { DataTable } from "../components/DataTable";
|
||||||
import { buttonClass, Field, iconButtonClass, inputClass, selectClass } from "../components/FormControls";
|
import { buttonClass, Field, iconButtonClass, inputClass, selectClass } from "../components/FormControls";
|
||||||
import { LoadingOverlay } from "../components/LoadingOverlay";
|
import { LoadingOverlay } from "../components/LoadingOverlay";
|
||||||
@@ -13,6 +13,25 @@ function policyValue(policy: Policy, key: string) {
|
|||||||
return String(policy.definition?.[key] ?? "");
|
return String(policy.definition?.[key] ?? "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function endpointLabel(value: string, workloads: Workload[]) {
|
||||||
|
if (value.startsWith("workload:")) {
|
||||||
|
const workloadId = value.replace("workload:", "");
|
||||||
|
const workload = workloads.find((item) => item.id === workloadId);
|
||||||
|
return workload ? `VM/LXC: ${workload.name}` : "VM/LXC: unknown";
|
||||||
|
}
|
||||||
|
if (value.startsWith("network:")) {
|
||||||
|
return `Network: ${value.replace("network:", "")}`;
|
||||||
|
}
|
||||||
|
if (value.startsWith("sg:")) {
|
||||||
|
return `Security Group: ${value.replace("sg:", "")}`;
|
||||||
|
}
|
||||||
|
return value || "any";
|
||||||
|
}
|
||||||
|
|
||||||
|
function policyEndpoint(policy: Policy, key: string, workloads: Workload[]) {
|
||||||
|
return endpointLabel(policyValue(policy, key), workloads);
|
||||||
|
}
|
||||||
|
|
||||||
function policyService(policy: Policy) {
|
function policyService(policy: Policy) {
|
||||||
const service = policy.definition?.service;
|
const service = policy.definition?.service;
|
||||||
if (!service || typeof service !== "object") {
|
if (!service || typeof service !== "object") {
|
||||||
@@ -95,6 +114,7 @@ export function Policies() {
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const policies = useQuery({ queryKey: ["policies"], queryFn: () => api<Policy[]>("/policies") });
|
const policies = useQuery({ queryKey: ["policies"], queryFn: () => api<Policy[]>("/policies") });
|
||||||
const projects = useQuery({ queryKey: ["projects"], queryFn: () => api<Project[]>("/projects") });
|
const projects = useQuery({ queryKey: ["projects"], queryFn: () => api<Project[]>("/projects") });
|
||||||
|
const workloads = useQuery({ queryKey: ["workloads"], queryFn: () => api<Workload[]>("/vms") });
|
||||||
const services = useQuery({ queryKey: ["service-catalog"], queryFn: () => api<ServiceCatalogItem[]>("/service-catalog") });
|
const services = useQuery({ queryKey: ["service-catalog"], queryFn: () => api<ServiceCatalogItem[]>("/service-catalog") });
|
||||||
const [preview, setPreview] = useState("");
|
const [preview, setPreview] = useState("");
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
@@ -250,8 +270,8 @@ export function Policies() {
|
|||||||
rows={(policies.data ?? []) as unknown as Record<string, unknown>[]}
|
rows={(policies.data ?? []) as unknown as Record<string, unknown>[]}
|
||||||
columns={[
|
columns={[
|
||||||
{ key: "name", label: "Policy" },
|
{ key: "name", label: "Policy" },
|
||||||
{ key: "source", label: "Source", render: (row) => policyValue(row as unknown as Policy, "source") },
|
{ key: "source", label: "Source", render: (row) => policyEndpoint(row as unknown as Policy, "source", workloads.data ?? []) },
|
||||||
{ key: "destination", label: "Destination", render: (row) => policyValue(row as unknown as Policy, "destination") },
|
{ key: "destination", label: "Destination", render: (row) => policyEndpoint(row as unknown as Policy, "destination", workloads.data ?? []) },
|
||||||
{ key: "service", label: "Service", render: (row) => policyService(row as unknown as Policy) },
|
{ key: "service", label: "Service", render: (row) => policyService(row as unknown as Policy) },
|
||||||
{ key: "enforcement_mode", label: "Mode" },
|
{ key: "enforcement_mode", label: "Mode" },
|
||||||
{ key: "deployment_status", label: "Status", render: (row) => <PolicyDeploymentStatus policy={row as unknown as Policy} /> },
|
{ key: "deployment_status", label: "Status", render: (row) => <PolicyDeploymentStatus policy={row as unknown as Policy} /> },
|
||||||
|
|||||||
Reference in New Issue
Block a user