GuardiCore-config.psm1
function Compare-Labels { param ( [Parameter(Mandatory,Position = 0)] $JSON, [PSTypeName("GCApiKey")] $ApiKey, [switch] $PassThru ) if ( $ApiKey ) { $Key = $ApiKey } else { $Key = $Global:GCApiKey } $Test = try { Get-GCAsset -Raw -ApiKey $ApiKey } catch { if ( $_.Exception -match "403" ) { throw "Authentication error. Please check your API key." } } # Converts to a single string for ConvertFrom-Json if ( $JSON.gettype().BaseType -eq "System.Array" ) { $JSON = $JSON -join "`n" } $ShouldLabels = $JSON | ConvertFrom-Json Write-Host Label check $Results = foreach ( $Label in $ShouldLabels ) { $Result = [PSCustomObject]@{ Label = $Label.Key + ": " + $Label.Value Criteria = $true "Added assets" = $true Pass = $true } Write-Host $CurrentLabel = Get-GClabel -LabelKey $Label.key -LabelValue $Label.value Write-Host $Result.Label -NoNewLine if ( -not $CurrentLabel ) { Write-Host " does not exist" -ForegroundColor Red $Result.Pass = $false continue } else { Write-Host " exists" -ForegroundColor Green } $CriteriaCount = $Label.dynamic_criteria.count for ( $i = 0; $i -lt $CriteriaCount; $i++ ) { $Criteria = $Label.dynamic_criteria[$i] $ItDescription = "dynamic criteria '" + $Criteria.field.tolower() + " " + $Criteria.op.tolower() + " " + $Criteria.argument.tolower() + "': " Write-Host $ItDescription -NoNewLine $CurrentCriteria = $CurrentLabel.dynamic_criteria[$i] $Should = @($Criteria.field,$Criteria.op,$Criteria.argument) -join "," $Current = @($CurrentCriteria.field,$CurrentCriteria.op,$CurrentCriteria.argument) -join "," if ( $Current -eq $Should ) { Write-Host pass -ForegroundColor Green } else { Write-Host fail -ForegroundColor Red $Result.Pass = $false $Result."Dynamic Criteria" = $false } } $TempCount = Get-GCAsset -Label $CurrentLabel -Raw -ApiKey $ApiKey | Select-Object -ExpandProperty total_count if ($TempCount -eq 0) { Continue } $CurrentLabelAssets = Get-GCAsset -Label $CurrentLabel -Limit $TempCount -ApiKey $ApiKey $CurrentLabel.added_assets = foreach ( $Asset in $CurrentLabelAssets ) { $Token = $Key.token $AssetLabels = Invoke-RestMethod -Method Post -Uri ($Key.Uri + "/visibility/labels/assets") -Body (@{asset_ids = @($Asset.id)} | ConvertTo-Json) -ContentType application/json -Headers @{Authorization = "bearer $Token"} $AssetLabel = $AssetLabels | Where-Object {($_.key -eq $Label.key) -and ($_.value -eq $Label.value)} if ($AssetLabel.is_static -eq $true) { $Asset | Select-Object name,_id } } if ( $CurrentLabel.added_assets.count -eq 0 ) { $CurrentLabel.added_assets = @() } else { $CurrentLabel.added_assets = @($CurrentLabel.added_assets) } $AssetCount = $Label.added_assets.count $Assets = $Label.added_assets | Sort-Object -Property name $CurrentAssets = $CurrentLabel.added_assets | Sort-Object -Property name for ( $i = 0; $i -lt $AssetCount; $i++ ) { $Asset = $Assets[$i] $ItDescription = "manually added asset '" + $Asset.name + " (" + $Asset._id + ")': " Write-Host $ItDescription -NoNewLine $CurrentAsset = $CurrentAssets[$i] $CurrentAssetRemote = Get-GCAsset -Asset $CurrentAsset -ApiKey $ApiKey $Should = @($Asset.name,$Asset._id) -join "," $Current = @($CurrentAssetRemote.name,$CurrentAssetRemote._id) -join "," if ( $Current -eq $Should ) { Write-Host pass -ForegroundColor Green } else { Write-Host fail -ForegroundColor Red $Result.Pass = $false $Result."Added Assets" = $false } } $Result } if ( $PassThru ) { $Results } } function Compare-Policy { param ( [Parameter(Mandatory,Position = 0)] $JSON, [PSTypeName("GCApiKey")] $ApiKey, [switch] $PassThru ) $Test = try { Get-GCAsset -Raw -ApiKey $ApiKey } catch { if ( $_.Exception -match "403" ) { throw "Authentication error. Please check your API key." } } # Converts to a single string for ConvertFrom-Json if ( $JSON.gettype().BaseType -eq "System.Array" ) { $JSON = $JSON -join "`n" } $ShouldPolicy = $JSON | ConvertFrom-Json $Results = foreach ( $Policy in $ShouldPolicy ) { $CurrentPolicy = Get-GCPolicy -Comments $Policy.comments -Ruleset $Policy.ruleset_name -Section $Policy.section -ApiKey $ApiKey -Limit 1 if ( $CurrentPolicy ) { $CurrentJSON = $CurrentPolicy.published_version | Select-Object -ExcludeProperty *id $CurrentJSON | Add-Member -MemberType NoteProperty -Name section -Value $CurrentPolicy.section_position $CurrentJSON = $CurrentJSON | ConvertTo-Json -Depth 99 $CurrentJSON = Convert-LabelID -JSON $CurrentJSON -ApiKey $ApiKey $CurrentPolicy = $CurrentJSON | ConvertFrom-Json } $Result = [PSCustomObject]@{ Policy = ($CurrentPolicy.section + " | " + $CurrentPolicy.ruleset_name + " | " + $CurrentPolicy.comments) Source = $false Destination = $false Ports = $false Status = $false Action = $false Pass = $true } if ( $CurrentPolicy ) { Write-Host Write-Host $Result.Policy Write-Host "source: " -NoNewLine $Should = $Policy.source | ConvertTo-Json -Depth 99 $Current = $CurrentPolicy.source | ConvertTo-Json -Depth 99 if ( $Current -eq $Should ) { $Result.Source = $true Write-Host pass -ForeGroundColor Green } else { $Result.Pass = $false Write-host fail -ForeGroundColor Red } Write-Host "destination: " -NoNewLine $Should = $Policy.destination | ConvertTo-Json -Depth 99 $Current = $CurrentPolicy.destination | ConvertTo-Json -Depth 99 if ( $Current -eq $Should ) { $Result.Destination = $true Write-Host pass -ForeGroundColor Green } else { $Result.Pass = $false Write-host fail -ForeGroundColor Red } Write-Host "ports: " -NoNewLine $ShouldPorts = $Policy.ports | Sort-Object $ShouldExcludePorts = $Policy.exclude_ports | Sort-Object $Should = ` [string]$ShouldPorts, [string]$Policy.port_ranges.start, [string]$Policy.port_ranges.end, [string]$ShouldExcludePorts, [string]$Policy.exclude_port_ranges.start, [string]$Policy.exclude_port_ranges.end -join "," $CurrentPorts = $CurrentPolicy.ports | Sort-Object $CurrentExcludePorts = $CurrentPolicy.exclude_ports | Sort-Object $Current = ` [string]$CurrentPorts, [string]$CurrentPolicy.port_ranges.start, [string]$CurrentPolicy.port_ranges.end, [string]$CurrentExcludePorts, [string]$CurrentPolicy.exclude_port_ranges.start, [string]$CurrentPolicy.exclude_port_ranges.end -join "," if ( $Current -eq $Should ) { $Result.Ports = $true Write-Host pass -ForeGroundColor Green } else { $Result.Pass = $false Write-host fail -ForeGroundColor Red } Write-Host "status: " -NoNewLine $Should = $Policy.enabled $Current = $CurrentPolicy.enabled if ( $Current -eq $Should ) { $Result.Status = $true Write-Host pass -ForeGroundColor Green } else { $Result.Pass = $false Write-host fail -ForeGroundColor Red } Write-Host "action: " -NoNewLine $Should = $Policy.action $Current = $CurrentPolicy.action if ( $Current -eq $Should ) { $Result.Action = $true Write-Host pass -ForeGroundColor Green } else { $Result.Pass = $false Write-host fail -ForeGroundColor Red } } else { Write-Host $MissingPolicy = ($Policy.section + " | " + $Policy.ruleset_name + " | " + $Policy.comments) Write-Host $MissingPolicy Write-Host "policy doesn't exist" -ForeGroundColor Red $Result.Policy = $MissingPolicy $Result.Pass = $false } $Result } if ( $PassThru ) { $Results } } # Converts UUIDs of labels to a key:value string for UUID-agnostic configs # Importantly, this ignores asset IDs, as assets are still defined by ID function Convert-LabelID { param ( [Parameter(Mandatory,Position = 0)] $JSON, [PSTypeName("GCApiKey")] $ApiKey ) # The below loops expect an array as input; passing the whole string will make all the label names the same if ( $JSON.GetType().Name -eq "String" ) { $JSON = $JSON.Split("`n") } $LabelCount = Get-GCLabel -Raw -ApiKey $ApiKey | Select-Object -ExpandProperty total_count $Labels = Get-GCLabel -Limit $LabelCount -ApiKey $ApiKey $LabelTable = @{} foreach ( $Item in $Labels ) { $Name = $Item.key + ":" + $Item.value $LabelTable.Add($Item.id,$Name) } $Regex = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" $NewContent = foreach ($Item in $JSON) { if ( $Item -match $Regex ) { $ID = $matches[0] if ( $LabelTable.ContainsKey($ID) ) { $Item -replace ($Regex,$LabelTable[$ID]) } else { $Item } } else { $Item } } # Converts back to a string $NewContent -join "`n" } function Declare-Labels { param ( [string[]] $JSON, [PSTypeName("GCApiKey")] $ApiKey ) if ( $JSON.GetType().BaseName -eq "System.Array" ) { $JSON = $JSON -join "`n" } $Labels = $JSON | ConvertFrom-Json foreach ( $Label in $Labels ) { $CurrentLabel = Get-GCLabel -LabelKey $Label.key -LabelValue $Label.value -ApiKey $ApiKey if ( -not $CurrentLabel ) { New-GCBlankLabel -LabelKey $Label.key -LabelValue $Label.value -ApiKey $ApiKey $CurrentLabel = Get-GCLabel -LabelKey $Label.key -LabelValue $Label.value -ApiKey $ApiKey } $DynamicCriteria = $Label.dynamic_criteria $AddedAssets = $Label.added_assets # Get assets by id $Assets = foreach ($Asset in $AddedAssets) { Get-GCAsset -Asset $Asset._id -ApiKey $ApiKey } if ($DynamicCriteria) { $CurrentLabel | Add-Member -MemberType NoteProperty -Name criteria -Value $DynamicCriteria $CurrentLabel.dynamic_criteria += $DynamicCriteria } $CurrentLabel | Set-GCLabel if ($AddedAssets) { New-GCStaticLabel -LabelKey $Label.key -LabelValue $Label.value -Asset $Assets -ApiKey $ApiKey } } } function Declare-Policy { [cmdletbinding()] param ( [Parameter(Mandatory,Position = 0)] $JSON, [Parameter(Mandatory)] $Comments, [PSTypeName("GCApiKey")] $ApiKey ) $UnpublishedCount = Get-GCPolicy -State "CREATED","MODIFIED","DELETED" -ApiKey $ApiKey -Raw | Select-Object -ExpandProperty total_count if ( $UnpublishedCount -gt 0 ) { throw "Unpublished policies on management; aborting" } # Converting any JSON array input to a string if ( $JSON.GetType().BaseName -eq "System.Array" ) { $JSON = $JSON -join "`n" } $ConfigPolicy = $JSON | ConvertFrom-Json foreach ( $Policy in $ConfigPolicy ) { $CurrentPolicy = Get-GCPolicy -Section $Policy.section -Comments $Policy.comments -Ruleset $Policy.ruleset_name -ApiKey $ApiKey -Limit 1 if ( $Policy.source.labels ) { foreach ( $Group in $Policy.source.labels.or_labels ) { $ItemCount = $Group.and_labels.count for ( $i = 0; $i -lt $ItemCount; $i++ ) { $Key = $Group.and_labels[$i].Split(":")[0] $Value = $Group.and_labels[$i].Split(":")[1] $Label = Get-GCLabel -LabelKey $Key -LabelValue $Value -ApiKey $ApiKey if ( -not $Label ) { throw "Label mismatch; check labels in management" } $Group.and_labels[$i] = $Label | Select-Object key,value,name,id,color_index $Group.and_labels[$i].name = $Label.key + ": " + $Label.value } } } if ( $Policy.destination.labels ) { foreach ( $Group in $Policy.destination.labels.or_labels ) { $ItemCount = $Group.and_labels.count for ( $i = 0; $i -lt $ItemCount; $i++ ) { $Key = $Group.and_labels[$i].Split(":")[0] $Value = $Group.and_labels[$i].Split(":")[1] $Label = Get-GCLabel -LabelKey $Key -LabelValue $Value -ApiKey $ApiKey if ( -not $Label ) { throw "Label mismatch; check labels in management" } $Group.and_labels[$i] = $Label | Select-Object key,value,name,id,color_index $Group.and_labels[$i].name = $Label.key + ": " + $Label.value } } } if ( -not $CurrentPolicy ) { New-GCPolicy -Section allow -Action allow -Ruleset $Policy.ruleset_name -Comments $Policy.comments -ApiKey $ApiKey $CurrentPolicy = Get-GCPolicy -Comments $Policy.comments -Ruleset $Policy.ruleset_name -ApiKey $ApiKey } $CurrentPolicy.action = $Policy.action $CurrentPolicy.section_position = $Policy.section $CurrentPolicy.source = $Policy.source $CurrentPolicy.destination = $Policy.destination if ( $Policy.ports ) { $CurrentPolicy.ports = @($Policy.ports) } if ( $Policy.port_ranges ) { $CurrentPolicy.port_ranges = @($Policy.port_ranges) } if ( $Policy.exclude_ports ) { $CurrentPolicy.exclude_ports = @($Policy.exclude_ports) } if ( $Policy.exclude_port_ranges ) { $CurrentPolicy.exclude_port_ranges = @($Policy.exclude_port_ranges) } $CurrentPolicy.ruleset_name = $Policy.ruleset_name $CurrentPolicy.comments = $Policy.comments $CurrentPolicy.enabled = $Policy.enabled $CurrentPolicy | Set-GCPolicy -ApiKey $ApiKey } Publish-GCPolicy -ApiKey $ApiKey -Comments $Comments } function Pull-Labels { param ( [PSTypeName("GCApiKey")] $ApiKey ) if ( $ApiKey ) { $Key = $ApiKey } else { $Key = $Global:GCApiKey } $LabelCount = Get-GCLabel -ApiKey $ApiKey -Raw | Select-Object -ExpandProperty total_count $Labels = Get-GCLabel -ApiKey $ApiKey -Limit $LabelCount -DynamicCriteriaLimit 1000 # Filtering out vcenter labels because it breaks other stuff $Labels = $Labels | Where-Object {$_.key -notmatch "vCenter"} $ParsedLabels = foreach ( $Label in $Labels ) { $Label.dynamic_criteria = @($Label.dynamic_criteria | Select-Object -Property argument,field,op) $AssetCount = Get-GCAsset -Label $Label -Raw | Select-Object -ExpandProperty total_count $Assets = Get-GCAsset -Label $Label -Limit ($AssetCount+1) $Label.added_assets = foreach ( $Asset in $Assets ) { $AssetLabels = Invoke-RestMethod -Method Post -Uri ($Key.Uri + "/visibility/labels/assets") -Body (@{asset_ids = @($Asset.id)} | ConvertTo-Json) -ContentType application/json -Headers @{Authorization = "bearer $Key.token"} $AssetLabel = $AssetLabels | Where-Object {($_.key -eq $Label.key) -and ($_.value -eq $Label.value)} if ($AssetLabel.is_static -eq $true) { $Asset | Select-Object name,_id } } if ( $Label.added_assets.count -eq 0 ) { $Label.added_assets = @() } else { $Label.added_assets = @($Label.added_assets) } $Label | Select-Object key,value,added_assets,dynamic_criteria } $ParsedLabels | ConvertTo-Json -Depth 99 } function Pull-Policy { param ( [PSTypeName("GCApiKey")] $ApiKey ) try { $PolicyCount = Get-GCPolicy -Section "allow","alert","block","override_allow","override_alert","override_block" -Raw -ApiKey $ApiKey | Select-Object -ExpandProperty total_count $Policy = Get-GCPolicy -Section "allow","alert","block","override_allow","override_alert","override_block" -Limit $PolicyCount -ApiKey $ApiKey } catch { $PolicyCount = Get-GCPolicy -Section "allow","alert","block","override" -Raw -ApiKey $ApiKey | Select-Object -ExpandProperty total_count $Policy = Get-GCPolicy -Section "allow","alert","block","override" -Limit $PolicyCount -ApiKey $ApiKey } $PublishedPolicy = foreach ( $ThisPolicy in $Policy ) { $Output = $ThisPolicy.published_version | Select-Object -ExcludeProperty *id $Output | Add-Member -MemberType NoteProperty -Name section -Value $ThisPolicy.section_position $Output } $PolicyJson = $PublishedPolicy | ConvertTo-Json -Depth 99 Convert-LabelID -JSON $PolicyJson -ApiKey $ApiKey } Export-ModuleMember -Function Compare-Labels,Compare-Policy,Convert-LabelID,Declare-Labels,Declare-Policy,Pull-Labels,Pull-Policy |