import { z } from 'zod';
/**
* @fileoverview VyOS API schema definitions using Zod for comprehensive type safety and validation.
* This module contains all the schema definitions for VyOS network operating system API operations,
* including configuration management, operational commands, and monitoring tools.
*
* @author VyOS MCP Server
* @version 1.0.0
* @since 2025-01-13
*/
/**
* Authentication schema for connecting to VyOS systems via HTTPS API.
*
* @example
* ```ts
* const auth: VyOSAuth = {
* host: "https://vyos-router.example.com",
* apiKey: "your-api-key-here",
* timeout: 30000,
* verifySSL: false
* };
* ```
*/
export const VyOSAuthSchema = z.object({
/** VyOS system hostname or IP address with protocol (https://) */
host: z.string().url().describe('VyOS system hostname or IP address'),
/** VyOS API authentication key configured on the system */
apiKey: z.string().min(1).describe('VyOS API authentication key'),
/** Request timeout in milliseconds (default: 30000) */
timeout: z
.number()
.optional()
.default(30000)
.describe('Request timeout in milliseconds'),
/** Whether to verify SSL certificates (default: false for self-signed certs) */
verifySSL: z
.boolean()
.optional()
.default(false)
.describe('Verify SSL certificates'),
});
/**
* Configuration path represented as an array of strings for hierarchical VyOS config navigation.
*
* @example
* ```ts
* // ^?
* const interfacePath: ConfigPath = ["interfaces", "ethernet", "eth0", "address"];
* const bgpPath: ConfigPath = ["protocols", "bgp", "65001", "neighbor", "192.168.1.1"];
* ```
*/
export const ConfigPathSchema = z
.array(z.string())
.describe('Configuration path as array of strings');
/**
* Schema for retrieving VyOS configuration data.
* Supports both full configuration dumps and specific path queries.
*
* @example
* ```ts
* // Show entire config in JSON format
* const fullConfig: ShowConfigRequest = { format: "json" };
*
* // Show specific interface config as commands
* const ifaceConfig: ShowConfigRequest = {
* path: ["interfaces", "ethernet", "eth0"],
* format: "commands"
* };
* ```
*/
export const ShowConfigRequestSchema = z.object({
/** Configuration path to retrieve (omit for full config) */
path: ConfigPathSchema.optional().describe('Configuration path to retrieve'),
/** Output format - JSON for structured data or commands for CLI syntax */
format: z
.enum([
'json',
'commands',
])
.optional()
.default('json')
.describe('Output format'),
});
/**
* Schema for setting configuration values in VyOS.
* Supports both valued and valueless configuration nodes.
*
* @example
* ```ts
* // Set interface IP address
* const setIP: SetConfigRequest = {
* path: ["interfaces", "ethernet", "eth0", "address"],
* value: "192.168.1.1/24"
* };
*
* // Enable a valueless node
* const enableNode: SetConfigRequest = {
* path: ["service", "ssh"],
* comment: "Enable SSH service"
* };
* ```
*/
export const SetConfigRequestSchema = z.object({
/** Hierarchical path to the configuration node */
path: ConfigPathSchema.describe('Configuration path to set'),
/** Value to set (omit for valueless nodes like enable/disable flags) */
value: z
.string()
.optional()
.describe('Value to set (omit for valueless nodes)'),
/** Optional comment to document the configuration change */
comment: z.string().optional().describe('Configuration comment'),
});
/**
* Schema for deleting configuration nodes from VyOS.
*
* @example
* ```ts
* // Delete interface configuration
* const deleteIface: DeleteConfigRequest = {
* path: ["interfaces", "ethernet", "eth1"]
* };
* ```
*/
export const DeleteConfigRequestSchema = z.object({
/** Configuration path to delete */
path: ConfigPathSchema.describe('Configuration path to delete'),
});
/**
* Schema for checking if a configuration path exists.
* Useful for conditional configuration logic.
*
* @example
* ```ts
* // Check if BGP is configured
* const checkBGP: ConfigExistsRequest = {
* path: ["protocols", "bgp"]
* };
* ```
*/
export const ConfigExistsRequestSchema = z.object({
/** Configuration path to check for existence */
path: ConfigPathSchema.describe('Configuration path to check'),
});
/**
* Schema for retrieving configuration values from a specific path.
* Returns all child values under the specified configuration node.
*
* @example
* ```ts
* // Get all interface names
* const getInterfaces: ReturnValuesRequest = {
* path: ["interfaces", "ethernet"]
* };
* ```
*/
export const ReturnValuesRequestSchema = z.object({
/** Configuration path to get values from */
path: ConfigPathSchema.describe('Configuration path to get values from'),
});
/**
* Schema for committing pending configuration changes.
* Supports both immediate commits and confirm-on-commit functionality.
*
* @example
* ```ts
* // Simple commit with comment
* const simpleCommit: CommitRequest = {
* comment: "Updated interface configuration"
* };
*
* // Commit with 10-minute confirm timeout for safety
* const safeCommit: CommitRequest = {
* comment: "Critical network changes",
* confirmTimeout: 10
* };
* ```
*/
export const CommitRequestSchema = z.object({
/** Descriptive comment for the commit (appears in commit history) */
comment: z.string().optional().describe('Commit comment'),
/** Auto-rollback timeout in minutes (requires manual confirm to prevent rollback) */
confirmTimeout: z
.number()
.optional()
.describe('Auto-rollback timeout in minutes'),
});
/**
* Schema for executing operational mode show commands.
* Used for monitoring and displaying system state.
*
* @example
* ```ts
* // Show interface statistics
* const showIfaces: ShowOperationalRequest = {
* path: ["interfaces", "ethernet", "statistics"],
* format: "json"
* };
*
* // Show BGP summary in raw format
* const showBGP: ShowOperationalRequest = {
* path: ["protocols", "bgp", "summary"],
* format: "raw"
* };
* ```
*/
export const ShowOperationalRequestSchema = z.object({
/** Operational command path array */
path: ConfigPathSchema.describe('Operational command path'),
/** Output format - JSON for structured data or raw for original command output */
format: z
.enum([
'json',
'raw',
])
.optional()
.default('json')
.describe('Output format'),
});
/**
* Schema for executing reset commands in operational mode.
* Used for clearing counters, resetting connections, etc.
*
* @example
* ```ts
* // Reset interface counters
* const resetCounters: ResetRequest = {
* path: ["interfaces", "ethernet", "eth0", "counters"]
* };
* ```
*/
export const ResetRequestSchema = z.object({
/** Reset command path */
path: ConfigPathSchema.describe('Reset command path'),
});
/**
* Schema for executing generate commands.
* Used for creating certificates, keys, and other generated content.
*
* @example
* ```ts
* // Generate WireGuard key pair
* const genKeys: GenerateRequest = {
* path: ["wireguard", "keypair"]
* };
* ```
*/
export const GenerateRequestSchema = z.object({
/** Generate command path */
path: ConfigPathSchema.describe('Generate command path'),
});
/**
* Schema for system image management operations.
*
* @example
* ```ts
* // Add new system image
* const addImage: ImageRequest = {
* name: "vyos-1.4-rolling-202501130317",
* action: "add"
* };
* ```
*/
export const ImageRequestSchema = z.object({
/** System image name */
name: z.string().describe('System image name'),
/** Image operation to perform */
action: z
.enum([
'add',
'delete',
])
.describe('Image operation'),
});
/**
* Schema for configuration file operations.
*
* @example
* ```ts
* // Save current config
* const saveConfig: ConfigFileRequest = {
* action: "save"
* };
*
* // Load specific config file
* const loadConfig: ConfigFileRequest = {
* action: "load",
* file: "/config/config.boot.backup"
* };
* ```
*/
export const ConfigFileRequestSchema = z.object({
/** Configuration file operation */
action: z
.enum([
'save',
'load',
])
.describe('Configuration file operation'),
/** Configuration file path (optional for save, defaults to startup config) */
file: z.string().optional().describe('Configuration file path'),
});
/**
* Schema for network interface configuration.
* Supports Ethernet, VLAN, bridge, and other interface types.
*
* @example
* ```ts
* // Configure LAN interface
* const lanInterface: Interface = {
* name: "eth0",
* address: "192.168.1.1/24",
* description: "LAN Interface",
* enabled: true,
* mtu: 1500
* };
*
* // Configure VLAN interface
* const vlanInterface: Interface = {
* name: "eth0.100",
* address: "10.100.1.1/24",
* description: "Management VLAN",
* vlan: 100
* };
* ```
*/
export const InterfaceSchema = z.object({
/** Interface name (e.g., eth0, eth1.100, wg0) */
name: z.string().min(1).describe('Interface name (e.g., eth0, wg0)'),
/** IP address with CIDR notation */
address: z.string().optional().describe('IP address with CIDR'),
/** Human-readable interface description */
description: z.string().optional().describe('Interface description'),
/** Administrative state (default: true) */
enabled: z
.boolean()
.optional()
.default(true)
.describe('Interface administrative state'),
/** Maximum transmission unit in bytes */
mtu: z.number().optional().describe('Maximum transmission unit'),
/** VLAN ID for VLAN interfaces */
vlan: z.number().optional().describe('VLAN ID for VLAN interfaces'),
});
export const StaticRouteSchema = z.object({
destination: z.string().describe('Destination network (CIDR notation)'),
nextHop: z.string().describe('Next hop IP address or interface'),
distance: z.number().optional().describe('Administrative distance'),
tag: z.number().optional().describe('Route tag'),
});
export const BGPPeerSchema = z.object({
address: z.string().describe('Peer IP address'),
asn: z.number().describe('Peer AS number'),
description: z.string().optional().describe('Peer description'),
password: z.string().optional().describe('BGP authentication password'),
routeMapIn: z.string().optional().describe('Inbound route map'),
routeMapOut: z.string().optional().describe('Outbound route map'),
});
export const BGPConfigSchema = z.object({
asn: z.number().describe('Local AS number'),
routerId: z.string().describe('BGP router ID'),
networks: z.array(z.string()).optional().describe('Networks to advertise'),
neighbors: z.array(BGPPeerSchema).optional().describe('BGP neighbors'),
});
export const FirewallRuleSchema = z.object({
number: z.number().describe('Rule number'),
action: z
.enum([
'accept',
'drop',
'reject',
])
.describe('Rule action'),
protocol: z
.enum([
'tcp',
'udp',
'icmp',
'all',
])
.optional()
.describe('Protocol'),
source: z
.object({
address: z.string().optional().describe('Source address/network'),
port: z.string().optional().describe('Source port'),
})
.optional(),
destination: z
.object({
address: z.string().optional().describe('Destination address/network'),
port: z.string().optional().describe('Destination port'),
})
.optional(),
state: z
.object({
established: z
.boolean()
.optional()
.describe('Match established connections'),
related: z.boolean().optional().describe('Match related connections'),
invalid: z.boolean().optional().describe('Match invalid connections'),
new: z.boolean().optional().describe('Match new connections'),
})
.optional(),
description: z.string().optional().describe('Rule description'),
});
export const NATRuleSchema = z.object({
number: z.number().describe('Rule number'),
type: z
.enum([
'source',
'destination',
])
.describe('NAT rule type'),
outboundInterface: z
.string()
.optional()
.describe('Outbound interface for source NAT'),
inboundInterface: z
.string()
.optional()
.describe('Inbound interface for destination NAT'),
source: z
.object({
address: z.string().optional().describe('Source address/network'),
port: z.string().optional().describe('Source port'),
})
.optional(),
destination: z
.object({
address: z.string().optional().describe('Destination address/network'),
port: z.string().optional().describe('Destination port'),
})
.optional(),
translation: z
.object({
address: z.string().optional().describe('Translation address'),
port: z.string().optional().describe('Translation port'),
})
.describe('Translation settings'),
description: z.string().optional().describe('Rule description'),
});
export const DHCPPoolSchema = z.object({
name: z.string().describe('DHCP pool name'),
subnet: z.string().describe('Subnet in CIDR notation'),
range: z
.object({
start: z.string().describe('Start IP address'),
stop: z.string().describe('End IP address'),
})
.describe('DHCP range'),
defaultRouter: z.string().describe('Default gateway IP'),
nameServer: z.array(z.string()).optional().describe('DNS servers'),
domainName: z.string().optional().describe('Domain name'),
lease: z.number().optional().describe('Lease time in seconds'),
});
export const IPSecTunnelSchema = z.object({
name: z.string().describe('IPSec tunnel name'),
localAddress: z.string().describe('Local tunnel endpoint'),
remoteAddress: z.string().describe('Remote tunnel endpoint'),
presharedKey: z.string().describe('Pre-shared key'),
localSubnets: z.array(z.string()).describe('Local subnets'),
remoteSubnets: z.array(z.string()).describe('Remote subnets'),
encryption: z
.enum([
'aes128',
'aes256',
'3des',
])
.optional()
.default('aes256')
.describe('Encryption algorithm'),
hash: z
.enum([
'sha1',
'sha256',
'md5',
])
.optional()
.default('sha256')
.describe('Hash algorithm'),
dhGroup: z.number().optional().default(14).describe('Diffie-Hellman group'),
});
export const WireGuardPeerSchema = z.object({
publicKey: z.string().describe('Peer public key'),
allowedIPs: z.array(z.string()).describe('Allowed IP addresses/networks'),
endpoint: z.string().optional().describe('Peer endpoint (IP:port)'),
persistentKeepalive: z
.number()
.optional()
.describe('Keepalive interval in seconds'),
});
export const WireGuardInterfaceSchema = z.object({
name: z.string().describe('WireGuard interface name'),
privateKey: z.string().describe('Interface private key'),
port: z.number().describe('Listen port'),
address: z.array(z.string()).describe('Interface IP addresses'),
peers: z.array(WireGuardPeerSchema).optional().describe('WireGuard peers'),
});
export const VRRPGroupSchema = z.object({
interface: z.string().describe('Interface name'),
groupId: z.number().describe('VRRP group ID'),
virtualAddress: z.array(z.string()).describe('Virtual IP addresses'),
priority: z.number().min(1).max(254).describe('VRRP priority'),
advertiseInterval: z
.number()
.optional()
.default(1)
.describe('Advertisement interval'),
authentication: z
.object({
type: z
.enum([
'plaintext',
'ah',
])
.describe('Authentication type'),
password: z.string().describe('Authentication password'),
})
.optional(),
});
export const SystemInfoSchema = z.object({
hostname: z.string(),
version: z.string(),
uptime: z.string(),
serialNumber: z.string().optional(),
hardware: z.string().optional(),
});
export const InterfaceStatsSchema = z.object({
name: z.string(),
state: z.enum([
'up',
'down',
]),
rxBytes: z.number(),
txBytes: z.number(),
rxPackets: z.number(),
txPackets: z.number(),
rxErrors: z.number(),
txErrors: z.number(),
});
export const RouteTableEntrySchema = z.object({
destination: z.string(),
gateway: z.string().optional(),
interface: z.string(),
metric: z.number(),
protocol: z.string(),
});
export const BGPNeighborStatusSchema = z.object({
address: z.string(),
asn: z.number(),
state: z.string(),
uptime: z.string(),
prefixCount: z.number(),
});
export const ConntrackEntrySchema = z.object({
protocol: z.string(),
sourceAddress: z.string(),
sourcePort: z.number().optional(),
destinationAddress: z.string(),
destinationPort: z.number().optional(),
state: z.string(),
timeout: z.number(),
});
export const VPNStatusSchema = z.object({
tunnel: z.string(),
status: z.enum([
'up',
'down',
]),
localAddress: z.string(),
remoteAddress: z.string(),
encryption: z.string(),
rxBytes: z.number(),
txBytes: z.number(),
});
export const PingRequestSchema = z.object({
host: z.string().describe('Target hostname or IP address'),
count: z.number().optional().default(3).describe('Number of packets to send'),
interval: z
.number()
.optional()
.default(1)
.describe('Interval between packets'),
timeout: z.number().optional().default(5).describe('Timeout for each packet'),
size: z.number().optional().default(56).describe('Packet size in bytes'),
source: z.string().optional().describe('Source IP address'),
});
export const TracerouteRequestSchema = z.object({
host: z.string().describe('Target hostname or IP address'),
maxHops: z.number().optional().default(30).describe('Maximum number of hops'),
timeout: z.number().optional().default(5).describe('Timeout for each hop'),
source: z.string().optional().describe('Source IP address'),
});
export const MonitorInterfaceRequestSchema = z.object({
interface: z.string().describe('Interface name to monitor'),
duration: z
.number()
.optional()
.default(10)
.describe('Monitoring duration in seconds'),
interval: z
.number()
.optional()
.default(1)
.describe('Update interval in seconds'),
});
export const LogQueryRequestSchema = z.object({
service: z
.string()
.optional()
.describe('Service name (e.g., ssh, dhcp, bgp)'),
severity: z
.enum([
'emergency',
'alert',
'critical',
'error',
'warning',
'notice',
'info',
'debug',
])
.optional()
.describe('Log severity level'),
since: z
.string()
.optional()
.describe("Start time (ISO format or relative like '1h ago')"),
until: z.string().optional().describe('End time (ISO format)'),
lines: z
.number()
.optional()
.default(100)
.describe('Number of lines to return'),
follow: z
.boolean()
.optional()
.default(false)
.describe('Follow log in real-time'),
});
export const BackupConfigRequestSchema = z.object({
format: z
.enum([
'commands',
'json',
])
.optional()
.default('commands')
.describe('Backup format'),
includeDefaults: z
.boolean()
.optional()
.default(false)
.describe('Include default values'),
});
export const RestoreConfigRequestSchema = z.object({
config: z.string().describe('Configuration data to restore'),
format: z
.enum([
'commands',
'json',
])
.describe('Configuration format'),
merge: z
.boolean()
.optional()
.default(false)
.describe('Merge with existing config'),
});
export const HealthCheckRequestSchema = z.object({
includeInterfaces: z
.boolean()
.optional()
.default(true)
.describe('Check interface status'),
includeRouting: z
.boolean()
.optional()
.default(true)
.describe('Check routing protocols'),
includeServices: z
.boolean()
.optional()
.default(true)
.describe('Check system services'),
includeResources: z
.boolean()
.optional()
.default(true)
.describe('Check system resources'),
});
export type VyOSAuth = z.infer<typeof VyOSAuthSchema>;
export type ConfigPath = z.infer<typeof ConfigPathSchema>;
export type ShowConfigRequest = z.infer<typeof ShowConfigRequestSchema>;
export type SetConfigRequest = z.infer<typeof SetConfigRequestSchema>;
export type DeleteConfigRequest = z.infer<typeof DeleteConfigRequestSchema>;
export type Interface = z.infer<typeof InterfaceSchema>;
export type StaticRoute = z.infer<typeof StaticRouteSchema>;
export type BGPConfig = z.infer<typeof BGPConfigSchema>;
export type FirewallRule = z.infer<typeof FirewallRuleSchema>;
export type NATRule = z.infer<typeof NATRuleSchema>;
export type DHCPPool = z.infer<typeof DHCPPoolSchema>;
export type IPSecTunnel = z.infer<typeof IPSecTunnelSchema>;
export type WireGuardInterface = z.infer<typeof WireGuardInterfaceSchema>;
export type VRRPGroup = z.infer<typeof VRRPGroupSchema>;
export type PingRequest = z.infer<typeof PingRequestSchema>;
export type TracerouteRequest = z.infer<typeof TracerouteRequestSchema>;
export type LogQueryRequest = z.infer<typeof LogQueryRequestSchema>;
export type HealthCheckRequest = z.infer<typeof HealthCheckRequestSchema>;