google-cloud-powershell icon indicating copy to clipboard operation
google-cloud-powershell copied to clipboard

Get-GceMetadata does not raise errors

Open chilversc opened this issue 5 years ago • 1 comments

When using the Get-GceMetadata cmdlet it doesn't seem to write errors to the error stream or throw exceptions when the metadata server returns an error such as 404.

Currently there doesn't seem to be a reasonable way to detect that there was an error.

Steps to reproduce

$ErrorActionPreference = "Continue"
Write-Host "Test 1"
$Result = Get-GceMetadata -Path instance/attributes/non-existent
Write-Host "Result: ${Result}"
$ErrorActionPreference = "Stop"
Write-Host "Test 2"
$Result = Get-GceMetadata -Path instance/attributes/non-existent
Write-Host "Result: ${Result}"

Expected result

Test 1 should output a blank result and the console should show the error text (normally in red). Test 2 shouldn't show any output as script should halt

Actual result

The error response is stored in $Result. When writing the result to the console it dumps a large block of HTML that contains a description of the error (e.g. 404).

Workarounds

Invoke-RestMethod

function Get-Metadata {
  [CmdletBinding()]
  param (
    [Parameter($Mandatory = $true)] [string] $Path
  )
  Invoke-RestMethod -Headers @{ "Metadata-Flavor" = "Google" } "http://metadata.google.internal/computeMetadata/v1/$Path"
}

$Result = Get-Metadata -Path instance/attributes/non-existent

Get-GceInstance

Many of the properties you need from the metadata are available directly from the instance object model. However, obtaining a specific metadata attribute by name can be a awkward.

function Get-MetadataAttribute {
  [CmdletBinding()]
  param (
    [Parameter($Mandatory = $true)] [string] $Name
  )
  $Instance = Get-GceInstance
  $Item = ($Instance.Metadata.Items | Where-Object Key -eq $Name)
  if ($Item -eq $null) {
    Write-Error "Metadata does not contain an attribute named '${Name}'"
  }
  return $Item.Value
}

chilversc avatar Jul 09 '20 22:07 chilversc

Looks like https://github.com/GoogleCloudPlatform/google-cloud-powershell/blob/b0549f98b2a150830ff6ddf10c66c3252df7626d/Google.PowerShell/Compute/GceMetadataCmdlet.cs#L161 is missing a call to response.EnsureSuccessCode() before accessing response.Content.

chilversc avatar Jul 10 '20 00:07 chilversc