-
Notifications
You must be signed in to change notification settings - Fork 326
/
utils.go
128 lines (108 loc) · 2.79 KB
/
utils.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
128
package utils
import (
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"time"
"github.com/rexray/rexray/libstorage/api/types"
"github.com/rexray/rexray/libstorage/drivers/storage/ebs"
)
const (
raddr = "169.254.169.254"
mdtURL = "http://" + raddr + "/latest/meta-data/"
iidURL = "http://" + raddr + "/latest/dynamic/instance-identity/document"
bdmURL = "http://" + raddr + "/latest/meta-data/block-device-mapping/"
)
// IsEC2Instance returns a flag indicating whether the executing host is an EC2
// instance based on whether or not the metadata URL can be accessed.
func IsEC2Instance(ctx types.Context) (bool, error) {
client := &http.Client{Timeout: time.Duration(1 * time.Second)}
req, err := http.NewRequest(http.MethodHead, mdtURL, nil)
if err != nil {
return false, err
}
res, err := doRequestWithClient(ctx, client, req)
if err != nil {
if terr, ok := err.(net.Error); ok && terr.Timeout() {
return false, nil
}
return false, err
}
if res.StatusCode >= 200 || res.StatusCode <= 299 {
return true, nil
}
return false, nil
}
type instanceIdentityDoc struct {
InstanceID string `json:"instanceId,omitempty"`
Region string `json:"region,omitempty"`
AvailabilityZone string `json:"availabilityZone,omitempty"`
}
// InstanceID returns the instance ID for the local host.
func InstanceID(
ctx types.Context,
driverName string) (*types.InstanceID, error) {
req, err := http.NewRequest(http.MethodGet, iidURL, nil)
if err != nil {
return nil, err
}
res, err := doRequest(ctx, req)
if err != nil {
return nil, err
}
defer res.Body.Close()
iid := instanceIdentityDoc{}
dec := json.NewDecoder(res.Body)
if err := dec.Decode(&iid); err != nil {
return nil, err
}
return &types.InstanceID{
ID: iid.InstanceID,
Driver: driverName,
Fields: map[string]string{
ebs.InstanceIDFieldRegion: iid.Region,
ebs.InstanceIDFieldAvailabilityZone: iid.AvailabilityZone,
},
}, nil
}
// BlockDevices returns the EBS devices attached to the local host.
func BlockDevices(ctx types.Context) ([]byte, error) {
req, err := http.NewRequest(http.MethodGet, bdmURL, nil)
if err != nil {
return nil, err
}
res, err := doRequest(ctx, req)
if err != nil {
return nil, err
}
defer res.Body.Close()
buf, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
return buf, nil
}
// BlockDeviceName returns the name of the provided EBS device.
func BlockDeviceName(
ctx types.Context,
device string) ([]byte, error) {
req, err := http.NewRequest(
http.MethodGet,
fmt.Sprintf("%s%s", bdmURL, device),
nil)
if err != nil {
return nil, err
}
res, err := doRequest(ctx, req)
if err != nil {
return nil, err
}
defer res.Body.Close()
buf, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
return buf, nil
}