DSCResources/POSHOrigin_vSphere_VM/Provisioners/Chef/helpers/_InvokeChefRestMethod.ps1
[CmdletBinding()] param ( [string] # The URI of the end point that needs to used $uri, [hashtable] # Hash of headers that need to be added to the request $headers = @{}, [string] # The accept string. $accept = "application/json", [ValidateSet('GET', 'PUT', 'POST', 'DELETE')] [string] # REST method, defaults to GET $method = "GET", [string] # The body to be passed with a POST or PUT request $body, [string] # Set the content type to be applued to the request $contenttype = "application/json", [string] # Path to where the file should be downloaded to $outfile ) $method = $method.ToUpper() #write-verbose $uri # Function variables $data = $false # Disable SSL checks [Net.ServicePointManager]::ServerCertificateValidationCallback = {$true} # Build up the request using .NET classes as it is not possible to set the correct Accept header using # Invoke-RestMethod # https://connect.microsoft.com/PowerShell/feedback/details/757249/invoke-restmethod-accept-header $request = [System.Net.WebRequest]::create($uri) # Set the request method $request.Method = $method # Set the agent # $request.UserAgent = "Chef Knife/11.8.0 (ruby-1.9.3-p448; ohai-6.20.0; i386-mingw32; +http://opscode.com)" $userAgent = "POSHOrigin/{0} (PowerShell {1})" -f 1, $PSVersionTable.PSVersion.ToString() $request.UserAgent = $userAgent # loop round the headers that have been passed $headers.keys | ForEach-Object { $request.headers.add($_, $headers.item($_)) } # Set the Accept $request.Accept = $accept # if the content type is not false then add it to the request # only set the conttentype if the accept is not '*/*'. this is so that files can # be downloaded from the cookbook if ($contenttype -ne $false -and $accept -ne "*/*") { $request.ContentType = $contenttype } # Prepare the body to pass to the endpoint if ($method -eq "POST" -or $method -eq "PUT") { # get the number of bytes the payload includes $enc = [System.Text.Encoding]::GetEncoding("UTF-8") [byte[]] $bytes = $enc.GetBytes($body) # Set the contentlength of the request $request.ContentLength = $bytes.length # add the body to the request stream $request_stream = [System.IO.Stream] $request.GetRequestStream() $request_stream.Write($bytes, 0, $bytes.length) } #$headers.Add('Accept', $accept) #write-host $method #write-host ($headers | fl * | out-string) #write-host $uri #write-host $userAgent #write-host $body #write-host $contenttype # Send the request to the server and get the response try { $response = $request.GetResponse() # Take the response and read from the stream $response_stream = $response.GetResponseStream() $return = @{} # if an outfile has been set ensure a filestream object is used if ([String]::IsNullOrEmpty($outfile)) { $sr = New-Object system.IO.StreamReader $response_stream # Get information about the api version that is actually in use from the response headers # this will be used to determine how to interpret the response from the server $api_info = @{} $api_header = $response.GetResponseHeader("X-Ops-API-Info") # Split on the ; character to get the components of the API information $components = $api_header -split ";" foreach($component in $components) { # split the component using the = sign $parts = $component -split "=" # now set the api_info hashtable $api_info.$($parts[0]) = $parts[1] } $return.data = $sr.ReadToEnd() #write-verbose $return.data $return.apiversion = $api_info.version } else { $fs = New-Object System.IO.FileStream -ArgumentList $outfile,Create # ensure the file is downloaded in chunks $buffer = New-Object Byte[] 10KB $count = $response_stream.Read($buffer, 0, $buffer.length) while ($count -gt 0) { $fs.Write($buffer, 0, $count) $count = $response_stream.Read($buffer, 0, $buffer.length) } $fs.Flush() $fs.Close() $fs.Dispose() } # build up the return object to be sent to the calling function $return.statuscode = [int32] ($response.StatusCode) } catch [System.Net.WebException] { write-error $_.Exception # An exception has occured # get the body of the response as it will have the error message in it $response = $_.Exception.Response.GetResponseStream() $sr = New-Object System.IO.StreamReader $response # build up the return object to be sent to the calling function $return = @{ data = $sr.ReadToEnd() statuscode = [int32] $($_.Exception.Response.StatusCode) } # determine when to exit and when not to if ([int]$return.StatusCode -ge 500) { $data = $false } } $response_stream.close() $return |