mirror of
https://github.com/hansjone/netx.git
synced 2026-10-08 23:33:21 +08:00
Track per-connection metadata on the hub and surface it in the UME key-alert UI so operators can see which Netx Ops clients are subscribed. Co-authored-by: Cursor <cursoragent@cursor.com>
1049 lines
23 KiB
TypeScript
1049 lines
23 KiB
TypeScript
export type DshAlarmHubConnection = {
|
|
id: string;
|
|
user: string;
|
|
remote?: string;
|
|
client?: string;
|
|
connected_at?: string;
|
|
last_seen_at?: string;
|
|
};
|
|
|
|
export type DshAlarmHubStatus = {
|
|
enabled: boolean;
|
|
path?: string;
|
|
subscribers: number;
|
|
published?: number;
|
|
deliver_ok?: number;
|
|
deliver_fail?: number;
|
|
connections?: DshAlarmHubConnection[];
|
|
};
|
|
|
|
export type IntegrationStatus = {
|
|
netx_api: { status: "up" | "down" | "unknown"; [k: string]: unknown };
|
|
db: { status: "up" | "down" | "unknown"; latency_ms?: number; error?: string; [k: string]: unknown };
|
|
dsh_alarm_hub?: DshAlarmHubStatus;
|
|
oclaw_bridge?: {
|
|
status: "up" | "down" | "unknown";
|
|
mode?: string;
|
|
enabled?: boolean;
|
|
connected?: boolean;
|
|
queue_size?: number;
|
|
published_ok?: number;
|
|
published_fail?: number;
|
|
latency_ms?: number;
|
|
error_kind?: string;
|
|
error?: string;
|
|
[k: string]: unknown;
|
|
};
|
|
};
|
|
|
|
export type UmeKeyAlertRuleItem = {
|
|
notification_id: string;
|
|
match_type: "notification_id" | "keyword";
|
|
match_value: string;
|
|
enabled: boolean;
|
|
label: string;
|
|
ne_types?: string[];
|
|
created_at: string;
|
|
updated_at: string;
|
|
forward_stats?: {
|
|
attempts: number;
|
|
published_ok: number;
|
|
last_forwarded_at: string;
|
|
};
|
|
};
|
|
|
|
export type UmeInventoryNeTypeItem = {
|
|
ne_type: string;
|
|
ne_count: number;
|
|
};
|
|
|
|
export type UmeKeyAlertForwarderStatus = {
|
|
enabled: boolean;
|
|
operational?: boolean;
|
|
paused?: boolean;
|
|
connected: boolean;
|
|
queue_size: number;
|
|
url: string;
|
|
published_ok?: number;
|
|
published_fail?: number;
|
|
queued_total?: number;
|
|
};
|
|
|
|
export type UmeKeyAlertMonitorResponse = {
|
|
ok: boolean;
|
|
rules: UmeKeyAlertRuleItem[];
|
|
total?: number;
|
|
page?: number;
|
|
page_size?: number;
|
|
config?: {
|
|
forward_on_clear: boolean;
|
|
};
|
|
/** Primary: NetX hub ← netxops clients (multi-subscriber). */
|
|
dsh_alarm_hub?: DshAlarmHubStatus;
|
|
/** Legacy: NetX → OClaw outbound bridge (single link). */
|
|
forwarder: UmeKeyAlertForwarderStatus;
|
|
};
|
|
|
|
export type UmeSyncJobItem = {
|
|
id: number;
|
|
domain: string;
|
|
status: string;
|
|
trigger_mode: string;
|
|
pulled_count: number;
|
|
inserted_count: number;
|
|
updated_count: number;
|
|
deleted?: number;
|
|
error_message?: string;
|
|
started_at: string;
|
|
ended_at?: string | null;
|
|
};
|
|
|
|
export type UmeWsLogEntry = {
|
|
ts: string;
|
|
level: string;
|
|
message: string;
|
|
subscription_id?: string;
|
|
};
|
|
|
|
export type UmeWsConnectionStatus = {
|
|
state: string;
|
|
label: string;
|
|
detail?: string;
|
|
};
|
|
|
|
export type UmeAlarmSubscriptionStatus = {
|
|
ok?: boolean;
|
|
created?: boolean;
|
|
already_exists?: boolean;
|
|
active: boolean;
|
|
subscription_id?: string;
|
|
wss_uri?: string;
|
|
topic?: string;
|
|
server_subscription_lost?: boolean;
|
|
server_subscription_lost_reason?: string;
|
|
current_alarms_mode?: "wss" | "rest";
|
|
wss_active_for_current_alarms?: boolean;
|
|
scheduled_sync_skipped?: boolean;
|
|
needs_local_cleanup?: boolean;
|
|
ume_already_missing?: boolean;
|
|
cleared_local?: boolean;
|
|
message?: string;
|
|
ws_connection?: UmeWsConnectionStatus;
|
|
ws_consumer_status?: string;
|
|
ws_consumer_last_error?: string;
|
|
ws_consumer_last_run_at?: string | null;
|
|
ws_logs?: UmeWsLogEntry[];
|
|
};
|
|
|
|
export type UmeTopologyFabricGap = {
|
|
dock_me_count?: number;
|
|
fabric_ume_count?: number;
|
|
world_exists?: boolean;
|
|
world_folder_id?: string;
|
|
latest_topology_status?: string;
|
|
latest_topology_error?: string;
|
|
partial_apply?: boolean;
|
|
needs_apply?: boolean;
|
|
error?: string;
|
|
};
|
|
|
|
export type UmeSyncStatusResponse = {
|
|
total?: number;
|
|
page?: number;
|
|
page_size?: number;
|
|
items: UmeSyncJobItem[];
|
|
latest_by_domain?: Record<string, UmeSyncJobItem>;
|
|
alarm_subscription?: UmeAlarmSubscriptionStatus;
|
|
topology_fabric?: UmeTopologyFabricGap;
|
|
runtime_tasks?: Array<{
|
|
task: string;
|
|
status: string;
|
|
paused?: boolean;
|
|
last_run_at?: string | null;
|
|
last_error?: string;
|
|
interval_s?: number | null;
|
|
interval_label?: string;
|
|
}>;
|
|
};
|
|
|
|
export type UmeNeItem = {
|
|
ne_id: string;
|
|
ne_name: string;
|
|
user_label: string;
|
|
ip_address: string;
|
|
ipv6_address?: string;
|
|
ne_type: string;
|
|
device_level?: string;
|
|
host_name?: string;
|
|
location?: string;
|
|
hardware_version?: string;
|
|
loopback?: string;
|
|
consistent_state?: string;
|
|
interface_version?: string;
|
|
mac?: string;
|
|
admin_status?: string;
|
|
address_type?: string;
|
|
connection_status?: string;
|
|
maintain_status?: string;
|
|
net_mask?: string;
|
|
create_time?: string;
|
|
creator?: string;
|
|
last_seen_at?: string;
|
|
};
|
|
|
|
export type UmeAlarmItem = {
|
|
alarm_key: string;
|
|
ne_id: string;
|
|
ne_name: string;
|
|
user_label: string;
|
|
host_name?: string;
|
|
ne_type?: string;
|
|
object_name: string;
|
|
event_type: string;
|
|
native_probable_cause: string;
|
|
perceived_severity: string;
|
|
is_cleared: string;
|
|
time_created: string;
|
|
last_seen_at?: string;
|
|
};
|
|
|
|
export type ConnectStatus = "unknown" | "testing" | "pass" | "fail";
|
|
|
|
export type ManagedNeItem = {
|
|
id: string;
|
|
name: string;
|
|
vendor: string;
|
|
device_type: string;
|
|
ip_address: string;
|
|
port: number;
|
|
protocol: string;
|
|
username: string;
|
|
/** True when a password is stored server-side (secret never returned). */
|
|
has_password?: boolean;
|
|
connect_status: ConnectStatus;
|
|
connect_message: string;
|
|
connect_detail: string;
|
|
connect_tested_at: string | null;
|
|
tags: string;
|
|
remark: string;
|
|
source?: string;
|
|
source_ref?: string;
|
|
hop_enabled: boolean;
|
|
hop_vendor: string;
|
|
hop_host: string;
|
|
hop_port: number;
|
|
hop_protocol: string;
|
|
hop_username: string;
|
|
hop_command_template: string;
|
|
hop_vrf: string;
|
|
hop_target_auth_mode: string;
|
|
hop_enter_system_view?: boolean;
|
|
created_at: string;
|
|
updated_at: string;
|
|
};
|
|
|
|
export type ManagedNeListResponse = {
|
|
total: number;
|
|
page: number;
|
|
page_size: number;
|
|
items: ManagedNeItem[];
|
|
};
|
|
|
|
export type ManagedNeMeta = {
|
|
device_types: string[];
|
|
vendors: string[];
|
|
};
|
|
|
|
export type ManagedNeImportResult = {
|
|
inserted: number;
|
|
updated: number;
|
|
failed: Array<{ row: number; reason: string }>;
|
|
};
|
|
|
|
export type CliConnectProfileItem = {
|
|
id: string;
|
|
name: string;
|
|
is_default: boolean;
|
|
username: string;
|
|
port: number;
|
|
protocol: string;
|
|
device_type_default: string;
|
|
vendor_default: string;
|
|
ne_type_rules: string;
|
|
hop_enabled: boolean;
|
|
hop_vendor: string;
|
|
hop_host: string;
|
|
hop_port: number;
|
|
hop_protocol: string;
|
|
hop_username: string;
|
|
hop_command_template: string;
|
|
hop_vrf: string;
|
|
hop_target_auth_mode: string;
|
|
hop_enter_system_view?: boolean;
|
|
created_at: string;
|
|
updated_at: string;
|
|
};
|
|
|
|
export type CliMeta = {
|
|
credentials_configured: boolean;
|
|
default_profile_configured: boolean;
|
|
cli_profile_ready: boolean;
|
|
};
|
|
|
|
export type CliTargetItem = {
|
|
source: string;
|
|
id: string;
|
|
ume_ne_id?: string | null;
|
|
name: string;
|
|
ip_address: string;
|
|
ne_type?: string;
|
|
vendor?: string;
|
|
device_type?: string;
|
|
protocol?: string;
|
|
port?: number;
|
|
username?: string;
|
|
has_password?: boolean;
|
|
hop_enabled?: boolean;
|
|
connect_status: string;
|
|
cli_profile_ready?: boolean;
|
|
/** ManagedNE.source (lldp / webcrt / ume_sync / …). */
|
|
ne_source?: string;
|
|
};
|
|
|
|
export type CliTargetListResponse = {
|
|
total: number;
|
|
page: number;
|
|
page_size: number;
|
|
items: CliTargetItem[];
|
|
};
|
|
|
|
export type UmeCliOverrideItem = {
|
|
ume_ne_id: string;
|
|
profile_id: string | null;
|
|
username_override: string;
|
|
device_type_override: string;
|
|
vendor_override: string;
|
|
connect_status: string;
|
|
connect_message: string;
|
|
connect_detail: string;
|
|
connect_tested_at: string | null;
|
|
updated_at: string;
|
|
};
|
|
|
|
export type EligibleNeItem = {
|
|
id: string;
|
|
source?: "managed" | "ume" | string;
|
|
name: string;
|
|
vendor: string;
|
|
device_type: string;
|
|
ip_address: string;
|
|
connect_status: string;
|
|
connect_tested_at: string | null;
|
|
};
|
|
|
|
export type CollectionJobItem = {
|
|
id: string;
|
|
title: string;
|
|
commands: string;
|
|
trigger_mode?: string;
|
|
status: string;
|
|
ne_count: number;
|
|
success_count: number;
|
|
fail_count: number;
|
|
output_count: number;
|
|
error_message: string;
|
|
created_at: string;
|
|
started_at: string | null;
|
|
ended_at: string | null;
|
|
last_run_at: string | null;
|
|
};
|
|
|
|
export type CollectionJobSummary = {
|
|
id: string;
|
|
title: string;
|
|
status: string;
|
|
trigger_mode?: string;
|
|
ne_count: number;
|
|
success_count: number;
|
|
fail_count: number;
|
|
created_at?: string | null;
|
|
started_at?: string | null;
|
|
ended_at?: string | null;
|
|
last_run_at?: string | null;
|
|
};
|
|
|
|
export type CollectionTargetRef = {
|
|
source: "managed" | "ume" | string;
|
|
id: string;
|
|
};
|
|
|
|
export type CollectionPolicy = {
|
|
enabled: boolean;
|
|
interval_days: number;
|
|
interval_hours: number;
|
|
scope_mode: "all" | "selected" | string;
|
|
selected_targets: CollectionTargetRef[];
|
|
title: string;
|
|
commands: string;
|
|
history_keep: number;
|
|
updated_at?: string | null;
|
|
};
|
|
|
|
export type CollectionDashboard = {
|
|
job_count: number;
|
|
active_count: number;
|
|
running_job: CollectionJobSummary | null;
|
|
last_job: CollectionJobSummary | null;
|
|
next_due_at?: string | null;
|
|
policy?: CollectionPolicy | null;
|
|
};
|
|
|
|
export type CollectionRunItem = {
|
|
id: string;
|
|
job_id: string;
|
|
ne_id: string;
|
|
ne_source?: string;
|
|
ne_name: string;
|
|
ne_ip: string;
|
|
status: string;
|
|
message: string;
|
|
output_rel_path: string;
|
|
has_output: boolean;
|
|
started_at: string | null;
|
|
ended_at: string | null;
|
|
};
|
|
|
|
export type CollectionJobDetail = {
|
|
job: CollectionJobItem;
|
|
};
|
|
|
|
export type CollectionRunList = {
|
|
total: number;
|
|
page: number;
|
|
page_size: number;
|
|
items: CollectionRunItem[];
|
|
};
|
|
|
|
export type UmeTokenStatus = {
|
|
ok?: boolean;
|
|
has_token: boolean;
|
|
expires_in_s: number;
|
|
expires_at_epoch_s: number;
|
|
auth_header: string;
|
|
token_preview?: string;
|
|
changed?: boolean;
|
|
error_kind?: string;
|
|
error?: string;
|
|
};
|
|
|
|
export type TopologyViewRole = "core" | "aggregation" | "access";
|
|
export type TopologyViewKind = "physical" | "custom";
|
|
|
|
export type TopologyViewItem = {
|
|
id: string;
|
|
name: string;
|
|
remark: string;
|
|
folder_id?: string;
|
|
kind?: TopologyViewKind | string;
|
|
role?: TopologyViewRole | string;
|
|
sort_order?: number;
|
|
filter?: Record<string, unknown>;
|
|
viewport?: Record<string, unknown>;
|
|
node_count: number;
|
|
edge_count?: number;
|
|
created_at?: string | null;
|
|
updated_at?: string | null;
|
|
};
|
|
|
|
export type TopologyTreeViewItem = {
|
|
id: string;
|
|
name: string;
|
|
kind: TopologyViewKind | string;
|
|
role?: TopologyViewRole | string;
|
|
sort_order: number;
|
|
node_count: number;
|
|
updated_at?: string | null;
|
|
};
|
|
|
|
export type TopologyTreeFolderItem = {
|
|
id: string;
|
|
parent_id: string;
|
|
kind: "root" | "region" | string;
|
|
name: string;
|
|
sort_order: number;
|
|
is_system: boolean;
|
|
external_ref?: string;
|
|
/** Distinct fabric NE count in this folder subtree (API). Region icons excluded. */
|
|
ne_count?: number;
|
|
views: TopologyTreeViewItem[];
|
|
children: TopologyTreeFolderItem[];
|
|
};
|
|
|
|
export type TopologyTree = {
|
|
root: TopologyTreeFolderItem | null;
|
|
};
|
|
|
|
export type ClassifyRuleScope = "role" | "region";
|
|
|
|
export type ClassifyRule = {
|
|
id: string;
|
|
scope: ClassifyRuleScope | string;
|
|
name: string;
|
|
pattern: string;
|
|
match_field: string;
|
|
priority: number;
|
|
enabled: boolean;
|
|
payload: Record<string, unknown>;
|
|
remark?: string;
|
|
created_at?: string | null;
|
|
updated_at?: string | null;
|
|
};
|
|
|
|
export type ClassifyPreview = {
|
|
total_nodes: number;
|
|
role_matched: number;
|
|
role_unmatched: number;
|
|
role_conflicts: number;
|
|
region_matched: number;
|
|
region_unmatched: number;
|
|
region_conflicts: number;
|
|
role_samples: Array<Record<string, unknown>>;
|
|
region_samples: Array<Record<string, unknown>>;
|
|
unmatched_samples: Array<Record<string, unknown>>;
|
|
};
|
|
|
|
export type ClassifyApplyResult = {
|
|
role_updated: number;
|
|
region_updated: number;
|
|
skipped_manual: number;
|
|
total_nodes: number;
|
|
};
|
|
|
|
export type FabricNodeSearchHit = {
|
|
id: string;
|
|
name: string;
|
|
ip: string;
|
|
vendor: string;
|
|
managed_ne_id?: string;
|
|
ume_ne_id?: string;
|
|
/** Layout rank major.minor; null/undefined = unclassified */
|
|
level?: number | null;
|
|
role?: string;
|
|
region_folder_id?: string | null;
|
|
world_x?: number | null;
|
|
world_y?: number | null;
|
|
link_status?: "managed" | "ume" | "both" | "orphaned" | string;
|
|
managed_alive?: boolean;
|
|
ume_alive?: boolean;
|
|
managed_source?: string;
|
|
deletable?: boolean;
|
|
views?: Array<{
|
|
view_id: string;
|
|
view_name: string;
|
|
folder_id: string;
|
|
folder_name: string;
|
|
kind: string;
|
|
}>;
|
|
};
|
|
|
|
export type TopologyViewNodeItem = {
|
|
fabric_node_id: string;
|
|
managed_ne_id: string;
|
|
ume_ne_id: string;
|
|
label: string;
|
|
x: number;
|
|
y: number;
|
|
locked: boolean;
|
|
name: string;
|
|
ip: string;
|
|
vendor: string;
|
|
device_type: string;
|
|
connect_status: string;
|
|
managed_source?: string;
|
|
/** Fabric classify rank; smaller = closer to external/WAN. */
|
|
level?: number | null;
|
|
/** Synced alias from floor(level): external|core|aggregation|access|edge|"" */
|
|
role?: string;
|
|
/** ne | region — region drills into a child canvas */
|
|
kind?: string;
|
|
folder_id?: string;
|
|
view_id?: string;
|
|
node_count?: number;
|
|
};
|
|
|
|
export type TopologyViewEdgeItem = {
|
|
id: string;
|
|
a_node_id: string;
|
|
b_node_id: string;
|
|
a_port: string;
|
|
b_port: string;
|
|
source: string;
|
|
status: string;
|
|
layer: string;
|
|
stroke_color?: string;
|
|
stroke_width?: number;
|
|
line_style?: string;
|
|
discovered_at?: string | null;
|
|
/** UME userLabel when no EQ+PTP ports. */
|
|
display_label?: string;
|
|
};
|
|
|
|
export type TopologyOutsidePeer = {
|
|
fabric_node_id: string;
|
|
name: string;
|
|
ip: string;
|
|
via_node_id: string;
|
|
};
|
|
|
|
export type TopologyWorldTransform = {
|
|
origin_x: number;
|
|
origin_y: number;
|
|
scale: number;
|
|
full_min_x: number;
|
|
full_max_x: number;
|
|
full_min_y: number;
|
|
full_max_y: number;
|
|
total: number;
|
|
lod: string;
|
|
dock_me_count?: number;
|
|
};
|
|
|
|
export type TopologyWorldScatterPoint = {
|
|
x: number;
|
|
y: number;
|
|
};
|
|
|
|
export type TopologyViewGraph = {
|
|
view: TopologyViewItem;
|
|
nodes: TopologyViewNodeItem[];
|
|
edges: TopologyViewEdgeItem[];
|
|
truncated?: boolean;
|
|
truncate_reason?: string;
|
|
outside_peers?: TopologyOutsidePeer[];
|
|
world_transform?: TopologyWorldTransform | null;
|
|
scatter?: TopologyWorldScatterPoint[];
|
|
};
|
|
|
|
export type FabricSummary = {
|
|
node_count: number;
|
|
edge_count: number;
|
|
edge_active: number;
|
|
edge_stale: number;
|
|
edge_missing?: number;
|
|
last_discover_at?: string | null;
|
|
updated_at?: string | null;
|
|
};
|
|
|
|
export type FabricEdge = {
|
|
id: string;
|
|
layer: string;
|
|
a_node_id: string;
|
|
b_node_id: string;
|
|
a_port: string;
|
|
b_port: string;
|
|
a_name?: string;
|
|
b_name?: string;
|
|
a_ip?: string;
|
|
b_ip?: string;
|
|
source: string;
|
|
status: string;
|
|
attrs?: Record<string, unknown>;
|
|
discovered_at?: string | null;
|
|
last_seen_at?: string | null;
|
|
updated_at?: string | null;
|
|
};
|
|
|
|
export type TopologyDiscoverUnmatched = {
|
|
remote_name: string;
|
|
remote_ip: string;
|
|
local_port: string;
|
|
remote_port: string;
|
|
};
|
|
|
|
export type TopologyDiscoverJobItem = {
|
|
id: string;
|
|
job_id: string;
|
|
ne_id: string;
|
|
ume_ne_id: string;
|
|
fabric_node_id: string;
|
|
ne_name: string;
|
|
ne_ip: string;
|
|
ok: boolean;
|
|
command: string;
|
|
neighbors: number;
|
|
edges_added: number;
|
|
edges_updated: number;
|
|
unmatched_count: number;
|
|
unmatched?: TopologyDiscoverUnmatched[];
|
|
parser_key?: string;
|
|
parser_stub?: boolean;
|
|
error: string;
|
|
raw_preview: string;
|
|
};
|
|
|
|
export type TopologyDiscoverJob = {
|
|
id: string;
|
|
scope: string;
|
|
trigger_mode?: string;
|
|
status: string;
|
|
total: number;
|
|
done: number;
|
|
edges_added: number;
|
|
edges_updated: number;
|
|
edges_stale: number;
|
|
edges_missing?: number;
|
|
error: string;
|
|
started_at?: string | null;
|
|
ended_at?: string | null;
|
|
created_at?: string | null;
|
|
items: TopologyDiscoverJobItem[];
|
|
items_total?: number;
|
|
items_page?: number;
|
|
items_page_size?: number;
|
|
};
|
|
|
|
/** @deprecated alias — prefer TopologyViewItem */
|
|
export type TopologyMapItem = TopologyViewItem;
|
|
|
|
/** UI-compat aliases for restored TopologyPage. */
|
|
export type TopologyNodeItem = TopologyViewNodeItem & { id?: string; map_id?: string; ne_name?: string; ne_ip?: string; protocol?: string };
|
|
export type TopologyEdgeItem = TopologyViewEdgeItem & {
|
|
source_node_id?: string;
|
|
target_node_id?: string;
|
|
map_id?: string;
|
|
};
|
|
export type TopologyDiscoverNeResult = TopologyDiscoverJobItem & {
|
|
links?: Array<Record<string, unknown>>;
|
|
};
|
|
export type TopologyDiscoverOut = {
|
|
map_id?: string;
|
|
protocol?: string;
|
|
job_id?: string;
|
|
scanned: number;
|
|
edges_added: number;
|
|
edges_updated: number;
|
|
edges_stale?: number;
|
|
results: TopologyDiscoverNeResult[];
|
|
graph: TopologyViewGraph | null;
|
|
};
|
|
|
|
export type ConfigSyncTargetRef = {
|
|
source: "managed" | "ume";
|
|
id: string;
|
|
};
|
|
|
|
export type LldpCollectPolicy = {
|
|
enabled: boolean;
|
|
interval_days: number;
|
|
interval_hours: number;
|
|
concurrency: number;
|
|
scope_mode: string;
|
|
selected_targets: ConfigSyncTargetRef[];
|
|
auto_add_unmatched: boolean;
|
|
history_keep: number;
|
|
updated_at?: string | null;
|
|
};
|
|
|
|
export type LldpCollectJobSummary = {
|
|
id: string;
|
|
scope: string;
|
|
trigger_mode: string;
|
|
status: string;
|
|
total: number;
|
|
done: number;
|
|
success_count?: number;
|
|
fail_count?: number;
|
|
edges_added: number;
|
|
edges_updated: number;
|
|
edges_stale: number;
|
|
edges_missing?: number;
|
|
error: string;
|
|
started_at?: string | null;
|
|
ended_at?: string | null;
|
|
created_at?: string | null;
|
|
};
|
|
|
|
export type LldpCollectDashboard = {
|
|
policy: LldpCollectPolicy;
|
|
fabric_node_count: number;
|
|
fabric_edge_count: number;
|
|
fabric_edge_active: number;
|
|
fabric_edge_stale: number;
|
|
fabric_edge_missing?: number;
|
|
last_discover_at?: string | null;
|
|
running_job: LldpCollectJobSummary | null;
|
|
last_job: LldpCollectJobSummary | null;
|
|
next_due_at?: string | null;
|
|
};
|
|
|
|
export type ConfigSyncPolicy = {
|
|
enabled: boolean;
|
|
interval_days: number;
|
|
concurrency: number;
|
|
scope_mode: string;
|
|
selected_targets: ConfigSyncTargetRef[];
|
|
history_keep: number;
|
|
cycle_keep: number;
|
|
updated_at?: string | null;
|
|
};
|
|
|
|
export type ConfigSyncCycle = {
|
|
id: string;
|
|
trigger_mode: string;
|
|
status: string;
|
|
concurrency: number;
|
|
planned_count: number;
|
|
success_count: number;
|
|
fail_count: number;
|
|
skip_count: number;
|
|
error_message: string;
|
|
started_at?: string | null;
|
|
ended_at?: string | null;
|
|
created_at?: string | null;
|
|
};
|
|
|
|
export type ConfigSyncTask = {
|
|
id: string;
|
|
cycle_id: string;
|
|
source: string;
|
|
target_id: string;
|
|
ne_name: string;
|
|
ne_ip: string;
|
|
vendor: string;
|
|
status: string;
|
|
message: string;
|
|
started_at?: string | null;
|
|
ended_at?: string | null;
|
|
};
|
|
|
|
export type ConfigSyncDashboard = {
|
|
policy: ConfigSyncPolicy;
|
|
snapshot_count: number;
|
|
last_cycle: ConfigSyncCycle | null;
|
|
running_cycle: ConfigSyncCycle | null;
|
|
next_due_at?: string | null;
|
|
fail_by_vendor: Record<string, number>;
|
|
};
|
|
|
|
export type NeConfigSnapshotMeta = {
|
|
source: string;
|
|
target_id: string;
|
|
vendor: string;
|
|
device_type: string;
|
|
ne_name: string;
|
|
ne_ip: string;
|
|
config_sha256: string;
|
|
config_alt_sha256: string;
|
|
plain_size: number;
|
|
plain_alt_size: number;
|
|
zlib_size: number;
|
|
zlib_alt_size: number;
|
|
has_alt: boolean;
|
|
commands: string[];
|
|
collected_at?: string | null;
|
|
last_cycle_id: string;
|
|
};
|
|
|
|
export type NeConfigSnapshotDetail = NeConfigSnapshotMeta & {
|
|
config_text: string;
|
|
config_alt_text: string;
|
|
};
|
|
|
|
export type PortTrafficDevice = {
|
|
id: string;
|
|
source: string;
|
|
ne_id: string;
|
|
ne_name: string;
|
|
ne_ip: string;
|
|
vendor: string;
|
|
note: string;
|
|
status: string;
|
|
interval_sec: number;
|
|
retention_days: number;
|
|
concurrency: number;
|
|
collect_running: boolean;
|
|
target_count: number;
|
|
active_target_count: number;
|
|
last_collect_started_at?: string | null;
|
|
last_collect_ended_at?: string | null;
|
|
last_error: string;
|
|
created_at?: string | null;
|
|
updated_at?: string | null;
|
|
};
|
|
|
|
/** @deprecated use PortTrafficDevice */
|
|
export type PortTrafficTask = PortTrafficDevice;
|
|
|
|
export type PortTrafficTarget = {
|
|
id: string;
|
|
device_id: string;
|
|
task_id?: string;
|
|
series_id?: string;
|
|
source: string;
|
|
target_id: string;
|
|
ne_name: string;
|
|
ne_ip: string;
|
|
vendor: string;
|
|
ifname: string;
|
|
if_description: string;
|
|
bw_bps: number;
|
|
status: string;
|
|
last_error: string;
|
|
last_sample_at?: string | null;
|
|
created_at?: string | null;
|
|
};
|
|
|
|
export type PortTrafficEvent = {
|
|
id: string;
|
|
device_id: string;
|
|
target_row_id: string;
|
|
ifname: string;
|
|
level: string;
|
|
message: string;
|
|
created_at?: string | null;
|
|
};
|
|
|
|
export type PortTrafficBoardPanel = {
|
|
id: string;
|
|
board_id: string;
|
|
title: string;
|
|
target_id: string;
|
|
range_hours: number;
|
|
baseline: "off" | "day" | "week" | "shift" | "custom" | string;
|
|
offset_hours: number;
|
|
ahead_hours: number;
|
|
baseline_target_id: string;
|
|
y_mode: "auto" | "current" | "util" | string;
|
|
ord: number;
|
|
col_span: number;
|
|
row_span: number;
|
|
stale: boolean;
|
|
target: PortTrafficTarget | null;
|
|
baseline_target: PortTrafficTarget | null;
|
|
created_at?: string | null;
|
|
updated_at?: string | null;
|
|
};
|
|
|
|
export type PortTrafficBoardPanelIn = {
|
|
id?: string;
|
|
title?: string;
|
|
target_id: string;
|
|
range_hours?: number;
|
|
baseline?: string;
|
|
offset_hours?: number;
|
|
ahead_hours?: number;
|
|
baseline_target_id?: string;
|
|
y_mode?: string;
|
|
ord?: number;
|
|
col_span?: number;
|
|
row_span?: number;
|
|
};
|
|
|
|
export type PortTrafficBoardSummary = {
|
|
id: string;
|
|
name: string;
|
|
remark: string;
|
|
cols: number;
|
|
panel_count: number;
|
|
created_by: string;
|
|
updated_by: string;
|
|
created_at?: string | null;
|
|
updated_at?: string | null;
|
|
};
|
|
|
|
export type PortTrafficBoard = PortTrafficBoardSummary & {
|
|
panels: PortTrafficBoardPanel[];
|
|
};
|
|
|
|
export type PortTrafficSeries = {
|
|
id: string;
|
|
device_id: string;
|
|
task_id?: string;
|
|
title: string;
|
|
status: string;
|
|
active_target: PortTrafficTarget | null;
|
|
retired_target_count: number;
|
|
created_at?: string | null;
|
|
};
|
|
|
|
export type PortTrafficIfaceIn = {
|
|
ifname: string;
|
|
if_description?: string;
|
|
bw_bps?: number;
|
|
};
|
|
|
|
export type PortTrafficTargetIn = PortTrafficIfaceIn & {
|
|
source?: "managed" | "ume";
|
|
target_id?: string;
|
|
ne_name?: string;
|
|
ne_ip?: string;
|
|
vendor?: string;
|
|
};
|
|
|
|
export type PortTrafficDiscoverPort = {
|
|
ifname: string;
|
|
attribute: string;
|
|
mode: string;
|
|
bw_raw: string;
|
|
bw_bps: number;
|
|
admin: string;
|
|
phy: string;
|
|
prot: string;
|
|
description: string;
|
|
};
|
|
|
|
export type PortTrafficDiscoverResponse = {
|
|
source: string;
|
|
id: string;
|
|
ne_name: string;
|
|
ne_ip: string;
|
|
vendor: string;
|
|
vendor_key: string;
|
|
ports: PortTrafficDiscoverPort[];
|
|
ok?: boolean;
|
|
command?: string;
|
|
raw_preview?: string;
|
|
error?: string;
|
|
};
|
|
|
|
export type PortTrafficSamplePoint = {
|
|
ts: string;
|
|
in_bps: number;
|
|
out_bps: number;
|
|
in_util_pct: number;
|
|
out_util_pct: number;
|
|
bw_bps: number;
|
|
rate_period_sec: number;
|
|
ts_raw?: string | null;
|
|
};
|
|
|
|
export type PortTrafficSamples = {
|
|
target: PortTrafficTarget;
|
|
points: PortTrafficSamplePoint[];
|
|
};
|
|
|
|
export type PortTrafficCompare = {
|
|
meta: {
|
|
target_id: string;
|
|
baseline: string;
|
|
offset_hours: number;
|
|
range_hours: number;
|
|
ahead_hours?: number;
|
|
current_target: PortTrafficTarget | null;
|
|
baseline_target: PortTrafficTarget | null;
|
|
baseline_target_id: string;
|
|
};
|
|
current: PortTrafficSamplePoint[];
|
|
baseline: PortTrafficSamplePoint[];
|
|
};
|
|
|
|
export type PortTrafficDashboard = {
|
|
device_count: number;
|
|
running_device_count: number;
|
|
active_target_count: number;
|
|
sample_count_24h: number;
|
|
last_sample_at?: string | null;
|
|
task_count?: number;
|
|
running_task_count?: number;
|
|
};
|
|
|