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