]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame - vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / aws / aws-sdk-go / aws / ec2metadata / service.go
CommitLineData
bae9f6d2
JC
1// Package ec2metadata provides the client for making API calls to the
2// EC2 Metadata service.
15c0b25d
AP
3//
4// This package's client can be disabled completely by setting the environment
5// variable "AWS_EC2_METADATA_DISABLED=true". This environment variable set to
6// true instructs the SDK to disable the EC2 Metadata client. The client cannot
107c1cdb 7// be used while the environment variable is set to true, (case insensitive).
bae9f6d2
JC
8package ec2metadata
9
10import (
11 "bytes"
12 "errors"
13 "io"
14 "net/http"
15c0b25d
AP
15 "os"
16 "strings"
bae9f6d2
JC
17 "time"
18
19 "github.com/aws/aws-sdk-go/aws"
20 "github.com/aws/aws-sdk-go/aws/awserr"
21 "github.com/aws/aws-sdk-go/aws/client"
22 "github.com/aws/aws-sdk-go/aws/client/metadata"
15c0b25d 23 "github.com/aws/aws-sdk-go/aws/corehandlers"
bae9f6d2
JC
24 "github.com/aws/aws-sdk-go/aws/request"
25)
26
27// ServiceName is the name of the service.
28const ServiceName = "ec2metadata"
15c0b25d 29const disableServiceEnvVar = "AWS_EC2_METADATA_DISABLED"
bae9f6d2
JC
30
31// A EC2Metadata is an EC2 Metadata service Client.
32type EC2Metadata struct {
33 *client.Client
34}
35
36// New creates a new instance of the EC2Metadata client with a session.
37// This client is safe to use across multiple goroutines.
38//
39//
40// Example:
41// // Create a EC2Metadata client from just a session.
42// svc := ec2metadata.New(mySession)
43//
44// // Create a EC2Metadata client with additional configuration
45// svc := ec2metadata.New(mySession, aws.NewConfig().WithLogLevel(aws.LogDebugHTTPBody))
46func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2Metadata {
47 c := p.ClientConfig(ServiceName, cfgs...)
48 return NewClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
49}
50
51// NewClient returns a new EC2Metadata client. Should be used to create
52// a client when not using a session. Generally using just New with a session
53// is preferred.
54//
55// If an unmodified HTTP client is provided from the stdlib default, or no client
56// the EC2RoleProvider's EC2Metadata HTTP client's timeout will be shortened.
57// To disable this set Config.EC2MetadataDisableTimeoutOverride to false. Enabled by default.
58func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string, opts ...func(*client.Client)) *EC2Metadata {
59 if !aws.BoolValue(cfg.EC2MetadataDisableTimeoutOverride) && httpClientZero(cfg.HTTPClient) {
60 // If the http client is unmodified and this feature is not disabled
61 // set custom timeouts for EC2Metadata requests.
62 cfg.HTTPClient = &http.Client{
63 // use a shorter timeout than default because the metadata
64 // service is local if it is running, and to fail faster
65 // if not running on an ec2 instance.
66 Timeout: 5 * time.Second,
67 }
68 }
69
70 svc := &EC2Metadata{
71 Client: client.New(
72 cfg,
73 metadata.ClientInfo{
74 ServiceName: ServiceName,
107c1cdb 75 ServiceID: ServiceName,
bae9f6d2
JC
76 Endpoint: endpoint,
77 APIVersion: "latest",
78 },
79 handlers,
80 ),
81 }
82
83 svc.Handlers.Unmarshal.PushBack(unmarshalHandler)
84 svc.Handlers.UnmarshalError.PushBack(unmarshalError)
85 svc.Handlers.Validate.Clear()
86 svc.Handlers.Validate.PushBack(validateEndpointHandler)
87
15c0b25d
AP
88 // Disable the EC2 Metadata service if the environment variable is set.
89 // This shortcirctes the service's functionality to always fail to send
90 // requests.
91 if strings.ToLower(os.Getenv(disableServiceEnvVar)) == "true" {
92 svc.Handlers.Send.SwapNamed(request.NamedHandler{
93 Name: corehandlers.SendHandler.Name,
94 Fn: func(r *request.Request) {
107c1cdb
ND
95 r.HTTPResponse = &http.Response{
96 Header: http.Header{},
97 }
15c0b25d
AP
98 r.Error = awserr.New(
99 request.CanceledErrorCode,
100 "EC2 IMDS access disabled via "+disableServiceEnvVar+" env var",
101 nil)
102 },
103 })
104 }
105
bae9f6d2
JC
106 // Add additional options to the service config
107 for _, option := range opts {
108 option(svc.Client)
109 }
110
111 return svc
112}
113
114func httpClientZero(c *http.Client) bool {
115 return c == nil || (c.Transport == nil && c.CheckRedirect == nil && c.Jar == nil && c.Timeout == 0)
116}
117
118type metadataOutput struct {
119 Content string
120}
121
122func unmarshalHandler(r *request.Request) {
123 defer r.HTTPResponse.Body.Close()
124 b := &bytes.Buffer{}
125 if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
126 r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err)
127 return
128 }
129
130 if data, ok := r.Data.(*metadataOutput); ok {
131 data.Content = b.String()
132 }
133}
134
135func unmarshalError(r *request.Request) {
136 defer r.HTTPResponse.Body.Close()
137 b := &bytes.Buffer{}
138 if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
139 r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err)
140 return
141 }
142
143 // Response body format is not consistent between metadata endpoints.
144 // Grab the error message as a string and include that as the source error
145 r.Error = awserr.New("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String()))
146}
147
148func validateEndpointHandler(r *request.Request) {
149 if r.ClientInfo.Endpoint == "" {
150 r.Error = aws.ErrMissingEndpoint
151 }
152}