diff --git a/src/WinBGP-API.ps1 b/src/WinBGP-API.ps1 index 905c4b8..2b5a2c7 100644 --- a/src/WinBGP-API.ps1 +++ b/src/WinBGP-API.ps1 @@ -363,195 +363,282 @@ if ($Configuration) { # Write-Log "API request received: $FullRequest" -EventLogSource 'WinBGP-API' $FullPath=($request.RawUrl).substring(1) $Path=$FullPath.Split('?')[0] - switch ($request.HttpMethod) { - 'GET' { - if ($FullPath -eq 'api') { - $commandOutput = ConvertTo-Json -InputObject @{'message'='WinBGP API running'} - $statusCode = [System.Net.HttpStatusCode]::OK - } elseif ($FullPath -like 'api/*') { - $Path=$Path.replace('api/','') - $shortPath=$Path.Split('/')[0] - switch ($shortPath) { - 'config' { - if (($Path -eq 'config') -or ($Path -eq 'config/')) { - $commandOutput = WinBGP -Config | ConvertTo-JSON - $outputHeader.Add('Content-Type', 'application/json') - $statusCode = [System.Net.HttpStatusCode]::OK - } else { - $SubConfig=$Path.Split('/')[1] - $commandOutput = (WinBGP -Config).$SubConfig - if ($commandOutput) { - $commandOutput = $commandOutput | ConvertTo-JSON + switch -wildcard ($FullPath) { + 'api*' { + switch ($request.HttpMethod) { + 'GET' { + if ($FullPath -eq 'api') { + $commandOutput = ConvertTo-Json -InputObject @{'message'='WinBGP API running'} + $statusCode = [System.Net.HttpStatusCode]::OK + } elseif ($FullPath -like 'api/*') { + $Path=$Path.replace('api/','') + $shortPath=$Path.Split('/')[0] + switch ($shortPath) { + 'config' { + if (($Path -eq 'config') -or ($Path -eq 'config/')) { + $commandOutput = WinBGP -Config | ConvertTo-JSON + $outputHeader.Add('Content-Type', 'application/json') + $statusCode = [System.Net.HttpStatusCode]::OK + } else { + $SubConfig=$Path.Split('/')[1] + $commandOutput = (WinBGP -Config).$SubConfig + if ($commandOutput) { + $commandOutput = $commandOutput | ConvertTo-JSON + $outputHeader.Add('Content-Type', 'application/json') + $statusCode = [System.Net.HttpStatusCode]::OK + } else { + $statusCode = [System.Net.HttpStatusCode]::NotFound + } + } + } + 'logs' { + $Last = $request.QueryString.Item("Last") + if (!($Last)) { $Last = 10 } + $commandOutput = WinBGP -Logs -Last $Last | Select-Object Index,TimeGenerated,@{Label='EntryType';Expression={($_.EntryType).ToString()}},Message,RouteName | ConvertTo-JSON $outputHeader.Add('Content-Type', 'application/json') $statusCode = [System.Net.HttpStatusCode]::OK - } else { - $statusCode = [System.Net.HttpStatusCode]::NotFound + } + 'peers' { + if (($Path -eq 'peers') -or ($Path -eq 'peers/')) { + $commandOutput = ConvertTo-Json -InputObject @(Get-BgpPeer | Select-Object PeerName,LocalIPAddress,LocalASN,PeerIPAddress,PeerASN,@{Label='ConnectivityStatus';Expression={$_.ConnectivityStatus.ToString()}}) #Using @() as inputobject to always return an array + $outputHeader.Add('Content-Type', 'application/json') + $statusCode = [System.Net.HttpStatusCode]::OK + } else { + $PeerName=$Path.Split('/')[1] + $commandOutput = Get-BgpPeer | Where-Object {$_.PeerName -eq $PeerName} | Select-Object PeerName,LocalIPAddress,PeerIPAddress,PeerASN,@{Label='ConnectivityStatus';Expression={$_.ConnectivityStatus.ToString()}} + if ($commandOutput) { + $commandOutput = $commandOutput | ConvertTo-JSON + $outputHeader.Add('Content-Type', 'application/json') + $statusCode = [System.Net.HttpStatusCode]::OK + } else { + $statusCode = [System.Net.HttpStatusCode]::NotFound + } + } + } + 'router' { + $commandOutput = Get-BgpRouter | Select-Object BgpIdentifier,LocalASN,PeerName,PolicyName | ConvertTo-JSON + $statusCode = [System.Net.HttpStatusCode]::OK + } + 'routes' { + if (($Path -eq 'routes') -or ($Path -eq 'routes/')) { + $commandOutput = ConvertTo-Json -InputObject @(WinBGP | Select-Object Name,Network,Status,@{Label='MaintenanceTimestamp';Expression={($_.MaintenanceTimestamp).ToString("yyyy-MM-ddTHH:mm:ss.fffK")}}) #Using @() as inputobject to always return an array + $outputHeader.Add('Content-Type', 'application/json') + $statusCode = [System.Net.HttpStatusCode]::OK + } else { + $RouteName=$Path.Split('/')[1] + $commandOutput = WinBGP | Where-Object {$_.Name -eq $RouteName} | Select-Object Name,Network,Status,@{Label='MaintenanceTimestamp';Expression={($_.MaintenanceTimestamp).ToString("yyyy-MM-ddTHH:mm:ss.fffK")}} + if ($commandOutput) { + $commandOutput = $commandOutput | ConvertTo-JSON + $outputHeader.Add('Content-Type', 'application/json') + $statusCode = [System.Net.HttpStatusCode]::OK + } else { + $statusCode = [System.Net.HttpStatusCode]::NotFound + } + } + } + 'statistics' { + $commandOutput=(Invoke-CimMethod -ClassName "PS_BgpStatistics" -Namespace 'ROOT\Microsoft\Windows\RemoteAccess' -MethodName Get -OperationTimeoutSec 5).cmdletoutput | Select-Object PeerName,TcpConnectionEstablished,TcpConnectionClosed,@{Label='OpenMessage';Expression={$_.OpenMessage.CimInstanceProperties | Select-Object Name,Value}},@{Label='NotificationMessage';Expression={$_.NotificationMessage.CimInstanceProperties | Select-Object Name,Value}},@{Label='KeepAliveMessage';Expression={$_.KeepAliveMessage.CimInstanceProperties | Select-Object Name,Value}},@{Label='RouteRefreshMessage';Expression={$_.RouteRefreshMessage.CimInstanceProperties | Select-Object Name,Value}},@{Label='UpdateMessage';Expression={$_.UpdateMessage.CimInstanceProperties | Select-Object Name,Value}},@{Label='IPv4Route';Expression={$_.IPv4Route.CimInstanceProperties | Select-Object Name,Value}},@{Label='IPv6Route';Expression={$_.IPv6Route.CimInstanceProperties | Select-Object Name,Value}} | ConvertTo-JSON + $outputHeader.Add('Content-Type', 'application/json') + $statusCode = [System.Net.HttpStatusCode]::OK + } + 'status' { + [string]$status = WinBGP -Status + $commandOutput = ConvertTo-Json -InputObject @{'service'=$status} + $outputHeader.Add('Content-Type', 'application/json') + $statusCode = [System.Net.HttpStatusCode]::OK + } + 'version' { + $commandOutput = WinBGP -Version | ConvertTo-JSON + $outputHeader.Add('Content-Type', 'application/json') + $statusCode = [System.Net.HttpStatusCode]::OK + } + Default { + $statusCode = [System.Net.HttpStatusCode]::NotImplemented } } } - 'logs' { - $Last = $request.QueryString.Item("Last") - if (!($Last)) { $Last = 10 } - $commandOutput = WinBGP -Logs -Last $Last | Select-Object Index,TimeGenerated,@{Label='EntryType';Expression={($_.EntryType).ToString()}},Message,RouteName | ConvertTo-JSON - $outputHeader.Add('Content-Type', 'application/json') - $statusCode = [System.Net.HttpStatusCode]::OK - } - 'peers' { - if (($Path -eq 'peers') -or ($Path -eq 'peers/')) { - $commandOutput = ConvertTo-Json -InputObject @(Get-BgpPeer | Select-Object PeerName,LocalIPAddress,LocalASN,PeerIPAddress,PeerASN,@{Label='ConnectivityStatus';Expression={$_.ConnectivityStatus.ToString()}}) #Using @() as inputobject to always return an array + } + 'POST' { + $RouteName = $request.QueryString.Item("RouteName") + $Path=$Path.replace('api/','') + Write-Log "API received POST request '$Path' from '$RequestUser' - Source IP: '$RequestHost'" -AdditionalFields $RouteName + switch ($Path) { + 'Reload' { + [string]$ActionOutput=WinBGP -Reload + $commandOutput = ConvertTo-Json -InputObject @{'output'=$ActionOutput} $outputHeader.Add('Content-Type', 'application/json') - $statusCode = [System.Net.HttpStatusCode]::OK - } else { - $PeerName=$Path.Split('/')[1] - $commandOutput = Get-BgpPeer | Where-Object {$_.PeerName -eq $PeerName} | Select-Object PeerName,LocalIPAddress,PeerIPAddress,PeerASN,@{Label='ConnectivityStatus';Expression={$_.ConnectivityStatus.ToString()}} - if ($commandOutput) { - $commandOutput = $commandOutput | ConvertTo-JSON - $outputHeader.Add('Content-Type', 'application/json') - $statusCode = [System.Net.HttpStatusCode]::OK - } else { - $statusCode = [System.Net.HttpStatusCode]::NotFound - } + } + 'StartMaintenance' { + [string]$ActionOutput=WinBGP -RouteName "$RouteName" -StartMaintenance + $commandOutput = ConvertTo-Json -InputObject @{'output'=$ActionOutput} + $outputHeader.Add('Content-Type', 'application/json') + } + 'StartRoute' { + [string]$ActionOutput=WinBGP -RouteName "$RouteName" -StartRoute + $commandOutput = ConvertTo-Json -InputObject @{'output'=$ActionOutput} + $outputHeader.Add('Content-Type', 'application/json') + } + 'StopMaintenance' { + [string]$ActionOutput=WinBGP -RouteName "$RouteName" -StopMaintenance + $commandOutput = ConvertTo-Json -InputObject @{'output'=$ActionOutput} + $outputHeader.Add('Content-Type', 'application/json') + } + 'StopRoute' { + [string]$ActionOutput=WinBGP -RouteName "$RouteName" -StopRoute + $commandOutput = ConvertTo-Json -InputObject @{'output'=$ActionOutput} + $outputHeader.Add('Content-Type', 'application/json') + } + Default { + $statusCode = [System.Net.HttpStatusCode]::NotImplemented } } - 'router' { - $commandOutput = Get-BgpRouter | Select-Object BgpIdentifier,LocalASN,PeerName,PolicyName | ConvertTo-JSON - $statusCode = [System.Net.HttpStatusCode]::OK - } - 'routes' { - if (($Path -eq 'routes') -or ($Path -eq 'routes/')) { - $commandOutput = ConvertTo-Json -InputObject @(WinBGP | Select-Object Name,Network,Status,@{Label='MaintenanceTimestamp';Expression={($_.MaintenanceTimestamp).ToString("yyyy-MM-ddTHH:mm:ss.fffK")}}) #Using @() as inputobject to always return an array - $outputHeader.Add('Content-Type', 'application/json') - $statusCode = [System.Net.HttpStatusCode]::OK - } else { - $RouteName=$Path.Split('/')[1] - $commandOutput = WinBGP | Where-Object {$_.Name -eq $RouteName} | Select-Object Name,Network,Status,@{Label='MaintenanceTimestamp';Expression={($_.MaintenanceTimestamp).ToString("yyyy-MM-ddTHH:mm:ss.fffK")}} - if ($commandOutput) { - $commandOutput = $commandOutput | ConvertTo-JSON - $outputHeader.Add('Content-Type', 'application/json') - $statusCode = [System.Net.HttpStatusCode]::OK - } else { - $statusCode = [System.Net.HttpStatusCode]::NotFound - } - } - } - 'statistics' { - $commandOutput=(Invoke-CimMethod -ClassName "PS_BgpStatistics" -Namespace 'ROOT\Microsoft\Windows\RemoteAccess' -MethodName Get -OperationTimeoutSec 5).cmdletoutput | Select-Object PeerName,TcpConnectionEstablished,TcpConnectionClosed,@{Label='OpenMessage';Expression={$_.OpenMessage.CimInstanceProperties | Select-Object Name,Value}},@{Label='NotificationMessage';Expression={$_.NotificationMessage.CimInstanceProperties | Select-Object Name,Value}},@{Label='KeepAliveMessage';Expression={$_.KeepAliveMessage.CimInstanceProperties | Select-Object Name,Value}},@{Label='RouteRefreshMessage';Expression={$_.RouteRefreshMessage.CimInstanceProperties | Select-Object Name,Value}},@{Label='UpdateMessage';Expression={$_.UpdateMessage.CimInstanceProperties | Select-Object Name,Value}},@{Label='IPv4Route';Expression={$_.IPv4Route.CimInstanceProperties | Select-Object Name,Value}},@{Label='IPv6Route';Expression={$_.IPv6Route.CimInstanceProperties | Select-Object Name,Value}} | ConvertTo-JSON - $outputHeader.Add('Content-Type', 'application/json') - $statusCode = [System.Net.HttpStatusCode]::OK - } - 'status' { - [string]$status = WinBGP -Status - $commandOutput = ConvertTo-Json -InputObject @{'service'=$status} - $outputHeader.Add('Content-Type', 'application/json') - $statusCode = [System.Net.HttpStatusCode]::OK - } - 'version' { - $commandOutput = WinBGP -Version | ConvertTo-JSON - $outputHeader.Add('Content-Type', 'application/json') - $statusCode = [System.Net.HttpStatusCode]::OK - } - Default { - $statusCode = [System.Net.HttpStatusCode]::NotImplemented + switch ($commandOutput.output) { + 'Success' { $statusCode = [System.Net.HttpStatusCode]::OK } + 'WinBGP not ready' { $statusCode = [System.Net.HttpStatusCode]::InternalServerError } } } - } elseif ($FullPath -eq 'metrics') { - # Define WinBGP Prometheus metrics - $WinBGP_metrics=@() - - # WinBGP peer status - $state_peerDescriptor=New-PrometheusMetricDescriptor -Name winbgp_state_peer -Type gauge -Help 'WinBGP Peers status' -Labels local_asn,local_ip,name,peer_asn,peer_ip,state - $peerStatus=@('connected','connecting','stopped') - # Try/catch to detect if BGP is configured properly - $BgpStatus=$null - try { - $peersCurrentStatus=Get-BgpPeer -ErrorAction SilentlyContinue | Select-Object PeerName,LocalIPAddress,LocalASN,PeerIPAddress,PeerASN,@{Label='ConnectivityStatus';Expression={$_.ConnectivityStatus.ToString()}} + Default { + $statusCode = [System.Net.HttpStatusCode]::NotImplemented } - catch { - # If BGP Router (Local) is not configured, catch it - $BgpStatus=($_).ToString() - } - if ($BgpStatus -eq 'BGP is not configured.') { - $peersCurrentStatus=$null - } - # Parse all peers and generate metric - foreach ($peerCurrentStatus in $peersCurrentStatus) { - foreach ($status in $peerStatus) { - $WinBGP_metrics+=New-PrometheusMetric -PrometheusMetricDescriptor $state_peerDescriptor -Value $(if ($status -eq $peerCurrentStatus.ConnectivityStatus) { 1 } else { 0 }) -Labels $peerCurrentStatus.LocalASN,$peerCurrentStatus.LocalIPAddress,$peerCurrentStatus.PeerName,$peerCurrentStatus.PeerASN,$peerCurrentStatus.PeerIPAddress,$status - } - } - - # WinBGP route status - $state_routeDescriptor=New-PrometheusMetricDescriptor -Name winbgp_state_route -Type gauge -Help 'WinBGP routes status' -Labels family,maintenance_timestamp,name,network,state - $routeStatus=@('down','maintenance','up','warning') - # Silently continue as WinBGP is generating errors when BGP is not configured (TO REVIEW) - $routesCurrentStatus=(WinBGP -ErrorAction SilentlyContinue | Select-Object Name,Network,Status,@{Label='MaintenanceTimestamp';Expression={($_.MaintenanceTimestamp).ToString("yyyy-MM-ddTHH:mm:ss.fffK")}}) - foreach ($routeCurrentStatus in $routesCurrentStatus) { - foreach ($status in $routeStatus) { - $WinBGP_metrics+=New-PrometheusMetric -PrometheusMetricDescriptor $state_routeDescriptor -Value $(if ($status -eq $routeCurrentStatus.Status) { 1 } else { 0 }) -Labels 'ipv4',$routeCurrentStatus.MaintenanceTimestamp,$routeCurrentStatus.Name,$routeCurrentStatus.Network,$status - } - } - - # Return output - $commandOutput = Export-PrometheusMetrics -Metrics $WinBGP_metrics - - # Add header - $outputHeader.Add('Content-Type', 'text/plain; version=0.0.4; charset=utf-8') - $statusCode = [System.Net.HttpStatusCode]::OK - } else { - $statusCode = [System.Net.HttpStatusCode]::NotImplemented } } - 'POST' { - # Add stop method to stop API (TO IMPROVE) - if ($FullPath -eq 'stop') { - # Only local request are authorized - if ($request.IsLocal) { - $keepListening = $false + 'metrics' { + switch ($request.HttpMethod) { + 'GET' { + # Define WinBGP Prometheus metrics + $WinBGP_metrics=@() + + # WinBGP peer status + $state_peerDescriptor=New-PrometheusMetricDescriptor -Name winbgp_state_peer -Type gauge -Help 'WinBGP Peers status' -Labels local_asn,local_ip,name,peer_asn,peer_ip,state + $peerStatus=@('connected','connecting','stopped') + # Try/catch to detect if BGP is configured properly + $BgpStatus=$null + try { + $peersCurrentStatus=Get-BgpPeer -ErrorAction SilentlyContinue | Select-Object PeerName,LocalIPAddress,LocalASN,PeerIPAddress,PeerASN,@{Label='ConnectivityStatus';Expression={$_.ConnectivityStatus.ToString()}} + } + catch { + # If BGP Router (Local) is not configured, catch it + $BgpStatus=($_).ToString() + } + if ($BgpStatus -eq 'BGP is not configured.') { + $peersCurrentStatus=$null + } + # Parse all peers and generate metric + foreach ($peerCurrentStatus in $peersCurrentStatus) { + foreach ($status in $peerStatus) { + $WinBGP_metrics+=New-PrometheusMetric -PrometheusMetricDescriptor $state_peerDescriptor -Value $(if ($status -eq $peerCurrentStatus.ConnectivityStatus) { 1 } else { 0 }) -Labels $peerCurrentStatus.LocalASN,$peerCurrentStatus.LocalIPAddress,$peerCurrentStatus.PeerName,$peerCurrentStatus.PeerASN,$peerCurrentStatus.PeerIPAddress,$status + } + } + + # WinBGP route status + $state_routeDescriptor=New-PrometheusMetricDescriptor -Name winbgp_state_route -Type gauge -Help 'WinBGP routes status' -Labels family,maintenance_timestamp,name,network,state + $routeStatus=@('down','maintenance','up','warning') + # Silently continue as WinBGP is generating errors when BGP is not configured (TO REVIEW) + $routesCurrentStatus=(WinBGP -ErrorAction SilentlyContinue | Select-Object Name,Network,Status,@{Label='MaintenanceTimestamp';Expression={($_.MaintenanceTimestamp).ToString("yyyy-MM-ddTHH:mm:ss.fffK")}}) + foreach ($routeCurrentStatus in $routesCurrentStatus) { + foreach ($status in $routeStatus) { + $WinBGP_metrics+=New-PrometheusMetric -PrometheusMetricDescriptor $state_routeDescriptor -Value $(if ($status -eq $routeCurrentStatus.Status) { 1 } else { 0 }) -Labels 'ipv4',$routeCurrentStatus.MaintenanceTimestamp,$routeCurrentStatus.Name,$routeCurrentStatus.Network,$status + } + } + + # Return output + $commandOutput = Export-PrometheusMetrics -Metrics $WinBGP_metrics + + # Add header + $outputHeader.Add('Content-Type', 'text/plain; version=0.0.4; charset=utf-8') $statusCode = [System.Net.HttpStatusCode]::OK - } else { - $statusCode = [System.Net.HttpStatusCode]::Forbidden + } + Default { + $statusCode = [System.Net.HttpStatusCode]::NotImplemented } } - elseif ($FullPath -like 'api/*') { - $RouteName = $request.QueryString.Item("RouteName") - $Path=$Path.replace('api/','') - Write-Log "API received POST request '$Path' from '$RequestUser' - Source IP: '$RequestHost'" -AdditionalFields $RouteName - switch ($Path) { - 'Reload' { - [string]$ActionOutput=WinBGP -Reload - $commandOutput = ConvertTo-Json -InputObject @{'output'=$ActionOutput} - $outputHeader.Add('Content-Type', 'application/json') - } - 'StartMaintenance' { - [string]$ActionOutput=WinBGP -RouteName "$RouteName" -StartMaintenance - $commandOutput = ConvertTo-Json -InputObject @{'output'=$ActionOutput} - $outputHeader.Add('Content-Type', 'application/json') - } - 'StartRoute' { - [string]$ActionOutput=WinBGP -RouteName "$RouteName" -StartRoute - $commandOutput = ConvertTo-Json -InputObject @{'output'=$ActionOutput} - $outputHeader.Add('Content-Type', 'application/json') - } - 'StopMaintenance' { - [string]$ActionOutput=WinBGP -RouteName "$RouteName" -StopMaintenance - $commandOutput = ConvertTo-Json -InputObject @{'output'=$ActionOutput} - $outputHeader.Add('Content-Type', 'application/json') - } - 'StopRoute' { - [string]$ActionOutput=WinBGP -RouteName "$RouteName" -StopRoute - $commandOutput = ConvertTo-Json -InputObject @{'output'=$ActionOutput} - $outputHeader.Add('Content-Type', 'application/json') - } - Default { - $statusCode = [System.Net.HttpStatusCode]::NotImplemented + } + 'mcp' { + # Always send json header for MCP + $outputHeader.Add('Content-Type', 'application/json') + # Body request + $requestBodyReader = New-Object System.IO.StreamReader $request.InputStream + $requestBody=$requestBodyReader.ReadToEnd() + $jsonRequestBody=$requestBody | convertfrom-json + switch ($request.HttpMethod) { + 'GET' { + # Send not allowed (405) to avoid switching to SSE + $statusCode = [System.Net.HttpStatusCode]::MethodNotAllowed + } + 'POST' { + switch ($jsonRequestBody.method) { + 'initialize' { + $commandOutput = '{"jsonrpc":"2.0","id":' + ($jsonRequestBody.id | ConvertTo-Json -Depth 10 -Compress) + ',"result":{"protocolVersion":"2025-03-26","capabilities":{"tools":{"listChanged":false}},"serverInfo":{"name":"WinBGP MCP Server","version":"0.1.0"}}}' + $statusCode = [System.Net.HttpStatusCode]::OK + } + 'notifications/initialized' { + # Accept the initialization request + $statusCode = [System.Net.HttpStatusCode]::Accepted + } + 'notifications/responses' { + # Accept the notification request + $statusCode = [System.Net.HttpStatusCode]::Accepted + } + 'tools/list' { + $toolsListJson = '{"name":"Get-WinBGPRoute","description":"Get-WinBGPRoute","inputSchema":{"type":"object","properties":{"ComputerName":{"type":"string","description":"Single or multiple ComputerName (Default: localhost)"},"Name":{"type":"string","description":"Single or multiple Route Name (IntelliSense availalble)"}},"required":[]},"returns":{"type":"string","description":"Get-WinBGPRoute"}}' + $commandOutput = '{"jsonrpc":"2.0","id":' + ($jsonRequestBody.id | ConvertTo-Json -Depth 10 -Compress) + ',"result":{"tools":' + $toolsListJson + '}}' + $statusCode = [System.Net.HttpStatusCode]::OK + } + 'tools/call' { + #$toolName = $jsonRequestBody.params.name + #$Arguments = $jsonRequestBody.params.arguments + + #$result = & $toolName @targetArgs + $result=[PSCustomObject]@{ + Name = 'demo.webalex.lab' + Network = '172.16.10.10/32' + Status = 'up' + MaintenanceTimestamp = $null + ComputerName = 'server1.webalex.lab' + } + + $callresponse = [ordered]@{ + jsonrpc = "2.0" + id = $jsonRequestBody.id + result = @{ + content = @( + [ordered]@{ + type = "text" + text = $result | Out-String + } + ) + isError = $false + } + } + + $commandOutput=$callresponse | ConvertTo-Json -Depth 10 -Compress + $statusCode = [System.Net.HttpStatusCode]::OK + } + Default { + $statusCode = [System.Net.HttpStatusCode]::NotImplemented + } } } - switch ($commandOutput.output) { - 'Success' { $statusCode = [System.Net.HttpStatusCode]::OK } - 'WinBGP not ready' { $statusCode = [System.Net.HttpStatusCode]::InternalServerError } + Default { + $statusCode = [System.Net.HttpStatusCode]::NotImplemented + } + } + } + # Add stop method to stop API (TO IMPROVE) + 'stop' { + switch ($request.HttpMethod) { + 'POST' { + # Only local request are authorized + if ($request.IsLocal) { + $keepListening = $false + $statusCode = [System.Net.HttpStatusCode]::OK + } else { + $statusCode = [System.Net.HttpStatusCode]::Forbidden + } + } + Default { + $statusCode = [System.Net.HttpStatusCode]::NotImplemented } - } else { - $statusCode = [System.Net.HttpStatusCode]::NotImplemented } } Default {