Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert and output to csv for external use (#25) #26

Merged
merged 2 commits into from
Nov 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Pasm.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ end {
CmdletsToExport = @()
FunctionsToExport = (Get-ChildItem -LiteralPath (Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath 'src') -ChildPath 'Functions') -Filter '*.ps1').ForEach( { [path]::GetFileNameWithoutExtension($_.Name) } )
VariablesToExport = '*'
AliasesToExport = @('psmi', 'psmv', 'psmb', 'psmd', 'psma')
AliasesToExport = @('psmi', 'psmv', 'psmb', 'psmd', 'psma', 'psmc', 'psme')
Tags = @('AWS', 'Linux', 'Windows')
ProjectUri = 'https://github.com/{0}/{1}' -f $author, $moduleName
LicenseUri = 'https://github.com/{0}/{1}/blob/main/LICENSE' -f $author, $moduleName
Expand Down
27 changes: 21 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![build](https://github.com/nekrassov01/Pasm/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/nekrassov01/Pasm/actions/workflows/build.yml) [![release](https://github.com/nekrassov01/Pasm/actions/workflows/release.yml/badge.svg)](https://github.com/nekrassov01/Pasm/actions/workflows/release.yml)

Pasm is a PowerShell module for simple management of public IP address ranges provided by AWS. By simply following simple rules and creating YAML templates, you can keep up with IP range changes, deploy and synchronize resources. The currently supported resources are SecurityGroup, NetworkACL, and PrefixList.
Pasm is a PowerShell module for simple management of public IP address ranges provided by AWS. By simply following simple rules and creating YAML templates, you can keep up with IP range changes, deploy and synchronize resources. The currently supported resources are SecurityGroup, NetworkACL, and PrefixList.

- [Pasm](#pasm)
- [Compatible Editions](#compatible-editions)
Expand All @@ -16,6 +16,7 @@ Pasm is a PowerShell module for simple management of public IP address ranges pr
- [Generating Blueprint](#generating-blueprint)
- [Deployment](#deployment)
- [Clean up](#clean-up)
- [Export to CSV](#export-to-csv)
- [Same Thing, Shorter](#same-thing-shorter)
- [Aliases](#aliases)
- [Sample Template (outline.yml)](#sample-template-outlineyml)
Expand All @@ -33,7 +34,7 @@ Install the modules required to use Pasm.
```ps1
Install-Module -Name PowerShell-Yaml, AWS.Tools.Installer -Scope CurrentUser
Install-AWSToolsModule -Name AWS.Tools.Common, AWS.Tools.EC2 -Scope CurrentUser
```
```

Set the AWS credential.

Expand Down Expand Up @@ -61,6 +62,7 @@ Pasm includes 6 functions.
|Invoke-PasmDeployment|Read the blueprint and deploy resources.|
|Invoke-PasmAutomation|Run the following in order: `Invoke-PasmValidation`, `Invoke-PasmBlueprint`, and `Invoke-PasmDeployment`|
|Invoke-PasmCleanUp|Clean up the deployed resources.|
|Invoke-PasmExport|Based on the Yaml template, get the range of ip from [ip-ranges.json](https://ip-ranges.amazonaws.com/ip-ranges.json) and create a simple csv for external use.|

## Configuration Files

Expand Down Expand Up @@ -182,17 +184,25 @@ ResourceType : NetworkAcl
ResourceName : test-acl-01
ResourceId : acl-e1t2d3g4c5bryfhvn
Detached : {subnet-q1z2x3w4e5cvrtbny, subnet-w1x2c3e4r5vbtynmu}
Skipped :
Skipped :
Action : CleanUp

ResourceType : PrefixList
ResourceName : test-pl-01
ResourceId : pl-a1d2s3f4d5gfhgjhk
Detached : {rtb-a1b2c3d4e5fghijkl, rtb-x1y2z3x4y5zxyzxyz, sg-1a2s3d4f5g6h7j890}
Skipped :
Skipped :
Action : CleanUp
```

### Export to CSV

Output to simple CSV for external use.

```ps1
Invoke-PasmExport -FilePath output.csv
```

## Same Thing, Shorter

`Invoke-PasmAutomation` runs the following in order: `Invoke-PasmValidation`, `Invoke-PasmBlueprint`, and `Invoke-PasmDeployment`.
Expand Down Expand Up @@ -243,6 +253,11 @@ psma -file 'C:\Pasm\outline.yml' -out 'blueprint.yml'
psmc -file 'C:\Pasm\blueprint.yml'
```

```ps1
# Invoke-PasmExport -FilePath 'C:\Pasm\outline.yml' -OutputFileName 'output.csv'
psme -file 'C:\Pasm\outline.yml' -out 'output.csv'
```

## Sample Template (outline.yml)

'outline.yml' will be deployed with comments. Please overwrite it according to your environment.
Expand Down Expand Up @@ -270,15 +285,15 @@ Resource: # required
FromPort: 80 # required - Range: 0-65535
ToPort: 80 # required - Range: 0-65535
- Id: 2
ServiceKey: S3
ServiceKey: S3
Region:
- ap-northeast-1
IpFormat:
- IPv6
Protocol: tcp
FromPort: 443
ToPort: 443
NetworkAcl: # not-required - One of the following must be present: 'SecurityGroup','NetworkAcl', 'PrefixList'
NetworkAcl: # not-required - One of the following must be present: 'SecurityGroup','NetworkAcl', 'PrefixList'
- ResourceName: test-acl-01 # required
VpcId: vpc-00000000000000000 # required
MaxEntry: 20 # not-required - Range: 1-20
Expand Down
111 changes: 111 additions & 0 deletions src/Functions/Invoke-PasmExport.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#Requires -Version 5.1
using namespace System.IO
using namespace System.Collections.Generic

function Invoke-PasmExport {
[CmdletBinding()]
[OutputType([System.IO.FileInfo[]])]
param (
# Specify the path to the Yaml template.
[Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[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')]
[ValidateNotNullOrEmpty()]
[string[]]$OutputFileName = $('{0}.csv' -f [Pasm.Template.Name]::output)
#[string[]]$OutputFileName = 'output.csv'
)

begin {
try {
Set-StrictMode -Version Latest

# Load helper functions
. $($PSScriptRoot, 'Helpers', 'Helpers.ps1' -join [path]::DirectorySeparatorChar)

# Implicitly run the validator process.
Invoke-PasmValidation -FilePath $filePath -SkipIdValidation | Out-Null

# Validation that the number of parameters match
if ($filePath.Length -ne $outputFileName.Length) {
throw [InvalidOperationException]::new('The length of the ''FilePath'' and the length of the ''OutputFileName'' must be the same.')
}
}
catch {
$PSCmdlet.ThrowTerminatingError($PSItem)
}
}

process {
try {
$i = 0
foreach ($file in $filePath) {
# Load outline file
$obj = Import-PasmFile -FilePath $file -Ordered

# Create output file path
$outputFilePath = $([path]::GetDirectoryName($file), $OutputFileName[$i] -join [path]::DirectorySeparatorChar)

# Create outer container
$container = [list[object]]::new()

foreach ($resource in $([enum]::GetNames([Pasm.Parameter.Resource]))) {
if ($obj.Resource.Contains($resource)) {
foreach ($res in $obj.Resource.$resource) {
foreach ($rule in $res.Rules) {
foreach ($r in $(Get-PasmAWSIpRange $rule -Resource $resource)) {
$o = [ordered]@{}
$o.ServiceKey = $rule.ServiceKey
$o.IpPrefix = $r.IpPrefix
$o.IpFormat = $r.IpAddressFormat
$o.Region = $r.Region
$container.Add($o)
}
}
}
}
}
# Converts the object to csv format and writes it to a file
# If the file already exists, it will be overwritten
$container | Export-Csv -LiteralPath $outputFilePath -NoTypeInformation -Force
$i++
$PSCmdlet.WriteObject([fileinfo]::new($outputFilePath))
}
}
catch {
$PSCmdlet.ThrowTerminatingError($PSItem)
}
}

end {
# Clean up processes, if any
}

<#
.SYNOPSIS
Get the ip ranges from 'ip-ranges.json' as described in the Yaml template, and create a simple csv.

.DESCRIPTION
Get the ip ranges from 'ip-ranges.json' as described in the Yaml template, and create a simple csv.
See the following source for details: https://github.com/nekrassov01/Pasm/blob/main/src/Functions/Invoke-PasmExport.ps1

.EXAMPLE
# Default input file path: ${PWD}/outline.yml, default output file name: 'output.csv'
Invoke-PasmExport

.EXAMPLE
# Loading multiple files
Invoke-PasmExport -FilePath 'C:/Pasm/outline-sg.yml', 'C:/Pasm/outline-nacl.yml', 'C:/Pasm/outline-pl.yml' -OutputFileName 'blueprint-sg.csv', 'blueprint-nacl.csv', 'blueprint-pl.csv'

.EXAMPLE
# Loading multiple files from pipeline
'C:/Pasm/outline-sg.yml', 'C:/Pasm/outline-nacl.yml', 'C:/Pasm/outline-pl.yml' | Invoke-PasmBlueprint -OutputFileName 'blueprint-sg.csv', 'blueprint-nacl.csv', 'blueprint-pl.csv'

.LINK
https://github.com/nekrassov01/Pasm
#>
}
2 changes: 1 addition & 1 deletion src/Functions/Invoke-PasmInitialize.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Resource: # required
if ($isExistsVpcId -or $isExistsSbnId) {
$yaml = ConvertFrom-Yaml -Yaml $content -Ordered
if ($isExistsVpcId) {
foreach ($resource in 'SecurityGroup', 'NetworkAcl', 'PrefixList') {
foreach ($resource in $([enum]::GetNames([Pasm.Parameter.Resource]))) {
foreach ($r in $yaml.Resource.$resource) {
if ($r.Contains('VpcId')) {
$r.VpcId = $vpcId
Expand Down
39 changes: 25 additions & 14 deletions src/Functions/Invoke-PasmValidation.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ function Invoke-PasmValidation {
[Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[Alias('file')]
[ValidateNotNullOrEmpty()]
[string[]]$FilePath = $($PWD, $('{0}.yml' -f [Pasm.Template.Name]::outline) -join [path]::DirectorySeparatorChar)
[string[]]$FilePath = $($PWD, $('{0}.yml' -f [Pasm.Template.Name]::outline) -join [path]::DirectorySeparatorChar),

# Skip validation of VpcId and SubnetId.
[Parameter(Mandatory = $false)]
[Alias('skip-id')]
[switch]$SkipIdValidation = $false
)

begin {
Expand Down Expand Up @@ -89,9 +94,11 @@ function Invoke-PasmValidation {
Out-PasmLogLine -Message $('Validation passed: SecurityGroup ''{0}'' Rules' -f $sg.ResourceName)
}

if ($sg.Contains('VpcId')) {
[void](Test-PasmVpcId -VpcId $sg.VpcId)
Out-PasmLogLine -Message $('Validation passed: SecurityGroup ''{0}'' VpcId' -f $sg.ResourceName)
if (!$PSBoundParameters.ContainsKey('SkipIdValidation')) {
if ($sg.Contains('VpcId')) {
[void](Test-PasmVpcId -VpcId $sg.VpcId)
Out-PasmLogLine -Message $('Validation passed: SecurityGroup ''{0}'' VpcId' -f $sg.ResourceName)
}
}
}
}
Expand Down Expand Up @@ -133,14 +140,16 @@ function Invoke-PasmValidation {
Out-PasmLogLine -Message $('Validation passed: NetworkAcl ''{0}'' Rules' -f $nacl.ResourceName)
}

if ($nacl.Contains('VpcId')) {
[void](Test-PasmVpcId -VpcId $nacl.VpcId)
Out-PasmLogLine -Message $('Validation passed: NetworkAcl ''{0}'' VpcId' -f $nacl.ResourceName)
}
if (!$PSBoundParameters.ContainsKey('SkipIdValidation')) {
if ($nacl.Contains('VpcId')) {
[void](Test-PasmVpcId -VpcId $nacl.VpcId)
Out-PasmLogLine -Message $('Validation passed: NetworkAcl ''{0}'' VpcId' -f $nacl.ResourceName)
}

if ($nacl.Contains('AssociationSubnetId')) {
[void](Test-PasmSubnetId -SubnetId $nacl.AssociationSubnetId)
Out-PasmLogLine -Message $('Validation passed: NetworkAcl ''{0}'' SubnetId' -f $nacl.ResourceName)
if ($nacl.Contains('AssociationSubnetId')) {
[void](Test-PasmSubnetId -SubnetId $nacl.AssociationSubnetId)
Out-PasmLogLine -Message $('Validation passed: NetworkAcl ''{0}'' SubnetId' -f $nacl.ResourceName)
}
}
}
}
Expand Down Expand Up @@ -170,9 +179,11 @@ function Invoke-PasmValidation {
Out-PasmLogLine -Message $('Validation passed: PrefixList ''{0}'' Rules' -f $pl.ResourceName)
}

if ($pl.Contains('VpcId')) {
[void](Test-PasmVpcId -VpcId $pl.VpcId)
Out-PasmLogLine -Message $('Validation passed: PrefixList ''{0}'' VpcId' -f $pl.ResourceName)
if (!$PSBoundParameters.ContainsKey('SkipIdValidation')) {
if ($pl.Contains('VpcId')) {
[void](Test-PasmVpcId -VpcId $pl.VpcId)
Out-PasmLogLine -Message $('Validation passed: PrefixList ''{0}'' VpcId' -f $pl.ResourceName)
}
}
}
}
Expand Down
17 changes: 9 additions & 8 deletions src/Pasm.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
# Generated by: nekrassov01
#
# Generated on: 2021/10/17
# Generated on: 2021/11/28
#

@{
Expand All @@ -12,7 +12,7 @@
RootModule = 'Pasm.psm1'

# Version number of this module.
ModuleVersion = '1.2.0'
ModuleVersion = '1.3.8'

# Supported PSEditions
CompatiblePSEditions = 'Core', 'Desktop'
Expand Down Expand Up @@ -51,8 +51,8 @@ ClrVersion = '4.0.0.0'
# ProcessorArchitecture = ''

# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @('PowerShell-Yaml',
'AWS.Tools.Common',
RequiredModules = @('PowerShell-Yaml',
'AWS.Tools.Common',
'AWS.Tools.EC2')

# Assemblies that must be loaded prior to importing this module
Expand All @@ -71,8 +71,8 @@ RequiredModules = @('PowerShell-Yaml',
# NestedModules = @()

# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = 'Invoke-PasmAutomation', 'Invoke-PasmBlueprint',
'Invoke-PasmDeployment', 'Invoke-PasmInitialize',
FunctionsToExport = 'Invoke-PasmAutomation', 'Invoke-PasmBlueprint', 'Invoke-PasmCleanUp',
'Invoke-PasmDeployment', 'Invoke-PasmExport', 'Invoke-PasmInitialize',
'Invoke-PasmValidation'

# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
Expand All @@ -82,7 +82,7 @@ CmdletsToExport = @()
VariablesToExport = '*'

# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
AliasesToExport = 'psmi', 'psmv', 'psmb', 'psmd', 'psma'
AliasesToExport = 'psmi', 'psmv', 'psmb', 'psmd', 'psma', 'psmc', 'psme'

# DSC resources to export from this module
# DscResourcesToExport = @()
Expand Down Expand Up @@ -111,7 +111,7 @@ PrivateData = @{
# IconUri = ''

# ReleaseNotes of this module
ReleaseNotes = 'https://github.com/nekrassov01/Pasm/releases/tag/1.2.0'
ReleaseNotes = 'https://github.com/nekrassov01/Pasm/releases/tag/1.3.8'

# Prerelease string of this module
# Prerelease = ''
Expand All @@ -133,3 +133,4 @@ PrivateData = @{
# DefaultCommandPrefix = ''

}

3 changes: 2 additions & 1 deletion src/Pasm.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace ${moduleName}.RequiredParameter
namespace ${moduleName}.Template
{
// Yaml template default file name
public enum Name { outline, blueprint }
public enum Name { outline, blueprint, output }
}
"@

Expand All @@ -53,6 +53,7 @@ $map = @{
'psmd' = 'Invoke-PasmDeployment'
'psma' = 'Invoke-PasmAutomation'
'psmc' = 'Invoke-PasmCleanUp'
'psme' = 'Invoke-PasmExport'
}
foreach ($m in $map.GetEnumerator()) {
Set-Alias -Name $m.Key -Value $m.Value
Expand Down
6 changes: 6 additions & 0 deletions tests/Pasm.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ InModuleScope 'Pasm' {
It 'Validation' {
Invoke-PasmValidation -FilePath $outlineFilePath | Should -BeTrue
}
It 'Export' {
Invoke-PasmExport -FilePath $outlineFilePath | Should -BeTrue
}
It 'Blueprint' {
Invoke-PasmBlueprint -FilePath $outlineFilePath -OutputFileName $blueprintFileName | Should -BeTrue
}
Expand Down Expand Up @@ -217,6 +220,9 @@ InModuleScope 'Pasm' {
It 'Validation' {
Invoke-PasmValidation -FilePath $outlineFilePath | Should -BeTrue
}
It 'Export' {
Invoke-PasmExport -FilePath $outlineFilePath | Should -BeTrue
}
It 'Blueprint' {
Invoke-PasmBlueprint -FilePath $outlineFilePath -OutputFileName $blueprintFileName | Should -BeTrue
}
Expand Down