Public/Get-AzLocalFleetSettings.ps1
|
function Get-AzLocalFleetSettings { <# .SYNOPSIS Reads the optional fleet-wide pipeline settings file. .DESCRIPTION Reads config/fleet-settings.yml by default, or the path supplied by -Path or AZLOCAL_FLEET_SETTINGS_PATH. The file is optional. A missing, empty, or fully commented file returns the existing implicit Azure subscription scope used by earlier module versions. Schema version 1 supports scope.managementGroups. When one or more management-group IDs are configured, Azure Resource Graph queries that do not already specify an explicit subscription use those management groups as their query scope. The parser is deliberately limited to this small operator-owned schema so the core fleet pipelines do not require powershell-yaml. .PARAMETER Path Optional path to fleet-settings.yml. Defaults first to AZLOCAL_FLEET_SETTINGS_PATH, then to ./config/fleet-settings.yml. .OUTPUTS PSCustomObject with Path, FileFound, SchemaVersion, ScopeMode, and ManagementGroups properties. .EXAMPLE Get-AzLocalFleetSettings Reads the default config/fleet-settings.yml file. A fully commented starter returns ScopeMode 'ImplicitSubscriptions'. .EXAMPLE Get-AzLocalFleetSettings -Path C:\repo\config\fleet-settings.yml Reads an explicit settings file path. .NOTES Author: Neil Bird, Microsoft Module: AzLocal.UpdateManagement #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$Path ) if (-not $PSBoundParameters.ContainsKey('Path')) { if (-not [string]::IsNullOrWhiteSpace($env:AZLOCAL_FLEET_SETTINGS_PATH)) { $Path = $env:AZLOCAL_FLEET_SETTINGS_PATH } else { $Path = Join-Path -Path $PWD.Path -ChildPath 'config\fleet-settings.yml' } } $result = [PSCustomObject]@{ Path = [System.IO.Path]::GetFullPath($Path) FileFound = $false SchemaVersion = 1 ScopeMode = 'ImplicitSubscriptions' ManagementGroups = [string[]]@() MaxRowsPerTable = 100 MaxSummaryBytes = 900000 MaxIncidentsPerRun = 25 } if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { return $result } $result.FileFound = $true $lines = [System.IO.File]::ReadAllLines($result.Path, [System.Text.UTF8Encoding]::new($false)) $activeLines = @($lines | Where-Object { $trimmed = $_.Trim() $trimmed.Length -gt 0 -and -not $trimmed.StartsWith('#') }) if ($activeLines.Count -eq 0) { return $result } $schemaVersion = $null $inScope = $false $inManagementGroups = $false $activeSection = '' $managementGroups = [System.Collections.Generic.List[string]]::new() foreach ($line in $activeLines) { if ($line -match '^\s*schemaVersion\s*:\s*([0-9]+)\s*(?:#.*)?$') { $schemaVersion = [int]$Matches[1] continue } if ($line -match '^scope\s*:\s*(?:#.*)?$') { $activeSection = 'scope' $inScope = $true $inManagementGroups = $false continue } if ($line -match '^reporting\s*:\s*(?:#.*)?$') { $activeSection = 'reporting' $inScope = $false $inManagementGroups = $false continue } if ($line -match '^itsm\s*:\s*(?:#.*)?$') { $activeSection = 'itsm' $inScope = $false $inManagementGroups = $false continue } if ($line -match '^\S') { $activeSection = '' $inScope = $false $inManagementGroups = $false continue } if ($inScope -and $line -match '^\s{2}managementGroups\s*:\s*(?:#.*)?$') { $inManagementGroups = $true continue } if ($inScope -and $line -match '^\s{2}\S') { $inManagementGroups = $false continue } if ($inManagementGroups -and $line -match '^\s{4}-\s*([^#]+?)\s*(?:#.*)?$') { $managementGroupId = $Matches[1].Trim() if ($managementGroupId.Length -ge 2 -and (($managementGroupId.StartsWith("'") -and $managementGroupId.EndsWith("'")) -or ($managementGroupId.StartsWith('"') -and $managementGroupId.EndsWith('"')))) { $managementGroupId = $managementGroupId.Substring(1, $managementGroupId.Length - 2).Trim() } if (-not [string]::IsNullOrWhiteSpace($managementGroupId) -and -not $managementGroups.Contains($managementGroupId)) { [void]$managementGroups.Add($managementGroupId) } continue } if ($activeSection -eq 'reporting' -and $line -match '^\s{2}maxRowsPerTable\s*:\s*([0-9]+)\s*(?:#.*)?$') { $result.MaxRowsPerTable = [int]$Matches[1] continue } if ($activeSection -eq 'reporting' -and $line -match '^\s{2}maxSummaryBytes\s*:\s*([0-9]+)\s*(?:#.*)?$') { $result.MaxSummaryBytes = [int]$Matches[1] continue } if ($activeSection -eq 'itsm' -and $line -match '^\s{2}maxIncidentsPerRun\s*:\s*([0-9]+)\s*(?:#.*)?$') { $result.MaxIncidentsPerRun = [int]$Matches[1] continue } throw "Get-AzLocalFleetSettings: unsupported or malformed active YAML at '$($result.Path)': $($line.Trim())" } if ($null -eq $schemaVersion) { throw "Get-AzLocalFleetSettings: active settings in '$($result.Path)' must declare schemaVersion: 1." } if ($schemaVersion -ne 1) { throw "Get-AzLocalFleetSettings: unsupported schemaVersion '$schemaVersion' in '$($result.Path)'. This module supports schemaVersion 1." } if ($result.MaxRowsPerTable -lt 1 -or $result.MaxRowsPerTable -gt 1000) { throw "Get-AzLocalFleetSettings: reporting.maxRowsPerTable must be between 1 and 1000." } if ($result.MaxSummaryBytes -lt 10000 -or $result.MaxSummaryBytes -gt 1000000) { throw "Get-AzLocalFleetSettings: reporting.maxSummaryBytes must be between 10000 and 1000000." } if ($result.MaxIncidentsPerRun -lt 0 -or $result.MaxIncidentsPerRun -gt 1000) { throw "Get-AzLocalFleetSettings: itsm.maxIncidentsPerRun must be between 0 and 1000." } $result.SchemaVersion = $schemaVersion $result.ManagementGroups = $managementGroups.ToArray() if ($result.ManagementGroups.Count -gt 0) { $result.ScopeMode = 'ManagementGroups' } return $result } |