Skip to content

Commit

Permalink
Merge pull request #24 from nekrassov01/feature#23
Browse files Browse the repository at this point in the history
Fix 'Invoke-PasmCleanUp' (#23), and trim whitespaces
  • Loading branch information
nekrassov01 authored Nov 21, 2021
2 parents 0dfa0d5 + 2c36f73 commit 41c3739
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 61 deletions.
10 changes: 5 additions & 5 deletions src/Functions/Helpers/Helpers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function Test-PasmRequiredKey {
[string]$Enum = 'Pasm.RequiredParameter.Parent'
)
$member = [enum]::GetNames($enum)
$label =
$label =
if ($enum -eq 'Pasm.RequiredParameter.Parent') {
'top-level'
}
Expand All @@ -78,7 +78,7 @@ function Test-PasmInvalidKey {
[string]$Enum = 'Pasm.Parameter.Parent'
)
$member = [enum]::GetNames($enum)
$label =
$label =
if ($enum -eq 'Pasm.Parameter.Parent') {
'top-level'
}
Expand Down Expand Up @@ -360,7 +360,7 @@ function New-PasmSecurityGroupEntry {
$ipPermission.IpProtocol = $r.Protocol
$ipPermission.FromPort = $r.FromPort
$ipPermission.ToPort = $r.ToPort

if ($r.Protocol -in 'icmp', 'icmpv6') {
$ipPermission.FromPort = '-1'
$ipPermission.ToPort = '-1'
Expand All @@ -371,13 +371,13 @@ function New-PasmSecurityGroupEntry {
$ipv4Range = [IpRange]::new()
$ipv4Range.CidrIp = $range.IpPrefix
$ipv4Range.Description = $range.Description
$ipPermission.Ipv4Ranges.Add($ipv4Range)
$ipPermission.Ipv4Ranges.Add($ipv4Range)
}
if ($range.IpFormat -eq 'IPv6') {
$ipv6Range = [Ipv6Range]::new()
$ipv6Range.CidrIpv6 = $range.IpPrefix
$ipv6Range.Description = $range.Description
$ipPermission.Ipv6Ranges.Add($ipv6Range)
$ipPermission.Ipv6Ranges.Add($ipv6Range)
}
}
$ipPermissions.Add($ipPermission)
Expand Down
4 changes: 2 additions & 2 deletions src/Functions/Invoke-PasmAutomation.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function Invoke-PasmAutomation {
[Alias('file')]
[ValidateNotNullOrEmpty()]
[string[]]$FilePath = $($PWD, $('{0}.yml' -f [Pasm.Template.Name]::outline) -join [path]::DirectorySeparatorChar),

# Specify the output file name.
[Parameter(Mandatory = $false)]
[Alias('out')]
Expand Down Expand Up @@ -49,7 +49,7 @@ function Invoke-PasmAutomation {
.DESCRIPTION
Run the following in order: Invoke-PasmValidation, Invoke-PasmBlueprint, Invoke-PasmDeproyment.
See the following source for details: https://github.com/nekrassov01/Pasm/blob/main/src/Functions/Invoke-PasmAutomation.ps1
.EXAMPLE
# Default input file path: ${PWD}/outline.yml, default output file name: 'blueprint.yml'
Invoke-PasmAutomation
Expand Down
28 changes: 14 additions & 14 deletions src/Functions/Invoke-PasmBlueprint.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function Invoke-PasmBlueprint {
if ($update) {
$dest = Import-PasmFile -FilePath $outputFilePath -Ordered
}

# Create metadata section
$metadata = [ordered]@{}
$metadata.UpdateNumber = if ($update) { [int]$dest.Metadata.UpdateNumber + 1 } else { 1 }
Expand All @@ -78,7 +78,7 @@ function Invoke-PasmBlueprint {
if ($resource.Contains('SecurityGroup')) { $securityGroup = $obj.Resource.SecurityGroup }
if ($resource.Contains('NetworkAcl')) { $networkAcl = $obj.Resource.NetworkAcl }
if ($resource.Contains('PrefixList')) { $prefixList = $obj.Resource.PrefixList }

# Create outer container
$parent = [ordered]@{}
$parent.Common = $obj.Common
Expand Down Expand Up @@ -122,10 +122,10 @@ function Invoke-PasmBlueprint {
$range.IpFormat = $r.IpAddressFormat
$range.Region = $r.Region
$range.Description = 'Service:{0} Region:{1} Published:{2} Created:{3} Updated:{4}' -f (
$rule.ServiceKey,
$r.Region,
$published.ToString($datetimeFormat),
$(if ($update) { ([datetime]$dest.Metadata.CreatedAt).ToUniversalTime().ToString($datetimeFormat) } else { $now.ToString($datetimeFormat) }),
$rule.ServiceKey,
$r.Region,
$published.ToString($datetimeFormat),
$(if ($update) { ([datetime]$dest.Metadata.CreatedAt).ToUniversalTime().ToString($datetimeFormat) } else { $now.ToString($datetimeFormat) }),
$now.ToString($datetimeFormat)
)
$sgRangesContainer.Add($range)
Expand Down Expand Up @@ -157,7 +157,7 @@ function Invoke-PasmBlueprint {
# Multiple resource definitions are allowed, so process them one by one
foreach ($nacl in $networkAcl) {
$naclRulesContainer = [list[object]]::new()

$obj = [ordered]@{}
$obj.ResourceName = $nacl.ResourceName
$obj.ResourceId = if ($update) { $dest.Resource.NetworkAcl.ResourceId } else { 'not-deployed' }
Expand Down Expand Up @@ -214,7 +214,7 @@ function Invoke-PasmBlueprint {
Test-PasmMaxEntry -Entry $obj.IPv6Entry -MaxEntry $obj.MaxEntry -IpFormat 'IPv6' -ResourceType 'NetworkAcl'

$naclContainer.Add($obj)
}
}
$parent.Resource.NetworkAcl = $naclContainer
}

Expand Down Expand Up @@ -252,10 +252,10 @@ function Invoke-PasmBlueprint {
$range.IpFormat = $r.IpAddressFormat
$range.Region = $r.Region
$range.Description = 'Service:{0} Region:{1} Published:{2} Created:{3} Updated:{4}' -f (
$rule.ServiceKey,
$r.Region,
$published.ToString($datetimeFormat),
$(if ($update) { ([datetime]$dest.Metadata.CreatedAt).ToUniversalTime().ToString($datetimeFormat) } else { $now.ToString($datetimeFormat) }),
$rule.ServiceKey,
$r.Region,
$published.ToString($datetimeFormat),
$(if ($update) { ([datetime]$dest.Metadata.CreatedAt).ToUniversalTime().ToString($datetimeFormat) } else { $now.ToString($datetimeFormat) }),
$now.ToString($datetimeFormat)
)
$plRangesContainer.Add($range)
Expand All @@ -275,7 +275,7 @@ function Invoke-PasmBlueprint {
Test-PasmMaxEntry -Entry $obj.IPv6Entry -MaxEntry $obj.MaxEntry -IpFormat 'IPv6' -ResourceType 'PrefixList'

$plContainer.Add($obj)
}
}
$parent.Resource.PrefixList = $plContainer
}

Expand Down Expand Up @@ -305,7 +305,7 @@ function Invoke-PasmBlueprint {
.DESCRIPTION
Get the ip ranges from 'ip-ranges.json' as described in the Yaml template, and create a blueprint.
See the following source for details: https://github.com/nekrassov01/Pasm/blob/main/src/Functions/Invoke-PasmBlueprint.ps1
.EXAMPLE
# Default input file path: ${PWD}/outline.yml, default output file name: 'blueprint.yml'
Invoke-PasmBlueprint
Expand Down
58 changes: 45 additions & 13 deletions src/Functions/Invoke-PasmCleanUp.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ function Invoke-PasmCleanUp {
[Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[Alias('file')]
[ValidateNotNullOrEmpty()]
[string[]]$FilePath = $($PWD, $('{0}.yml' -f [Pasm.Template.Name]::blueprint) -join [path]::DirectorySeparatorChar)
[string[]]$FilePath = $($PWD, $('{0}.yml' -f [Pasm.Template.Name]::blueprint) -join [path]::DirectorySeparatorChar),

# If the ResourceName matches even if the ResourceId does not, cleanup is performed.
[Parameter(Mandatory = $false)]
[switch]$Force
)

begin {
Expand All @@ -32,17 +36,17 @@ function Invoke-PasmCleanUp {
foreach ($file in $filePath) {
# Load blueprint file
$obj = Import-PasmFile -FilePath $file -Ordered

# Rresource variables
$resource = $obj.Resource
if ($resource.Contains('SecurityGroup')) { $securityGroup = $obj.Resource.SecurityGroup }
if ($resource.Contains('NetworkAcl')) { $networkAcl = $obj.Resource.NetworkAcl }
if ($resource.Contains('PrefixList')) { $prefixList = $obj.Resource.PrefixList }

# Set AWS default settings for this session
Set-AWSCredential -ProfileName $obj.Common.ProfileName -Scope Local
Set-DefaultAWSRegion -Region $obj.Common.Region -Scope Local

# Create result object list
$ret = [list[PSCustomObject]]::new()

Expand All @@ -51,12 +55,20 @@ function Invoke-PasmCleanUp {
if ($resource.Contains('SecurityGroup')) {
foreach ($sg in $securityGroup) {
$target = Get-EC2SecurityGroup -Filter @{ Name = 'group-id'; Values = $sg.ResourceId }

if ($PSBoundParameters.ContainsKey('Force')) {
$evidence = Get-EC2SecurityGroup -Filter @{ Name = 'group-name'; Values = $sg.ResourceName }
if ($null -eq $target -and $null -ne $evidence) {
$target = $evidence
}
}

if ($null -ne $target) {
$groupList = [list[string]]::new()
$detachedList = [list[string]]::new()
$remainingList = [list[string]]::new()
$action = 'CleanUp'

# Get the ENI to which the target security group is attached
$eni = Get-EC2NetworkInterface -Filter @{ Name = 'group-id'; Values = $target.GroupId }
if ($eni) {
Expand All @@ -83,6 +95,7 @@ function Invoke-PasmCleanUp {
}
}
}

if ((!$eni) -or ($eni -and $eni.RequesterManaged -notcontains $true)) {
Remove-EC2SecurityGroup -GroupId $target.GroupId -Confirm:$false | Out-Null
$sg.ResourceId = 'cleaned'
Expand All @@ -98,7 +111,6 @@ function Invoke-PasmCleanUp {
Action = $action
}
)

}
}
}
Expand All @@ -108,6 +120,14 @@ function Invoke-PasmCleanUp {
if ($resource.Contains('NetworkAcl')) {
foreach ($nacl in $networkAcl) {
$target = Get-EC2NetworkAcl -Filter @{ Name = 'network-acl-id'; Values = $nacl.ResourceId }

if ($PSBoundParameters.ContainsKey('Force')) {
$evidence = Get-EC2NetworkAcl -Filter @{ Name = 'tag:Name'; Values = $nacl.ResourceName }
if ($null -eq $target -and $null -ne $evidence) {
$target = $evidence
}
}

if ($null -ne $target) {
$subnetList = [list[string]]::new()
$naclAssocs = $target.Associations
Expand Down Expand Up @@ -140,10 +160,18 @@ function Invoke-PasmCleanUp {
if ($resource.Contains('PrefixList')) {
foreach ($pl in $prefixList) {
$target = Get-EC2ManagedPrefixList -Filter @{ Name = 'prefix-list-id'; Values = $pl.ResourceId }

if ($PSBoundParameters.ContainsKey('Force')) {
$evidence = Get-EC2ManagedPrefixList -Filter @{ Name = 'prefix-list-name'; Values = $pl.ResourceName }
if ($null -eq $target -and $null -ne $evidence) {
$target = $evidence
}
}

if ($null -ne $target) {
$resourceList = [list[string]]::new()
$plAssocs = Get-EC2ManagedPrefixListAssociation -PrefixListId $target.PrefixListId
if ($plAssocs) {
if ($plAssocs) {
foreach ($plAssoc in $plAssocs) {
if ($plAssoc.ResourceId -match '^sg-[0-9a-z]{17}$') {
$targetSg = Get-EC2SecurityGroup -Filter @{ Name = 'group-id'; Values = $plAssoc.ResourceId }
Expand All @@ -170,7 +198,7 @@ function Invoke-PasmCleanUp {
}
}
}
Remove-EC2ManagedPrefixList -PrefixListId $pl.ResourceId -Confirm:$false | Out-Null
Remove-EC2ManagedPrefixList -PrefixListId $target.PrefixListId -Confirm:$false | Out-Null
$pl.ResourceId = 'cleaned'

$ret.Add(
Expand All @@ -186,7 +214,7 @@ function Invoke-PasmCleanUp {
}
}
}

# Update metadata section
if ($obj.Contains('MetaData')) {
$metadata = [ordered]@{}
Expand All @@ -200,13 +228,13 @@ function Invoke-PasmCleanUp {
$metadata.CleandAt = [datetime]::Now.ToUniversalTime()
$obj.MetaData = $metadata
}

# Convert the object to Yaml format and overwrite the file
$obj | ConvertTo-Yaml -OutFile $file -Force

# Return result list
$PSCmdlet.WriteObject($ret)

# Clear AWS default settings for this session
Clear-AWSDefaultConfiguration -SkipProfileStore
}
Expand All @@ -226,7 +254,7 @@ function Invoke-PasmCleanUp {
.DESCRIPTION
Clean up the deployed resources. Force detach of associated resources. Skip requester-managed ENIs, as they cannot be detached.
See the following source for details: https://github.com/nekrassov01/Pasm/blob/main/src/Functions/Invoke-PasmCleanUp.ps1
.EXAMPLE
# Default input file path: ${PWD}/blueprint.yml
Invoke-PasmCleanUp
Expand All @@ -239,6 +267,10 @@ function Invoke-PasmCleanUp {
# Loading multiple files from pipeline
'C:/Pasm/blueprint-sg.yml', 'C:/Pasm/blueprint-nacl.yml', 'C:/Pasm/blueprint-pl.yml' | Invoke-PasmCleanUp
.EXAMPLE
# When the Force switch is enabled, even if the ResourceId does not match, if the ResourceName matches, cleanup will be performed
Invoke-PasmCleanUp -Force
.LINK
https://github.com/nekrassov01/Pasm
#>
Expand Down
20 changes: 10 additions & 10 deletions src/Functions/Invoke-PasmDeployment.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function Invoke-PasmDeployment {
$sg.ResourceId = $target.GroupId

# Add an object to the result list
$ret.Add(
$ret.Add(
[PSCustomObject]@{
ResourceType = [Pasm.Parameter.Resource]::SecurityGroup
ResourceName = $target.GroupName
Expand Down Expand Up @@ -129,7 +129,7 @@ function Invoke-PasmDeployment {
$tags = @{ Key = 'Name'; Value = $nacl.ResourceName }
$nameTag = [TagSpecification]::new()
$nameTag.ResourceType = 'network-acl'
$nameTag.Tags.Add($tags)
$nameTag.Tags.Add($tags)

$target = New-EC2NetworkAcl -VpcId $nacl.VpcId -TagSpecification $nameTag

Expand Down Expand Up @@ -170,7 +170,7 @@ function Invoke-PasmDeployment {
}

# Add entries to the network acl
New-PasmNetworkAclEntry $nacl -NetworkAcl $target
New-PasmNetworkAclEntry $nacl -NetworkAcl $target

# Overwrite ResourceId
$nacl.ResourceId = $target.NetworkAclId
Expand Down Expand Up @@ -200,7 +200,7 @@ function Invoke-PasmDeployment {
$tags = @{ Key = 'Name'; Value = $pl.ResourceName }
$nameTag = [TagSpecification]::new()
$nameTag.ResourceType = 'prefix-list'
$nameTag.Tags.Add($tags)
$nameTag.Tags.Add($tags)

$target = New-EC2ManagedPrefixList -PrefixListName $pl.ResourceName -AddressFamily $pl.AddressFamily -MaxEntry $pl.MaxEntry -Entry $entries -TagSpecification $nameTag

Expand All @@ -215,7 +215,7 @@ function Invoke-PasmDeployment {
$pl.ResourceId = $target.PrefixListId

# Add an object to the result list
$ret.Add(
$ret.Add(
[PSCustomObject]@{
ResourceType = [Pasm.Parameter.Resource]::PrefixList
ResourceName = $target.PrefixListName
Expand Down Expand Up @@ -287,7 +287,7 @@ function Invoke-PasmDeployment {
}
}
}

# Update metadata section
if ($obj.Contains('MetaData')) {
$metadata = [ordered]@{}
Expand All @@ -301,13 +301,13 @@ function Invoke-PasmDeployment {
$metadata.CleandAt = if ($obj.MetaData.Contains('CleandAt')) { ([datetime]$obj.Metadata.CleandAt).ToUniversalTime() }
$obj.MetaData = $metadata
}

# Convert the object to Yaml format and overwrite the file
$obj | ConvertTo-Yaml -OutFile $file -Force

# Return result list
$PSCmdlet.WriteObject($ret)

# Clear AWS default settings for this session
Clear-AWSDefaultConfiguration -SkipProfileStore
}
Expand All @@ -327,7 +327,7 @@ function Invoke-PasmDeployment {
.DESCRIPTION
Reads the configuration generated by the blueprinting process and deploys the actual resources.
See the following source for details: https://github.com/nekrassov01/Pasm/blob/main/src/Functions/Invoke-PasmDeployment.ps1
.EXAMPLE
# Default input file path: ${PWD}/blueprint.yml
Invoke-PasmDeployment
Expand Down
Loading

0 comments on commit 41c3739

Please sign in to comment.