KnowIT.Interworx.psm1
|
#region === Public functions === ### Source file: 'Connect-Interworx.ps1' ### function Connect-Interworx { [CmdletBinding(DefaultParameterSetName = 'Credential')] param( [Parameter(Mandatory, Position = 0)] [ValidateNotNullOrEmpty()] [Alias('Host')] [string]$Server, [Parameter(Mandatory, ParameterSetName = 'ApiKey')] [ValidateNotNullOrEmpty()] [securestring]$ApiKey, [Parameter(Mandatory, ParameterSetName = 'Credential')] [pscredential]$Credential ) try { Update-CallerPreference $PSCmdlet $Server = $Server.TrimEnd('/') if($Server -notmatch ':\d+') { $Server = "${Server}:2443" } if(!$Server.StartsWith('http')) { $Server = "https://$Server" } $newConnection = switch ($PSCmdlet.ParameterSetName) { 'ApiKey' { @{ Method = 'ApiKey' Server = $Server Credential = [pscredential]::new('apikey', $ApiKey) } } 'Credential' { @{ Method = 'Credential' Server = $Server Credential = $Credential } } default { throw "Invalid parameter set: $($PSCmdlet.ParameterSetName)" } } Write-Verbose "Establece conexión con Interworx '$($newConnection.Server)' mediante [$($newConnection.Method)]" -Verbose $script:IworxConnection = $newConnection } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Get-InterworxConnection.ps1' ### function Get-InterworxConnection { [CmdletBinding()] param( ) try { Update-CallerPreference $PSCmdlet [PSCustomObject]$script:IworxConnection } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Get-NodeworxDnsZone.ps1' ### function Get-NodeworxDnsZone { [CmdletBinding()] param( [Parameter(Position = 0)] [ValidateNotNullOrEmpty()] [Alias('DomainPattern')] [string]$Domain ) try { Update-CallerPreference $PSCmdlet Invoke-Nodeworx 'DnsZone' -Action 'listZones' | Map-Object { if($_.is_template -eq 1 -or ($Domain -and $_.domain -notmatch $Domain)) { return } [PSCustomObject]@{ PSTypeName = 'KnowIT.Nodeworx.DnsZone' ZoneId = $_.zone_id Domain = $_.domain MasterDomain = $_.master_domain DomainType = $_.domain_type Suspended = $_.is_suspended -as [bool] } } } catch { $PSCmdlet.WriteError($_) } } ### Source file: 'Invoke-Nodeworx.ps1' ### function Invoke-Nodeworx { [CmdletBinding()] [Alias('nodeworx')] param( [Parameter(Mandatory)] [string]$Controller, [Parameter(Mandatory)] [string]$Action, [hashtable]$Params = @{}, # Si se especifica, devuelve la respuesta XML sin procesar [switch]$AsXmlString ) try { Update-CallerPreference $PSCmdlet $controller = '/nodeworx/' + $Controller.TrimStart('/') $request = CreateIworxRequest $controller $Action $Params $response = Invoke-WebRequest @request -UseBasicParsing -Verbose:$false $content = $response.Content if($AsXmlString) { return $content } ParseIworxResponse $content } catch { $PSCmdlet.WriteError($_) } } #endregion #region === Private functions === ### Source file: 'IworxApi.ps1' ### function CreateIworxRequest ([string]$Controller, [string]$Action, [hashtable]$Params, [string]$Domain) { if(!$script:IworxConnection) { throw "No se ha establecido una conexión a Interworx. Ejecuta el comando 'Connect-Interworx'." } $cred = $script:IworxConnection.Credential.GetNetworkCredential() $key = switch ($script:IworxConnection.Method) { 'ApiKey' { if($Domain) { @{ apikey = $cred.Password; domain = $Domain } } else { $cred.Password } } 'Credential' { $credKey = @{ email = $cred.UserName; password = $cred.Password } if($Domain) { $credKey.domain = $Domain } $credKey } default { throw "Método de autenticación incorrecto: $($script:IworxConnection.Method)" } } $body = @" <?xml version="1.0" encoding="UTF-8"?> <methodCall> <methodName>iworx.route</methodName> <params> <param><value>$(ConvertToXmlRpcValue $key)</value></param> <param><value><string>$Controller</string></value></param> <param><value><string>$Action</string></value></param> <param><value>$(ConvertToXmlRpcStruct $Params)</value></param> </params> </methodCall> "@ Write-Debug "Request body: $body" return @{ Method = 'POST' Uri = $script:IworxConnection.Server + '/xmlrpc' Body = $body ContentType = 'text/xml; charset=UTF-8' } } function ParseIworxResponse ([xml]$Response) { if($Response.methodResponse.fault) { $errorCode = $response.methodResponse.fault.value.struct.member.Where({ $_.name -eq 'faultCode' }).value.int $errorString = $response.methodResponse.fault.value.struct.member.Where({ $_.name -eq 'faultString' }).value.string throw "API Error - Code [$errorCode]: $errorString." } $status = $Response.methodResponse.params.param.value.struct.member.Where({ $_.name -eq 'status' }).value.int $payload = $Response.methodResponse.params.param.value.struct.member.Where({ $_.name -eq 'payload' }).value if($status -gt 0) { throw "API Error - Status code [$status] $($payload.string)" } ParseXmlRpcNode $payload } ### Source file: 'KnowIT.ModuleHelpers.ps1' ### function Update-CallerPreference { # https://devblogs.microsoft.com/scripting/weekend-scripter-access-powershell-preference-variables/ param( [ValidateNotNull()] [PSTypeName('System.Management.Automation.PSScriptCmdlet')]$ScriptCmdlet = (Get-Variable PSCmdlet -Scope 1 -ValueOnly), [ValidateSet('ErrorAction', 'Warning', 'Verbose', 'Debug', 'Information', 'Progress', 'Confirm', 'WhatIf')] [string[]]$Skip ) $commonParameters = 'ErrorAction', 'Warning', 'Verbose', 'Debug', 'Information', 'Progress', 'Confirm', 'WhatIf' $invocation = $ScriptCmdlet.MyInvocation $commandDebug = $invocation.BoundParameters.ContainsKey('Debug') Write-Debug "Updating [$($invocation.MyCommand)] Preference variables:" -Debug:$commandDebug foreach($p in $commonParameters) { if($invocation.BoundParameters.ContainsKey($p)) { continue } $var = "${p}Preference" if($p -eq 'ErrorAction') { $val = 'Stop' $scope = 'Forced' } elseif($p -in $Skip) { $val = Get-Variable -Scope Global -Name $var -ValueOnly $scope = 'Global' } else { $val = $ScriptCmdlet.GetVariableValue($var) $scope = 'Caller' } Write-Debug " (From $scope scope) $var = $val " -Debug:$commandDebug Set-Variable -Scope 1 -Name $var -Value $val } } function Map-Object { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseApprovedVerbs', '', Justification = 'Internal functions')] param([scriptblock]$ScriptBlock) begin { $code = "& { process { $ScriptBlock } }" $pipeline = [scriptblock]::Create($code).GetSteppablePipeline() $pipeline.Begin($true) } process { $pipeline.Process($_) } end { $pipeline.End() } } ### Source file: 'XmlRpc.ps1' ### function ConvertToXmlRpcValue ($Value) { switch ($Value.GetType().Name) { 'String' { "<string>$Value</string>" } 'Int32' { "<int>$Value</int>" } 'Boolean' { "<boolean>$([int]$Value)</boolean>" } 'Hashtable' { ConvertToXmlRpcStruct $Value } 'OrderedDictionary' { ConvertToXmlRpcStruct $Value } default { throw "Unsupported parameter type: [$_] $Value" } } } function ConvertToXmlRpcStruct ($Params) { if($Params.Count -eq 0) { return "<struct/>" } $members = foreach($key in $Params.Keys) { $value = ConvertToXmlRpcValue $Params[$key] "<member><name>$key</name><value>$value</value></member>" } "<struct>`n$($members -join "`n")`n</struct>" } function ParseXmlRpcNode ([Xml.XmlElement]$Node) { if($Node.struct) { $result = @{} foreach ($member in $Node.struct.member) { $name = $member.name $valueNode = $member.value $result[$name] = ParseXmlRpcNode $valueNode } return [PSCustomObject]$result } if($Node.array) { foreach ($item in $Node.array.data.value) { ParseXmlRpcNode $item } return } if($Node.string) { return $Node.string } if($Node.int) { return [int]$Node.int } if($Node.i4) { return [int]$Node.i4 } if($Node.boolean) { return [bool]([int]$Node.boolean) } return $Node.InnerText } #endregion |