Functions/Private/Test-AffinityCompliance.ps1
|
function Test-AffinityCompliance { <# .SYNOPSIS Checks the current cluster placement against all configured affinity rules and returns a list of violations. .OUTPUTS Array of PSCustomObjects: RuleId, RuleName, Type, Enforced, VMs, Description. VMs contains the names of the VMs directly involved in this specific violation. #> [CmdletBinding()] param( [Parameter(Mandatory)] [PSCustomObject] $Snapshot, [PSCustomObject[]] $RuleSet ) if (-not $RuleSet -or $RuleSet.Count -eq 0) { return @() } $vmHost = @{} foreach ($vm in $Snapshot.VMs) { $vmHost[$vm.VMName] = $vm.HostNode } $violations = [System.Collections.Generic.List[PSCustomObject]]::new() foreach ($rule in $RuleSet) { $activeVMs = @($rule.VMs | Where-Object { $vmHost.ContainsKey($_) }) if ($activeVMs.Count -eq 0) { continue } switch ($rule.Type) { 'VmVmAffinity' { $hostGroups = @($activeVMs | Group-Object { $vmHost[$_] }) if ($hostGroups.Count -gt 1) { $hostList = $hostGroups | Select-Object -ExpandProperty Name $violations.Add([PSCustomObject]@{ RuleId = $rule.RuleId RuleName = $rule.Name Type = $rule.Type Enforced = $rule.Enforced VMs = $activeVMs Description = "Affinity group '$($rule.Name)' is spread across $($hostGroups.Count) host(s): $($hostList -join ', ')" }) } } 'VmVmAntiAffinity' { $conflicts = @($activeVMs | Group-Object { $vmHost[$_] } | Where-Object { $_.Count -gt 1 }) foreach ($conflict in $conflicts) { $violations.Add([PSCustomObject]@{ RuleId = $rule.RuleId RuleName = $rule.Name Type = $rule.Type Enforced = $rule.Enforced VMs = @($conflict.Group) Description = "Anti-affinity rule '$($rule.Name)': '$($conflict.Group -join "', '")' co-located on '$($conflict.Name)'" }) } } 'VmHostAffinity' { foreach ($vm in $activeVMs) { if ($rule.Hosts -notcontains $vmHost[$vm]) { $violations.Add([PSCustomObject]@{ RuleId = $rule.RuleId RuleName = $rule.Name Type = $rule.Type Enforced = $rule.Enforced VMs = @($vm) Description = "Host-affinity rule '$($rule.Name)': '$vm' is on '$($vmHost[$vm])' — allowed: [$($rule.Hosts -join ', ')]" }) } } } 'VmHostAntiAffinity' { foreach ($vm in $activeVMs) { if ($rule.Hosts -contains $vmHost[$vm]) { $violations.Add([PSCustomObject]@{ RuleId = $rule.RuleId RuleName = $rule.Name Type = $rule.Type Enforced = $rule.Enforced VMs = @($vm) Description = "Host-anti-affinity rule '$($rule.Name)': '$vm' is on excluded host '$($vmHost[$vm])'" }) } } } } } return $violations.ToArray() } |