-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaws.go
127 lines (108 loc) · 3.2 KB
/
aws.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package cloudinfo
import (
"encoding/json"
"errors"
"strings"
)
type awsProvider struct {
cache *cachedHttp
info *Info
token string
}
type awsIdentity struct {
AccountId string `json:"accountId"` // 12 digits
Architecture string `json:"architecture"` // x86_64
AvailabilityZone string `json:"availabilityZone"` // ap-northeast-1c
// "billingProducts" : null,
// "devpayProductCodes" : null,
// "marketplaceProductCodes" : null,
ImageId string `json:"imageId"` // ami-xxx
InstanceId string `json:"instanceId"` // i-xxx
InstanceType string `json:"instanceType"` // m5a.large
// "kernelId" : null,
// "pendingTime" : "2021-10-17T13:39:07Z",
PrivateIp string `json:"privateIp"`
PublicIp string `json:"-"`
// "ramdiskId" : null,
Region string `json:"region"` // ap-northeast-1
Version string `json:"version"` // 2017-09-30
Hostname string `json:"-"`
}
func (a *awsProvider) Name() string {
return "aws"
}
func (a *awsProvider) Fetch() (*Info, error) {
// initialize a.res
if a.info == nil {
a.info = &Info{}
}
err := a.getToken()
if err != nil {
return a.info, err
}
err = a.getIdentity()
if err != nil {
return a.info, err
}
return a.info, nil
}
// getToken fetches an api token from the aws server and stores it into a.token
func (a *awsProvider) getToken() error {
if a.token != "" {
// already have a token
return nil
}
tokenB, _, err := a.cache.PutWithHeaders("http://169.254.169.254/latest/api/token", map[string]string{"X-aws-ec2-metadata-token-ttl-seconds": "60"})
if err != nil {
return err
}
token := strings.TrimSpace(string(tokenB))
if token == "" {
return errors.New("could not fetch aws token")
}
a.token = token
return nil
}
func (a *awsProvider) getMeta(p string) (string, error) {
res, _, err := a.cache.GetWithHeaders("http://169.254.169.254/latest/meta-data/"+p, map[string]string{"X-aws-ec2-metadata-token": a.token})
return strings.TrimSpace(string(res)), err
}
func (a *awsProvider) getIdentity() error {
res, _, err := a.cache.GetWithHeaders("http://169.254.169.254/latest/dynamic/instance-identity/document", map[string]string{"X-aws-ec2-metadata-token": a.token})
if err != nil {
return err
}
var info *awsIdentity
err = json.Unmarshal(res, &info)
if err != nil {
return err
}
// let's try to fill any missing info from the identity
a.fill(&info.Hostname, "hostname")
a.fill(&info.InstanceType, "instance-type")
a.fill(&info.AvailabilityZone, "placement/availability-zone")
a.fill(&info.Region, "placement/region")
a.fill(&info.PublicIp, "public-ipv4")
a.fill(&info.PrivateIp, "local-ipv4")
// fill a.info with the info here
a.info.Hostname = info.Hostname
a.info.AccountId = info.AccountId
a.info.Architecture = info.Architecture
a.info.Image = info.ImageId
a.info.ID = info.InstanceId
a.info.Type = info.InstanceType
a.info.PrivateIP.addString(info.PrivateIp)
a.info.PublicIP.addString(info.PublicIp)
a.info.Location = makeLocation("cloud", "aws", "region", info.Region, "zone", info.AvailabilityZone)
a.info.fix()
return nil
}
func (a *awsProvider) fill(s *string, field string) error {
if *s != "" {
// already got the data
return nil
}
var err error
*s, err = a.getMeta(field)
return err
}