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 { 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 { buttonClass, Field, iconButtonClass, inputClass, selectClass } from "../components/FormControls";
|
||||
import { LoadingOverlay } from "../components/LoadingOverlay";
|
||||
@@ -13,6 +13,25 @@ function policyValue(policy: Policy, key: string) {
|
||||
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) {
|
||||
const service = policy.definition?.service;
|
||||
if (!service || typeof service !== "object") {
|
||||
@@ -95,6 +114,7 @@ export function Policies() {
|
||||
const queryClient = useQueryClient();
|
||||
const policies = useQuery({ queryKey: ["policies"], queryFn: () => api<Policy[]>("/policies") });
|
||||
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 [preview, setPreview] = useState("");
|
||||
const [open, setOpen] = useState(false);
|
||||
@@ -250,8 +270,8 @@ export function Policies() {
|
||||
rows={(policies.data ?? []) as unknown as Record<string, unknown>[]}
|
||||
columns={[
|
||||
{ key: "name", label: "Policy" },
|
||||
{ key: "source", label: "Source", render: (row) => policyValue(row as unknown as Policy, "source") },
|
||||
{ key: "destination", label: "Destination", render: (row) => policyValue(row as unknown as Policy, "destination") },
|
||||
{ key: "source", label: "Source", render: (row) => policyEndpoint(row as unknown as Policy, "source", workloads.data ?? []) },
|
||||
{ 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: "enforcement_mode", label: "Mode" },
|
||||
{ key: "deployment_status", label: "Status", render: (row) => <PolicyDeploymentStatus policy={row as unknown as Policy} /> },
|
||||
|
||||
Reference in New Issue
Block a user