feat: add service catalog management with policy integration for domain-based resource access control

Add ServiceCatalogItem type and services CRUD API endpoints (list, create, update, delete). Extend Policy type to include services array with domain, upstream_ip, proxy_ip, and ports metadata.

Add ServicesPage component with table view and create/edit modals for managing service definitions. Include service name, domain, proxy, and upstream columns with port parsing logic.

Integrate service selection
This commit is contained in:
2026-03-18 13:09:54 +01:00
parent 0ac93dfeb6
commit 6cf49ff3e0
25 changed files with 1375 additions and 99 deletions

View File

@@ -55,6 +55,15 @@ export type Policy = {
full_tunnel: boolean;
is_active: boolean;
destinations?: string[];
services?: Array<{
id: string;
name: string;
domain: string;
upstream_ip: string;
proxy_ip: string;
ports: number[];
description: string;
}>;
targets?: Array<{
type: string;
id: string;
@@ -62,6 +71,17 @@ export type Policy = {
}>;
};
export type ServiceCatalogItem = {
id: string;
name: string;
description: string;
domain: string;
upstream_ip: string;
proxy_ip: string;
ports: number[];
is_active: boolean;
};
export type Group = {
id: string;
name: string;
@@ -168,6 +188,37 @@ export const api = {
method: "DELETE"
}),
devices: () => request<Device[]>("/admin/devices"),
services: () => request<ServiceCatalogItem[]>("/admin/services"),
createService: (payload: {
name: string;
description: string;
domain: string;
upstream_ip: string;
proxy_ip: string;
ports: number[];
is_active?: boolean;
}) =>
request<ServiceCatalogItem>("/admin/services", {
method: "POST",
body: JSON.stringify(payload)
}),
updateService: (serviceId: string, payload: {
name?: string;
description?: string;
domain?: string;
upstream_ip?: string;
proxy_ip?: string;
ports?: number[];
is_active?: boolean;
}) =>
request<ServiceCatalogItem>(`/admin/services/${serviceId}`, {
method: "PATCH",
body: JSON.stringify(payload)
}),
deleteService: (serviceId: string) =>
request<{ ok: boolean }>(`/admin/services/${serviceId}`, {
method: "DELETE"
}),
deviceProfile: (deviceId: string) => request<DeviceProfile>(`/admin/devices/${deviceId}/profile`),
revokeDevice: (deviceId: string) =>
request<{ ok: boolean }>(`/admin/devices/${deviceId}/revoke`, {
@@ -187,6 +238,7 @@ export const api = {
effect: string;
full_tunnel: boolean;
destinations: string[];
service_ids: string[];
targets: Array<{ type: string; id: string }>;
}) =>
request<Policy>("/admin/policies", {
@@ -201,6 +253,7 @@ export const api = {
full_tunnel?: boolean;
is_active?: boolean;
destinations?: string[];
service_ids?: string[];
targets?: Array<{ type: string; id: string }>;
}) =>
request<Policy>(`/admin/policies/${policyId}`, {