Module: Ohai::Mixin::AzureMetadata

Defined in:
lib/ohai/mixin/azure_metadata.rb

Overview

This code parses the Azure Instance Metadata API to provide details of the running instance.

The code probes the instance metadata endpoint for available versions, determines the most advanced version known to work and executes the metadata retrieval using that version.

If no compatible version is found, an empty hash is returned.

Instance Method Summary collapse

Instance Method Details

#best_api_versionObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/ohai/mixin/azure_metadata.rb', line 41

def best_api_version
  @api_version ||= begin
    logger.trace("Mixin AzureMetadata: Fetching http://#{AZURE_METADATA_ADDR}/metadata/instance to determine the latest supported metadata release")
    response = http_get("/metadata/instance")
    if response.code == "404"
      logger.trace("Mixin AzureMetadata: Received HTTP 404 from metadata server while determining API version, assuming #{AZURE_SUPPORTED_VERSIONS.last}")
      return AZURE_SUPPORTED_VERSIONS.last
    elsif response.code != "400" # 400 is actually what we want
      raise "Mixin AzureMetadata: Unable to determine Azure metadata version (returned #{response.code} response)"
    end

    # azure returns a list of the 3 latest versions it supports
    versions = parse_json(response.body).fetch("newest-versions", [])
    versions.sort!

    until versions.empty? || AZURE_SUPPORTED_VERSIONS.include?(versions.last)
      pv = versions.pop
      logger.trace("Mixin AzureMetadata: Azure metadata version #{pv} is not present in the versions provided by the Azure Instance Metadata service")
    end

    if versions.empty?
      logger.debug "Mixin AzureMetadata: The short list of supported versions provided by Azure Instance Metadata service doesn't match any known versions to Ohai. Using the latest supported release known to Ohai instead: #{AZURE_SUPPORTED_VERSIONS.last}"
      return AZURE_SUPPORTED_VERSIONS.last
    end

    logger.trace("Mixin AzureMetadata: Latest supported Azure metadata version: #{versions.last}")
    versions.last
  end
end

#fetch_metadata(api_version = nil) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/ohai/mixin/azure_metadata.rb', line 96

def (api_version = nil)
   = "/metadata/instance?api-version=#{best_api_version}"
  logger.trace("Mixin AzureMetadata: Fetching metadata from host #{AZURE_METADATA_ADDR} at #{}")
  response = http_get()
  if response.code == "200"
    parse_json(response.body)
  else
    logger.warn("Mixin AzureMetadata: Received response code #{response.code} requesting metadata")
    nil
  end
end

#http_get(uri) ⇒ Net::HTTP

fetch the meta content with a timeout and the required header and a read timeout of 6s

Parameters:

  • the (String)

    relative uri to fetch from the Azure Metadata Service URL

Returns:

  • (Net::HTTP)


76
77
78
79
80
# File 'lib/ohai/mixin/azure_metadata.rb', line 76

def http_get(uri)
  conn = Net::HTTP.start(AZURE_METADATA_ADDR)
  conn.read_timeout = 6
  conn.get(uri, { "Metadata" => "true" })
end

#parse_json(response_body) ⇒ Hash

parse JSON data from a String to a Hash

Parameters:

  • response_body (String)

    json as string to parse

Returns:

  • (Hash)


87
88
89
90
91
92
93
94
# File 'lib/ohai/mixin/azure_metadata.rb', line 87

def parse_json(response_body)
  data = String(response_body)
  parser = FFI_Yajl::Parser.new
  parser.parse(data)
rescue FFI_Yajl::ParseError
  logger.warn("Mixin AzureMetadata: Metadata response is NOT valid JSON")
  nil
end