FunctionGeneration/New-GLFunction.ps1
Function Get-GLFunctionType { param($ParamObject) $TranslateTable = @{ Integer = "Int" String = "String" Boolean = "Bool" Array = "Array" Any = 'PSCustomObject' Object = $ParamObject.Additional } $Return = $TranslateTable.($ParamObject.Type) if ($ParamObject.Id -ne $null) { $Return = ($ModelList | ? { $_.RealId -eq $ParamObject.Id }).id } if ($null -eq $Return) { switch -regex ($ParamObject.name) { 'JSON' { $Return = 'PSCustomObject' } } } if ($Return -notmatch "Graylog") { if ($null -ne $ParamObject.Additional) { $Return = $TranslateTable.($ParamObject.Additional) } } if ($null -eq $Return) { $Return = "String" } Return $Return } Function New-GLFunction { param( $SwaggerObject, $OutDir = $PSScriptRoot, $Context, $Models, [switch]$Print ) $Prefix = "GL" $Operation = $SwaggerObject.Operations $TextInfo = (Get-Culture).TextInfo $Verb = $null # Select proper verb if ($Verb -eq $null -and $Operation.Method -eq 'Put') { $Verb = "Set" } Switch -regex ($Operation.nickname) { '^all' { $Verb = 'Get' } 'revoke' { $Verb = 'Revoke' } 'create|generate' { $Verb = 'New' } 'delete' { $Verb = 'Remove' } 'edit|change|save' { $Verb = "Set" } 'list|Get' { $Verb = "Get" } 'search|histogram|absolute' { $Verb = 'Find' } 'update' { $Verb = 'Update' } } if ($Verb -eq $null -and $Operation.Method -eq 'Get') { if ($Operation.Summary -match 'get|list') { $Verb = "Get" } if ($Operation.Summary -match 'Delete') { $Verb = "Remove" } if ($Operation.Summary -match 'Close') { $Verb = "Close" } if ($Operation.Summary -match 'Reopen') { $Verb = "Open" } } if ($Verb -eq $null -and $Operation.Method -ne 'Get') { if ($Operation.Summary -match 'Delete') { $Verb = "Remove" } if ($Operation.Summary -match 'Close') { $Verb = "Close" } if ($Operation.Summary -match 'Reopen') { $Verb = "Open" } if ($Operation.Summary -match '^Get') { $Verb = "Get" } if ($Operation.Summary -match 'Set') { $Verb = "Set" } if ($Operation.Summary -match 'Stop') { $Verb = "Set" } } if ($Verb -eq $null) { Switch -Regex (($Operation.nickname + $Operation.summary)) { 'test' { $Verb = "Test" } 'resolve' { $Verb = "Resolve" } 'stats' { $Verb = "Get" } 'Download' { $Verb = "Download" } 'Pause' { $Verb = "Pause" } 'Send' { $Verb = "Send" } 'Count' { $Verb = "Measure" } 'read' { $Verb = "Get" } 'add' { $Verb = "Add" } 'Simulate' { $Verb = "Simulate" } 'connect' { $Verb = "Connect" } 'remove' { $Verb = "Remove" } 'info' { $Verb = "Get" } 'purge' { $Verb = "Purge" } 'Lookup' { $Verb = "Resolve" } 'resume' { $Verb = "Resume" } 'Shutdown' { $Verb = "Stop" } 'current thr' { $Verb = "Get" } 'stat' { $Verb = "Get" } 'Terminate' { $Verb = "Stop" } 'validate' { $Verb = "Test" } 'start' { $Verb = "Start" } 'Show' { $Verb = "Get" } 'Cycle' { $Verb = "Set" } 'Trigger' { $Verb = "Start" } 'clone' { $Verb = "Copy" } 'Parse' { $Verb = "Parse" } 'Analyze' { $Verb = "Analyze" } 'terms|(keyword|Relative)' { $Verb = "Find" } 'assign' { $Verb = "Set" } 'Register' { $Verb = "Register" } 'Copy' { $Verb = "Copy" } 'List' { $Verb = "Get" } 'Cancel' { $Verb = "Cancel" } 'Hello|hello' { $Verb = "Test" } 'Render' { $Verb = "Get" } 'New' { $Verb = "New" } 'Counts' { $Verb = "Get" } 'Order' { $Verb = "Get" } 'Install' { $Verb = "Install" } 'Total number of messages' { $Verb = 'Get' } 'Export' { $Verb = 'Export' } 'Redirect' { $Verb = 'Send' } } } if ($Verb -eq $null) { Write-Warning "no verb match for $($Operation.nickname) - $($Operation.summary)" } $TranslateTable = @{ Integer = "Int" String = "String" Boolean = "Bool" } $Noun = ($Operation.nickname -split "") | ? { $_ -ne "" } $Noun[0] = $Operation.nickname.ToUpper()[0] $Noun = $Noun -join "" $Noun = $Noun -replace 'delete|remove|list|set|get|connect|Create', '' -replace "getall", 'All' -replace $Verb, '' $CmdletName = "$Verb-" + $Prefix + $Context + $Noun $ContentType = $Operation.produces $Parameters = @() Foreach ($Parameter in $Operation.parameters) { $ParameterObject = [PSCustomObject]@{ Name = ($TextInfo.ToTitleCase($Parameter.Name) -replace "JSON ", "" -replace ' ', '') realName = $Parameter.Name HelpInfo = $Parameter.Description Mandatory = $parameter.required Type = (Get-GLFunctionType $Parameter) ParamType = $Parameter.paramType Models = $Models } if ($Parameter.Name.length -eq 0 -and $Parameter.paramType -eq 'body') { $ParameterObject.Name = "Body" $ParameterObject.realName = "JSON Body" } $Parameters += $ParameterObject } $UriParameters = @() ($SwaggerObject.path | Select-String -Pattern "\{([a-z]+)\}" -AllMatches).matches.Groups | ? { $_.Name -eq 1 } | Foreach { $ParameterObject = [PSCustomObject]@{ Name = $TextInfo.ToTitleCase($_) realName = $_ HelpInfo = "$_ value" Mandatory = $True Type = "String" ParamType = "String" } if ([string]::IsNullOrEmpty($ParameterObject.Name)) { Write-Warning ($_ | ConvertTo-Json) } $UriParameters += $ParameterObject } # Should process support if ($Operation.Method -match "POST|PUT|DELETE") { $ShouldProcess = $True } # Parameter block $ParameterBlock = Foreach ($Parameter in ($Parameters | ? { $_ -ne $null })) { Write-Warning "Adding param $($Parameter.realname)" if ([string]::IsNullOrEmpty($Parameter.HelpInfo)) { $Parameter.HelpInfo = "Parameter $($Parameter.realname)" } if ($Parameter.HelpInfo -match 'TimeRange') { $Parameter.Type = "DateTime" } @" # $($Parameter.HelpInfo) [Parameter(Mandatory=`$$($Parameter.Mandatory),ValueFromPipelineByPropertyName=`$true)] [$($Parameter.Type)]`$$($Parameter.Name), "@ } $ParameterBlock += ' # Base url for the API, normally https://<grayloghost>:<port>/api [string]$APIUrl = $Global:GLApiUrl, # Graylog credentials as username:password or use Convert-GLTokenToCredential for token usage [PSCredential]$Credential = $Global:GLCredential ' ############################ $ScriptBlock = @() $ScriptBlock += "" $ScriptBlock += "`$QueryArray = @()" $Parameters | Foreach { $ScriptBlock += "if(![string]::IsNullOrEmpty(`$$($_.Name))){ $(if($_.Type -eq 'string'){"`$$($_.name) = [system.web.httputility]::UrlEncode(`$$($_.name))"}) $(if($_.Type -eq 'DateTime'){ "[string]`$$($_.Name)String = `$$($_.Name).ToUniversalTime() | Get-Date -Format 'yyyy-MM-ddTHH:mm:ss.fffZ'";$_.Name = ($_.Name+"String") }) `$QueryArray += `"$($_.RealName)=`$$($_.Name)`" } " } $ScriptBlock += "`$Headers = @{Accept = 'application/json';'X-Requested-By'='PSGraylog Module'}" $ScriptBlock += "`$APIPath = '$($SwaggerObject.Path)'" $UriParameters.name | Foreach { $ScriptBlock += "`$APIPath = `$APIPath -Replace `"\{$_\}`",`"`$$_`" " } if ($Operation.method -eq 'Get') { $ScriptBlock += "`$QueryString = `$QueryArray -join '&'" $ScriptBlock += "" $ScriptBlock += "Try {" $ScriptBlock += " Invoke-RestMethod -Method $($Operation.Method) -Headers `$Headers -ContentType 'application/json' -Uri (`$APIUrl+`$APIPath+`"`?`"+`$QueryString) -Credential `$Credential -ErrorAction Stop" $ScriptBlock += "}" $ScriptBlock += "Catch {" if (($Operation.responseMessages | Measure-Object).count -gt 0) { $n = 0 $Operation.responseMessages | foreach { $Code = $Operation.responseMessages.code $Message = $Operation.responseMessages.Message if ($n -eq 0) { $if = "if" } else { $if = "elseif" } $n++ $ScriptBlock += "$if(`$Error[0].Exception.Response.StatusCode.value__ -eq $($_.Code)) {" $ScriptBlock += " Write-Error -Exception `$Error[0].Exception -Message `"$($_.Message)`" -ErrorAction `$ErrorActionPreference" $ScriptBlock += "}" } $ScriptBlock += "else {" $ScriptBlock += " Write-Error -Exception `$Error[0].Exception -Message `$Error[0].Message -ErrorAction `$ErrorActionPreference" $ScriptBlock += "}" } else { $ScriptBlock += " Write-Error -Exception `$Error[0].Exception -Message `$Error[0].Message -ErrorAction `$ErrorActionPreference" } $ScriptBlock += "" $ScriptBlock += "}" $ScriptBlock += "" } else { if ($Operation.Method -match "put|post") { If (($Parameters | ? { $_.realName -match 'JSON Body' } | measure).count -ge 1) { Write-Warning "Body parameter found" $Body = "-Body (`$Body | ConvertTo-Json)" $CmdletName } else { $Body = "-Body `$Body" $Scriptblock = "`$BodyHash = @{}" $ScriptBlock += "`n" $ScriptBlock += "`$QueryArray | Foreach { `$val = `$_ -split '=' `$BodyHash[`$val[0]] = `$val[1] } `$Body = `$BodyHash | ConvertTo-Json " } } $ScriptBlock += "Try {" $ScriptBlock += "Invoke-RestMethod -Method $($Operation.Method) -Headers `$Headers -ContentType 'application/json' -Uri `"`$APIUrl`$APIPath`" -Credential `$Credential $Body -ErrorAction Stop" $ScriptBlock += "}" $ScriptBlock += "Catch {" if (($Operation.responseMessages | Measure-Object).count -gt 0) { $n = 0 $Operation.responseMessages | foreach { $Code = $Operation.responseMessages.code $Message = $Operation.responseMessages.Message if ($n -eq 0) { $if = "if" } else { $if = "elseif" } $n++ $ScriptBlock += "$if(`$Error[0].Exception.Response.StatusCode.value__ -eq $($_.Code)) {" $ScriptBlock += " Write-Error -Exception `$Error[0].Exception -Message `"$($_.Message)`" -ErrorAction `$ErrorActionPreference" $ScriptBlock += "}" } $ScriptBlock += "else {" $ScriptBlock += " Write-Error -Exception `$Error[0].Exception -Message `$Error[0].Message -ErrorAction `$ErrorActionPreference" $ScriptBlock += "}" } else { $ScriptBlock += " Write-Error -Exception `$Error[0].Exception -Message `$Error[0].Message -ErrorAction `$ErrorActionPreference" } $ScriptBlock += "" $ScriptBlock += "}" $ScriptBlock += "" } $ExampleParameters = $Parameters | Foreach { "-" + $_.Name + " <" + $_.Type + ">" } $ExampleHelp = $CmdletName + " " + $ExampleParameters -join ' ' $Function = @" <# .SYNOPSIS $($Operation.Summary) .DESCRIPTION $($Operation.Summary) $(if(($Operation.Notes).length -ge 1){$Operation.Notes}) For more information about this cmdlet - please search for $($Swaggerobject.Path) in the docs available at http(s)://your-graylog.fqdn/api/api-docs .EXAMPLE $ExampleHelp .NOTES Auto generated #> Function $($CmdletName) { [CmdletBinding($(if($ShouldProcess){"SupportsShouldProcess, ConfirmImpact='Medium'"}))] Param( $ParameterBlock ) Begin{ if([string]::IsNullOrEmpty(`$APIUrl)) { Write-Error -ErrorAction Stop -Exception "APIUrl not set" -Message "APIUrl was null or empty, refer to the documentation" } if(`$Null -eq `$Credential){ Write-Error -ErrorAction Stop -Exception "Credential not set" -Message "Credential not set - refer to the documentation for help" } } Process { $( if($ShouldProcess) { $descr = $Operation.summary if([string]::IsNullOrWhiteSpace($Descr)){ $descr = $cmdletname } $Target = '$'+$Parameters[0].name if([string]::IsNullOrEmpty($Parameters[0].name)) { $Target = "`"All?`"" } 'if ($PSCmdlet.ShouldProcess('+$Target+',"'+$descr+'")) {' } ) $($ScriptBlock -join "`n" -replace '\}\s*$',"}`n" -replace "\{\s*$","{`n" -replace "^\s*",' ') $( if($ShouldProcess) {'}'} ) } End {} } "@ #$Function = Format-Intendation -Script $Function if ($Print) { Write-Output $Function } else { $OutFile = "$OutDir\$Cmdletname.ps1" if (Test-Path $OutFile) { #Set-Content -Value $Function -Path "$OutDir\$Cmdletname-collide.ps1" -Encoding UTF8 $NewFile = ($OutFile -replace '\.ps1', 'All.ps1') $NewCmdletName = $CmdletName + "All" $PathLength = (($Function | Select-String "\`$ApiPath *= *'(/.*)'").Matches.groups | ? { $_.Name -eq 1 }).Length $CollidedPathLength = (($OutFile | Select-String "\`$ApiPath *= *'(/.*)'").Matches.groups | ? { $_.Name -eq 1 }).length if ($CollidedPathLength -lt $PathLength) { mv $OutFile $NewFile $NewVal = (Cat -Raw $NewFile) -replace $CmdletName, $NewCmdletName Set-Content -Path $NewFile -Value $NewVal Set-Content -Value $Function -Path "$OutDir\$Cmdletname.ps1" -Encoding UTF8 } else { $CmdletName = $NewCmdletName Set-Content -Value $Function -Path "$OutDir\$Cmdletname.ps1" -Encoding UTF8 } } else { Set-Content -Value $Function -Path "$OutDir\$Cmdletname.ps1" -Encoding UTF8 } } } Function Format-Intendation { param( [string]$Script ) $n = 0 $out = @() $param = $false $ParamEnd = $false $prev = "" $Script -split "`n" | foreach { $space = $spacenext if ($_ -match "\{" -and $_ -notmatch "\@\{[\}]*") { $n++ } if ($_ -match "\}" -and $_ -notmatch "\@\{\}") { $n-- } # Detect param if ($_ -match "Param\(\s*$" -and $Param -eq $false -and $ParamEnd -ne $true) { $Param = $true $n++ } if ($Param -eq $true -and $_ -match '^\s*\)$') { $Param = $false $ParamEnd = $True Write-Warning "param end" $n-- } if ($n -lt 0) { $n = 0 } $spacenext = " " * $n if ($_ -match "^\s*\}\s*$" -or ($ParamEnd -eq $true -and $_ -match '^\s*\)\s*$')) { $out += $_ -replace "^[ ]+", $spacenext } else { if ($Prev -cmatch "^\.[A-Z]+") { $out += $_ -replace "^[ ]+", " " } else { $out += $_ -replace "^[ ]+", $space } } $prev = $_ } $out -join "`n" } |