17 Commits

Author SHA1 Message Date
0c7f736d73 Update src/WinBGP-API.ps1 2025-11-07 22:14:39 +01:00
Alexandre JARDON
c1dbeeea1c Add service signing 2025-03-15 11:31:17 +01:00
Alexandre JARDON
1e221eafe7 Review build 2025-03-15 09:51:17 +01:00
Alexandre JARDON
ca7224391d Review build 2025-03-15 09:49:43 +01:00
Alexandre JARDON
25ed7571a1 Review build 2025-03-15 09:48:11 +01:00
Alexandre JARDON
9f36ca794e Review build 2025-03-15 09:43:53 +01:00
Alexandre JARDON
ea4006b290 Review build 2025-03-15 09:42:58 +01:00
Alexandre JARDON
cb99fc2470 Review build 2025-03-15 09:40:18 +01:00
Alexandre JARDON
76c9ed376c Review build 2025-03-15 09:38:48 +01:00
Alexandre JARDON
e01fc6c7c9 Review build 2025-03-15 09:37:21 +01:00
Alexandre JARDON
30a3360f72 Review build 2025-03-15 09:35:10 +01:00
Alexandre JARDON
1fb7093032 Review build 2025-03-15 09:32:57 +01:00
Alexandre JARDON
00e27a77de Review build 2025-03-15 09:28:11 +01:00
Alexandre JARDON
b4b06f361e Review build 2025-03-15 09:26:26 +01:00
Alexandre JARDON
f682432188 Review build 2025-03-15 09:24:43 +01:00
Alexandre JARDON
838a206ed3 Review build 2025-03-15 09:20:40 +01:00
Alexandre JARDON
cfcd5550f2 Review build 2025-03-14 15:59:09 +01:00
3 changed files with 278 additions and 176 deletions

View File

@@ -21,8 +21,22 @@ Trap {
# Reset working dir on error
Pop-Location
}
# If signing, get the certificate
if ($Sign) {
$cert=Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Where-Object { $_.Thumbprint -eq $CertificateThumbprint }
}
# Building service executable
Write-Output "Building WinBGP service"
& "..\service\WinBGP-Service.ps1" -Build
Move-Item -Path "..\builder\WinBGP-Service.exe" -Destination "..\service\WinBGP-Service.exe" -Force
if ($Sign) {
& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe" sign /sha1 $CertificateThumbprint /tr http://time.certum.pl/ /td sha256 /fd sha256 /v "..\service\WinBGP-Service.exe"
}
# Building engine
Write-Output "Building engine"
New-Item -ItemType Directory -Path "..\engine" -Force | Out-Null
Get-ChildItem -Path '..\src' | Where-Object {$_.Extension -eq '.ps1'} | ForEach-Object {
Copy-Item -Path $_.FullName -Destination "..\engine" -Force
if ($Sign) {
@@ -30,17 +44,18 @@ Get-ChildItem -Path '..\src' | Where-Object {$_.Extension -eq '.ps1'} | ForEach
}
}
Write-Verbose "Creating winbgp-${Version}-${Arch}.msi"
Write-Output "Building winbgp-${Version}-${Arch}.msi"
$wixArch = @{"amd64" = "x64"; "arm64" = "arm64"}[$Arch]
Invoke-Expression "wix build -arch $wixArch -o .\WinBGP-$($Version)-$($Arch).msi .\files.wxs .\main.wxs -d ProductName=WinBGP -d Version=$($MsiVersion) -ext WixToolset.Firewall.wixext -ext WixToolset.UI.wixext -ext WixToolset.Util.wixext"
Write-Verbose "Done!"
Pop-Location
Write-Output "Build complete !"
# Clean temporary build folder
Remove-Item -Path "..\engine\*"
Write-Output "Release build"
New-Item -ItemType Directory -Path "..\release" -Force | Out-Null
Copy-Item -Path "WinBGP-$($Version)-$($Arch).msi" -Destination "..\release" -Force
if ($Sign) {
& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe" sign /sha1 $CertificateThumbprint /tr http://time.certum.pl/ /td sha256 /fd sha256 /v "..\release\WinBGP-$($Version)-$($Arch).msi"

View File

@@ -897,10 +897,10 @@ if ($Build) { # Install the service
# Generate the service .EXE from the C# source embedded in this script
# Overwrite for builder
$exeFullName=".\$exeName"
$exeFullName=$exeName
try {
Write-Verbose "Compiling $exeFullName"
Write-Output "Compiling $exeFullName"
Add-Type -TypeDefinition $source -Language CSharp -OutputAssembly $exeFullName -OutputType ConsoleApplication -ReferencedAssemblies "System.ServiceProcess" -Debug:$false
} catch {
$msg = $_.Exception.Message

View File

@@ -363,6 +363,8 @@ if ($Configuration) {
# Write-Log "API request received: $FullRequest" -EventLogSource 'WinBGP-API'
$FullPath=($request.RawUrl).substring(1)
$Path=$FullPath.Split('?')[0]
switch -wildcard ($FullPath) {
'api*' {
switch ($request.HttpMethod) {
'GET' {
if ($FullPath -eq 'api') {
@@ -454,7 +456,55 @@ if ($Configuration) {
$statusCode = [System.Net.HttpStatusCode]::NotImplemented
}
}
} elseif ($FullPath -eq 'metrics') {
}
}
'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')
}
'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
}
}
switch ($commandOutput.output) {
'Success' { $statusCode = [System.Net.HttpStatusCode]::OK }
'WinBGP not ready' { $statusCode = [System.Net.HttpStatusCode]::InternalServerError }
}
}
Default {
$statusCode = [System.Net.HttpStatusCode]::NotImplemented
}
}
}
'metrics' {
switch ($request.HttpMethod) {
'GET' {
# Define WinBGP Prometheus metrics
$WinBGP_metrics=@()
@@ -497,13 +547,87 @@ if ($Configuration) {
# Add header
$outputHeader.Add('Content-Type', 'text/plain; version=0.0.4; charset=utf-8')
$statusCode = [System.Net.HttpStatusCode]::OK
} else {
}
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
}
}
}
Default {
$statusCode = [System.Net.HttpStatusCode]::NotImplemented
}
}
}
# Add stop method to stop API (TO IMPROVE)
if ($FullPath -eq 'stop') {
'stop' {
switch ($request.HttpMethod) {
'POST' {
# Only local request are authorized
if ($request.IsLocal) {
$keepListening = $false
@@ -512,47 +636,10 @@ if ($Configuration) {
$statusCode = [System.Net.HttpStatusCode]::Forbidden
}
}
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
}
}
switch ($commandOutput.output) {
'Success' { $statusCode = [System.Net.HttpStatusCode]::OK }
'WinBGP not ready' { $statusCode = [System.Net.HttpStatusCode]::InternalServerError }
}
} else {
$statusCode = [System.Net.HttpStatusCode]::NotImplemented
}
}
Default {
$statusCode = [System.Net.HttpStatusCode]::NotImplemented