Build-LMFilterValidationConfig.ps1
|
<# .SYNOPSIS Development tool to generate filter field validation configuration from swagger YAML. .DESCRIPTION This script parses the logicmonitor-api.yaml file to extract all API endpoints and their response schemas. It then maps each endpoint to the properties available in the response model, creating a validation configuration file that can be used at runtime to validate filter fields before sending API requests. .EXAMPLE .\Build-LMFilterValidationConfig.ps1 This will generate Private/LMFilterValidationConfig.psd1 with all endpoint-to-fields mappings. .NOTES This is a development-time tool and should be run whenever the swagger file is updated. Requires the powershell-yaml module for parsing YAML files. #> [CmdletBinding()] param() # Check if powershell-yaml module is available if (-not (Get-Module -ListAvailable -Name powershell-yaml)) { Write-Warning "The powershell-yaml module is required to parse the swagger YAML file." Write-Warning "Install it with: Install-Module -Name powershell-yaml" Write-Warning "Attempting to install now..." try { Install-Module -Name powershell-yaml -Scope CurrentUser -Force -AllowClobber Write-Host "Successfully installed powershell-yaml module" -ForegroundColor Green } catch { Write-Error "Failed to install powershell-yaml module. Please install it manually." return } } Import-Module powershell-yaml $SwaggerPath = Join-Path $PSScriptRoot "logicmonitor-api.yaml" $OutputPath = Join-Path $PSScriptRoot "Private/LMFilterValidationConfig.psd1" if (-not (Test-Path $SwaggerPath)) { Write-Error "Swagger file not found at: $SwaggerPath" return } Write-Host "Parsing swagger file: $SwaggerPath" -ForegroundColor Cyan # Parse the YAML file $SwaggerContent = Get-Content -Path $SwaggerPath -Raw $Swagger = ConvertFrom-Yaml -Yaml $SwaggerContent Write-Host "Extracting API endpoints and schemas..." -ForegroundColor Cyan # Build endpoint to schema mapping $EndpointToSchema = @{} $SchemaProperties = @{} # First, extract all schema properties foreach ($schemaName in $Swagger.components.schemas.Keys) { $schema = $Swagger.components.schemas[$schemaName] $properties = @() if ($schema.properties) { $properties += $schema.properties.Keys } # Handle allOf (inheritance) if ($schema.allOf) { foreach ($allOfItem in $schema.allOf) { if ($allOfItem.properties) { $properties += $allOfItem.properties.Keys } # Handle $ref in allOf if ($allOfItem.'$ref') { $refSchema = $allOfItem.'$ref' -replace '#/components/schemas/', '' # We'll resolve these in a second pass } } } if ($properties.Count -gt 0) { $SchemaProperties[$schemaName] = $properties | Sort-Object -Unique } } Write-Host "Found $($SchemaProperties.Count) schemas with properties" -ForegroundColor Green # Now map endpoints to their response schemas foreach ($path in $Swagger.paths.Keys) { $pathItem = $Swagger.paths[$path] # We're primarily interested in GET endpoints for filtering if ($pathItem.get) { $getOp = $pathItem.get # Check if it has a filter parameter $hasFilter = $false if ($getOp.parameters) { foreach ($param in $getOp.parameters) { if ($param.name -eq 'filter') { $hasFilter = $true break } } } if ($hasFilter) { # Extract the response schema if ($getOp.responses.'200'.content.'application/json'.schema.'$ref') { $responseSchemaRef = $getOp.responses.'200'.content.'application/json'.schema.'$ref' $responseSchemaName = $responseSchemaRef -replace '#/components/schemas/', '' # For pagination responses, we need to get the items schema if ($responseSchemaName -match 'PaginationResponse$') { $paginationSchema = $Swagger.components.schemas[$responseSchemaName] if ($paginationSchema.properties.items.items.'$ref') { $itemsSchemaRef = $paginationSchema.properties.items.items.'$ref' $itemsSchemaName = $itemsSchemaRef -replace '#/components/schemas/', '' if ($SchemaProperties[$itemsSchemaName]) { $EndpointToSchema[$path] = @{ Schema = $itemsSchemaName Properties = $SchemaProperties[$itemsSchemaName] } } } } # For non-pagination responses, use the schema directly elseif ($SchemaProperties[$responseSchemaName]) { $EndpointToSchema[$path] = @{ Schema = $responseSchemaName Properties = $SchemaProperties[$responseSchemaName] } } } } } } Write-Host "Mapped $($EndpointToSchema.Count) endpoints to schemas" -ForegroundColor Green # Build the final configuration hashtable $Config = @{} foreach ($endpoint in $EndpointToSchema.Keys | Sort-Object) { $properties = $EndpointToSchema[$endpoint].Properties $schema = $EndpointToSchema[$endpoint].Schema # Only include properties that actually exist in the schema # Don't add special properties if they're not defined in the API $Config[$endpoint] = $properties | Sort-Object -Unique Write-Verbose "Endpoint: $endpoint -> Schema: $schema -> Properties: $($properties.Count)" } # Generate the PSD1 file Write-Host "Generating configuration file: $OutputPath" -ForegroundColor Cyan $PSD1Content = @" <# .SYNOPSIS Filter field validation configuration generated from logicmonitor-api.yaml .DESCRIPTION This file contains a mapping of API endpoints to their valid filterable fields. It is automatically generated by Build-LMFilterValidationConfig.ps1 and should not be manually edited. Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') Swagger endpoints processed: $($EndpointToSchema.Count) .NOTES To regenerate this file, run: .\Build-LMFilterValidationConfig.ps1 #> @{ "@ foreach ($endpoint in $Config.Keys | Sort-Object) { $properties = $Config[$endpoint] $propertiesString = ($properties | ForEach-Object { "'$_'" }) -join ', ' $PSD1Content += "`n '$endpoint' = @($propertiesString)" } $PSD1Content += "`n}`n" # Write the file Set-Content -Path $OutputPath -Value $PSD1Content -Encoding UTF8 Write-Host "Successfully generated configuration file!" -ForegroundColor Green Write-Host " Endpoints: $($Config.Keys.Count)" -ForegroundColor Green Write-Host " Output: $OutputPath" -ForegroundColor Green # Display some sample mappings Write-Host "`nSample mappings:" -ForegroundColor Cyan $sampleEndpoints = @('/device/devices', '/device/groups', '/alert/alerts') | Where-Object { $Config[$_] } foreach ($endpoint in $sampleEndpoints) { Write-Host " $endpoint" -ForegroundColor Yellow Write-Host " Fields: $($Config[$endpoint] -join ', ')" -ForegroundColor Gray } |