tests/Test-WizardFindings.ps1
|
#Requires -Version 7 $ErrorActionPreference = 'Stop' . (Join-Path $PSScriptRoot '_TestHelpers.ps1') $wizardRoot = Split-Path $PSScriptRoot -Parent Import-Module (Join-Path $wizardRoot 'modules/IW.Core.psm1') -Force -Global Import-Module (Join-Path $wizardRoot 'modules/IW.Render.psm1') -Force -Global Import-Module (Join-Path $wizardRoot 'modules/ISC.OperatorConsole.psm1') -Force -Global -WarningAction SilentlyContinue $azure = Import-Module (Join-Path $wizardRoot 'modules/Definitions/Azure.Connector.psm1') -Force -PassThru $awsMod = Import-Module (Join-Path $wizardRoot 'modules/Definitions/Aws.Connector.psm1') -Force -PassThru $google = Import-Module (Join-Path $wizardRoot 'modules/Definitions/Google.Connector.psm1') -Force -PassThru Import-Module (Join-Path $wizardRoot 'modules/Definitions/Aws.Entro.psm1') -Force Register-IntegrationWizardPlatform -Name 'AWS' -Title 'AWS' -CoreOptions @('SaaSConnector', 'CiemConnector', 'Entro') -CliName 'aws' Register-IntegrationWizardPlatform -Name 'GoogleCloud' -Title 'Google Cloud' -CoreOptions @('SaaSConnector', 'CiemConnector') -CliName 'gcloud' Register-AwsConnectorDefinitions Register-AwsEntroDefinitions Register-GoogleConnectorDefinitions $readWrite = & $azure { Get-AzureLegacyArguments -Context @{ Access = 'ReadWrite' } } Assert-Equal 'Granular' $readWrite.PermissionMode 'ReadWrite defaults to Granular permissions' Assert-True (-not $readWrite.ContainsKey('Feature')) 'an omitted Entra feature list is not splatted as null' $directory = & $azure { Get-AzureLegacyArguments -Context @{ Access = 'ReadWrite'; PermissionMode = 'Directory' } } Assert-Equal 'Directory' $directory.PermissionMode 'explicit Directory mode is kept for ReadWrite' $readOnly = & $azure { Get-AzureLegacyArguments -Context @{ Access = 'ReadOnly'; PermissionMode = 'Directory' } } Assert-Equal 'Granular' $readOnly.PermissionMode 'ReadOnly stays on Granular permissions' $saasDef = Get-IntegrationWizardDefinition -Id 'aws-saas-connector' Assert-True (@($saasDef.Inputs.Name) -contains 'Feature') 'AWS SaaS definition collects feature packs' $packed = & $awsMod { Get-AwsLegacyArguments -SourceType 'AwsSaas' -Context @{ Feature = 'ActivityInsights,Ciem'; IscExternalId = 'ext' } } Assert-Equal 'ActivityInsights' @($packed.Feature)[0] 'comma-separated feature packs split' Assert-Equal 'Ciem' @($packed.Feature)[1] 'second feature pack is kept' Assert-Equal 2 @($packed.Feature).Count 'two feature packs are passed' $none = & $awsMod { Get-AwsLegacyArguments -SourceType 'AwsSaas' -Context @{ Feature = ''; IscExternalId = 'ext' } } Assert-True ($none.ContainsKey('Feature')) 'an answered empty feature list is explicit' Assert-Equal 0 @($none.Feature).Count 'an empty feature answer passes no packs' $omitted = & $awsMod { Get-AwsLegacyArguments -SourceType 'AwsSaas' -Context @{ IscExternalId = 'ext' } } Assert-True (-not $omitted.ContainsKey('Feature')) 'a missing feature list is left for the legacy prompt' Assert-True (-not $omitted.ContainsKey('Cloud')) 'an omitted cloud is left for the legacy prompt' $govCloud = & $awsMod { Get-AwsLegacyArguments -SourceType 'AwsSaas' -Context @{ IscExternalId = 'ext'; Cloud = 'GovCloud' } } Assert-Equal 'GovCloud' $govCloud.Cloud 'an explicit cloud is passed through' Assert-True (@($saasDef.Inputs.Name) -contains 'Cloud') 'AWS SaaS definition collects the AWS cloud' $ciemAwsDef = Get-IntegrationWizardDefinition -Id 'aws-ciem-connector' Assert-True (@($ciemAwsDef.Inputs.Name) -contains 'Cloud') 'AWS CIEM definition collects the AWS cloud' function Get-ScriptParameterSetNames { param([Parameter(Mandatory)][string]$Path, [Parameter(Mandatory)][string]$ParameterName) $tokens = $null $parseErrors = $null $ast = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$tokens, [ref]$parseErrors) if ($parseErrors) { throw "Failed to parse ${Path}: $($parseErrors[0].Message)" } $paramAst = @($ast.ParamBlock.Parameters | Where-Object { $_.Name.VariablePath.UserPath -eq $ParameterName }) if ($paramAst.Count -ne 1) { throw "Parameter $ParameterName was not found in $Path" } $sets = [System.Collections.Generic.List[string]]::new() foreach ($attr in $paramAst[0].Attributes) { if ($attr.TypeName.Name -ne 'Parameter') { continue } $setArg = @($attr.NamedArguments | Where-Object { $_.ArgumentName -eq 'ParameterSetName' }) if ($setArg.Count -eq 1) { $sets.Add([string]$setArg[0].Argument.Value) } } return $sets.ToArray() } $awsFeatureSets = @(Get-ScriptParameterSetNames -Path (Join-Path $wizardRoot 'AWS.ps1') -ParameterName 'Feature') Assert-True ($awsFeatureSets -contains 'SaaSConnector') 'AWS.ps1 accepts -Feature for the SaaS connector' $awsCloudSets = @(Get-ScriptParameterSetNames -Path (Join-Path $wizardRoot 'AWS.ps1') -ParameterName 'Cloud') Assert-True ($awsCloudSets -contains 'SaaSConnector') 'AWS.ps1 accepts -Cloud for the SaaS connector' Assert-True ($awsCloudSets -contains 'CiemConnector') 'AWS.ps1 accepts -Cloud for the CIEM connector' $ciemDef = Get-IntegrationWizardDefinition -Id 'google-ciem-connector' Assert-True (@($ciemDef.Inputs.Name) -contains 'ImpersonateUser') 'GCP CIEM collects the impersonated admin' $missingImpersonation = Test-IntegrationWizardRequiredInputs -Definition $ciemDef -Context @{ OrganizationId = '1'; ProjectId = 'p' } Assert-True ($missingImpersonation -contains 'ImpersonateUser') 'GCP CIEM requires ImpersonateUser' $ciemArgs = & $google { Get-GoogleLegacyArguments -Mode 'Ciem' -Context @{ Feature = 'NhiDiscovery,AgentDiscovery'; ImpersonateUser = 'admin@contoso.com' } } Assert-Equal 'Gcp' @($ciemArgs.Feature)[0] 'CIEM mode enables the Gcp pack' Assert-Equal 'Ciem' @($ciemArgs.Feature)[1] 'CIEM mode enables the Ciem pack' Assert-Equal 'NhiDiscovery' @($ciemArgs.Feature)[2] 'CIEM mode keeps the first extra pack' Assert-Equal 'AgentDiscovery' @($ciemArgs.Feature)[3] 'CIEM mode keeps the second extra pack' Assert-Equal 'admin@contoso.com' $ciemArgs.ImpersonateUser 'CIEM mode passes ImpersonateUser' $saasArgs = & $google { Get-GoogleLegacyArguments -Mode 'Saas' -Context @{ ImpersonateUser = 'admin@contoso.com' } } Assert-True (-not $saasArgs.ContainsKey('Feature')) 'SaaS mode does not force CIEM packs' $googlePath = Join-Path $wizardRoot 'Google Cloud.ps1' $googleImpersonateSets = @(Get-ScriptParameterSetNames -Path $googlePath -ParameterName 'ImpersonateUser') Assert-True ($googleImpersonateSets -contains 'CiemConnector') 'Google Cloud.ps1 accepts -ImpersonateUser for CIEM' $googleFeatureSets = @(Get-ScriptParameterSetNames -Path $googlePath -ParameterName 'Feature') Assert-True ($googleFeatureSets -contains 'CiemConnector') 'Google Cloud.ps1 accepts -Feature for CIEM' $render = Get-Module -Name 'IW.Render' & $render { function script:Get-IntegrationWizardCliSession { param([Parameter(Mandatory)][string]$CliName) return @{ SignedIn = $false; Installed = $false } } function script:Install-IntegrationWizardCli { param([Parameter(Mandatory)][string]$CliName, [switch]$NonInteractive) $global:IwInstallCount++ } function script:Invoke-IntegrationWizardCliLogin { param([Parameter(Mandatory)][string]$CliName, [switch]$NonInteractive) $global:IwLoginCount++ } } $runDef = @{ CliName = 'aws'; Title = 'test'; Steps = { param($ctx) ,@() } } $global:IwInstallCount = 0 $global:IwLoginCount = 0 Invoke-IntegrationWizardRun -Definition $runDef -Context @{ ConnectionMode = 'NoSession'; NonInteractive = $true } Assert-Equal 0 $global:IwInstallCount 'NoSession does not install the CLI' Assert-Equal 0 $global:IwLoginCount 'NoSession does not sign in' Invoke-IntegrationWizardRun -Definition $runDef -Context @{ ConnectionMode = 'UseSession'; NonInteractive = $true } Assert-Equal 1 $global:IwInstallCount 'a missing session installs the CLI' Assert-Equal 1 $global:IwLoginCount 'a missing session signs in' Assert-Equal 'Entro-ext-id-123' (Get-EntroAwsCloudFormationStackName -ExternalId 'ext id/123') 'stack name keeps only stack-safe characters' Assert-Equal 'Skip' (Get-EntroAwsCloudFormationProbeResult -StackStatus 'CREATE_COMPLETE') 'a completed stack is unchanged' Assert-Equal 'Create' (Get-EntroAwsCloudFormationProbeResult -StackStatus '') 'a missing stack is created' Assert-Equal 'Update' (Get-EntroAwsCloudFormationProbeResult -StackStatus 'ROLLBACK_COMPLETE') 'a failed stack is deployed again' Assert-Equal 'Skip' (Get-EntroAwsCloudFormationProbeResult -StackStatus 'CREATE_IN_PROGRESS') 'an in-progress stack is left alone' $script:AwsCalls = @() $script:StackStatus = $null function global:Invoke-MockAwsCli { [CmdletBinding()] param([Parameter(ValueFromRemainingArguments = $true)][string[]]$AwsCliArgs) $line = $AwsCliArgs -join ' ' $script:AwsCalls += $line if ($line -match 'describe-stacks') { if ($script:StackStatus) { $global:LASTEXITCODE = 0 return $script:StackStatus } $global:LASTEXITCODE = 254 return '' } if ($line -match 'get-role') { $global:LASTEXITCODE = 0 return 'exists' } $global:LASTEXITCODE = 0 return '' } Set-Alias -Name aws -Value Invoke-MockAwsCli -Scope Global -Force $entro = Get-IntegrationWizardDefinition -Id 'aws-entro' $cfCtx = @{ EntroExternalId = 'ext-id-123'; Method = 'CloudFormation'; EntroRoleName = 'EntroReadOnly' Region = 'eu-west-1'; EntroTemplateRegion = 'Default'; OutputDirectory = (Get-Location).Path } $cfSteps = & $entro.Steps $cfCtx $trust = @($cfSteps | Where-Object { $_.Id -eq 'entro-trust' })[0] Assert-Equal 'Create' (& $trust.Probe $cfCtx) 'CloudFormation is not skipped just because the IAM role exists' Assert-True (@($script:AwsCalls | Where-Object { $_ -match 'describe-stacks' -and $_ -match 'Entro-ext-id-123' -and $_ -match 'eu-west-1' }).Count -ge 1) 'CloudFormation probe checks the stack in the selected region' $script:StackStatus = 'CREATE_COMPLETE' Assert-Equal 'Skip' (& $trust.Probe $cfCtx) 'CloudFormation skips when that stack is already complete' $assumeCtx = @{ EntroExternalId = 'ext-id-123'; Method = 'AssumeRole'; EntroRoleName = 'EntroReadOnly' } $assumeSteps = & $entro.Steps $assumeCtx $assumeTrust = @($assumeSteps | Where-Object { $_.Id -eq 'entro-trust' })[0] Assert-Equal 'Skip' (& $assumeTrust.Probe $assumeCtx) 'AssumeRole still skips when the role exists' $script:AwsCalls = @() $script:StackStatus = $null & $trust.Run $cfCtx Assert-True (@($script:AwsCalls | Where-Object { $_ -match 'cloudformation deploy' -and $_ -match 'Entro-ext-id-123' -and $_ -match 'eu-west-1' }).Count -ge 1) 'CloudFormation deploy uses the stable stack name and region' Write-Host "PASS ($script:AssertionCount assertions)" |