Class/PanResponse.ps1
class PanResponse { <# Decision to include $WRContent... properties in this class came through inconsistencies in the PAN-OS XML-API which necessitated the need to get at more raw response data. In one example, submitting an operational command via API: <request><license><fetch><auth-code>1234-valid-authcode-needed</auth-code></fetch></license></request> the API does *not* return valid XML, but *does* set the Content-Type: application/xml and returns the raw string: VM Device License installed. Restarting pan services. Running this through the XML constructors (based on Content-Type: application/xml) produces errors. Code/cmdlets performing this admittedly obscure request operation can at least access and test for response using $WrStatus and $WrContent. There will no doubt be other inconsistencies and examples in the future where untouched responses are desirable. #> # WebRequest/HTTP Status - comes directly from WebRequestObject [Int] $WRStatus # WebRequest/HTTP Status Description - comes directly from WebRequestObject [String] $WRStatusDescription # WebRequest/HTTP Headers - comes directly from WebRequestObject. The *headers* [Object] $WRHeaders # WebRequest/HTTP Content - comes directly from WebRequestObject. The raw content *body* [String] $WRContent # WebRequest/HTTP RawContent - comes directly from WebRequestObject. The raw content *headers* AND *body* [String] $WRRawContent # PAN API <response> status attribute, examples "success" or "error" [String] $Status # PAN API <response> code attribute, used to further describe successes and errors [Int] $Code # PAN API <response><msg>, commonly populated during errors [String] $Message # PAN API <response> element and all children. The goods. [Object] $Response # PAN API <response><result> element and all children. This property is deprecated and should not be used. # Preserved for < PowerPAN 0.5.0 compatibility within existing scripts and will be removed in future. hidden [Object] $Result # Parent PanDevice / Source of response [PanDevice] $Device # Default Constructor PanResponse() { } # Constructor PanResponse([Microsoft.PowerShell.Commands.WebResponseObject] $WebResponse, [PanDevice] $Device) { $this.WRStatus = $WebResponse.StatusCode $this.WRStatusDescription = $WebResponse.StatusDescription $this.WRHeaders = $WebResponse.Headers $this.WRContent = $WebResponse.Content $this.WRRawContent = $WebResponse.RawContent $this.Device = $Device if($WebResponse.Headers.'Content-Type' -Match 'application\/xml') { Write-Debug $($MyInvocation.MyCommand.Name + ': Content-Type: application/xml') # Turn the XML body into an XmlDocument object with XmlDocument doing the parse heavy lifting # Interesting note, [xml] is the PowerShell type accelerator (alias) for [System.Xml.XmlDocument]. Let's be verbose. $XDoc = [System.Xml.XmlDocument]$WebResponse.Content # Populate PanResponse with XML body details # Status $this.Status = $XDoc.Item('response').GetAttribute('status') # Code $this.Code = $XDoc.Item('response').GetAttribute('code') # Message # Variety A: msg contains no other elements # Example: Commits with no pending changes return <msg>There are no changes to commit.</msg> which is mapped to a string. if($XDoc.Item('response').msg -is [String]) { $this.Message = $XDoc.Item('response').msg } # Variety B: msg contains other nested elements # Example: ??? <msg><line>Some Message</line></msg> elseif($XDoc.Item('response').msg -is [System.Xml.XmlElement]) { $this.Message = $XDoc.Item('response').msg.InnerText } # Response $this.Response = $XDoc.Item('response') # Result (deprecated, but preserved for compatibility for now) $this.Result = $XDoc.Item('response').Item('result') } <# elseif ($WebResponse.Headers.'Content-Type' -Match 'application\/json') { Write-Debug $($MyInvocation.MyCommand.Name + ': Content-Type: application/json') # Turn the JSON body into a JSON object $JsonContentObj = ConvertFrom-Json -InputObject $WebResponse.Content # Populate with JSON body details $this.Status = $JsonContentObj.response.status $this.Code = $JsonContentObj.response.code $this.Message = $JsonContentObj.response.msg $this.Result = $JsonContentObj.response.result } #> } } |