1// Copyright 2014 Google Inc. All rights reserved. 2// Use of this source code is governed by the Apache 2.0 3// license that can be found in the LICENSE file. 4 5package internal 6 7// This file has code for accessing metadata. 8// 9// References: 10// https://cloud.google.com/compute/docs/metadata 11 12import ( 13 "fmt" 14 "io/ioutil" 15 "net/http" 16 "net/url" 17) 18 19const ( 20 metadataHost = "metadata" 21 metadataPath = "/computeMetadata/v1/" 22) 23 24var ( 25 metadataRequestHeaders = http.Header{ 26 "Metadata-Flavor": []string{"Google"}, 27 } 28) 29 30// TODO(dsymonds): Do we need to support default values, like Python? 31func mustGetMetadata(key string) []byte { 32 b, err := getMetadata(key) 33 if err != nil { 34 panic(fmt.Sprintf("Metadata fetch failed for '%s': %v", key, err)) 35 } 36 return b 37} 38 39func getMetadata(key string) ([]byte, error) { 40 // TODO(dsymonds): May need to use url.Parse to support keys with query args. 41 req := &http.Request{ 42 Method: "GET", 43 URL: &url.URL{ 44 Scheme: "http", 45 Host: metadataHost, 46 Path: metadataPath + key, 47 }, 48 Header: metadataRequestHeaders, 49 Host: metadataHost, 50 } 51 resp, err := http.DefaultClient.Do(req) 52 if err != nil { 53 return nil, err 54 } 55 defer resp.Body.Close() 56 if resp.StatusCode != 200 { 57 return nil, fmt.Errorf("metadata server returned HTTP %d", resp.StatusCode) 58 } 59 return ioutil.ReadAll(resp.Body) 60} 61