/
metadata.go
103 lines (93 loc) · 2.14 KB
/
metadata.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package ec2dynamicdata
import (
"fmt"
"io/ioutil"
"net"
"net/http"
)
const metaDataEndpoint = "http://169.254.169.254/latest/meta-data/"
// Item defines a single resource that can be retrieved from a met-data
// endpoint
type Item int
// This is an incomplete list because other items have sub items. So if you
// need them just modify the source to have a support to it. But probably it's
// an overkill and you'll not going to need it :)
const (
AmiId Item = iota + 1
AmiLaunchIndex
AmiManifestPath
Hostname
InstanceAction
InstanceId
InstanceType
LocalHostname
LocalIPv4
Mac
Profile
PublicIPv4
PublicHostname
ReservationId
SecurityGroups
)
// String implements the Stringer interface. It's also used to construct the
// meta-data endpoint
func (i Item) String() string {
switch i {
case AmiId:
return "ami-id"
case AmiLaunchIndex:
return "ami-launch-index"
case AmiManifestPath:
return "ami-manifest-path"
case Hostname:
return "hostname"
case InstanceAction:
return "instance-action"
case InstanceId:
return "instance-id"
case InstanceType:
return "instance-type"
case LocalHostname:
return "local-hostname"
case LocalIPv4:
return "local-ipv4"
case Mac:
return "mac"
case Profile:
return "profile"
case PublicIPv4:
return "public-ipv4"
case PublicHostname:
return "public-hostname"
case ReservationId:
return "reservation-id"
case SecurityGroups:
return "security-groups"
default:
return "unknown"
}
}
// GetMetadata returns the value for the given meta data item.
func GetMetadata(item Item) (string, error) {
client := http.Client{
Transport: &http.Transport{
// timeout only for dialing, because if we are not in ec2, this will timeout
Dial: func(network, addr string) (net.Conn, error) {
return net.DialTimeout(network, addr, DialTimeout)
},
},
}
resp, err := client.Get(metaDataEndpoint + item.String())
if err != nil {
return "", wrapEC2Error(err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return "", fmt.Errorf("err: status code (%d)", resp.StatusCode)
}
out, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(out), nil
}