Skip to content

Commit e6b1343

Browse files
authored
Refactoring SDK's code generation patterns (#298)
Updates the SDK's code generation pattern with several improvements to improve discoverability, and consistency in client naming. * Standardizing of the service model's ServiceID for the name of the service client's package. * Adds an operation `Response` type that is in addition from the operation's `Output` parameters. This prevents collisions between SDK response metadata, marshaling methods, and modeled output parameters. * Refactor service client package's client name to be named Client instead of the service's short name. Removes the stuttering of client package and type, (e.g. s3.S3 becomes s3.Client) * Fix service endpoint lookups use the the service's modeled EndpointID instead of inconsistent service name. * Generate API operations into their own file instead of all operations and parameter types being generated into a single file. This improves readability of individual source files for documentation reference. Non-input/output types are still generated into a single file. This change also fixes several occurrences of incorrectly generated API operation input/output type names. * Removes aws/endpoints Service identifiers from endpoint list. These were not actually service identifiers, but EndpointsID. In addition the values modeled by the services were unstable, and could change causing breaking changes in the SDK's aws/endpoints package. The service client package's `EndpointsID` const should be used instead. * Move Paginate method from the initialized Request type into its own construct via the New<RequestType>Paginator function to create the request paginator. (e.g. req.Paginate becomes NewListObjectsPaginator(req)) Fix #294 #282 #275
1 parent 1f1e9be commit e6b1343

File tree

7,511 files changed

+1362876
-1304998
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

7,511 files changed

+1362876
-1304998
lines changed

aws/client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
// Metadata wraps immutable data from the Client structure.
88
type Metadata struct {
99
ServiceName string
10+
ServiceID string
11+
EndpointsID string
1012
APIVersion string
1113

1214
Endpoint string

aws/ec2metadata/api.go

Lines changed: 0 additions & 162 deletions
This file was deleted.

aws/ec2metadata/api_client.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Package ec2metadata provides the client for making API calls to the
2+
// EC2 Instance Metadata service.
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
7+
// be used while the environemnt variable is set to true, (case insensitive).
8+
package ec2metadata
9+
10+
import (
11+
"bytes"
12+
"errors"
13+
"io"
14+
"net/http"
15+
"os"
16+
"strings"
17+
18+
"github.com/aws/aws-sdk-go-v2/aws"
19+
"github.com/aws/aws-sdk-go-v2/aws/awserr"
20+
"github.com/aws/aws-sdk-go-v2/aws/defaults"
21+
)
22+
23+
const disableServiceEnvVar = "AWS_EC2_METADATA_DISABLED"
24+
25+
// A Client is an EC2 Instance Metadata service Client.
26+
type Client struct {
27+
*aws.Client
28+
}
29+
30+
// New creates a new instance of the Client client with a Config.
31+
// This client is safe to use across multiple goroutines.
32+
//
33+
// Example:
34+
// // Create a Client client from just a config.
35+
// svc := ec2metadata.New(cfg)
36+
func New(config aws.Config) *Client {
37+
svc := &Client{
38+
Client: aws.NewClient(
39+
config,
40+
aws.Metadata{
41+
ServiceName: "EC2 Instance Metadata",
42+
ServiceID: "EC2InstanceMetadata",
43+
EndpointsID: "ec2metadata",
44+
APIVersion: "latest",
45+
},
46+
),
47+
}
48+
49+
svc.Handlers.Unmarshal.PushBack(unmarshalHandler)
50+
svc.Handlers.UnmarshalError.PushBack(unmarshalError)
51+
svc.Handlers.Validate.Clear()
52+
svc.Handlers.Validate.PushBack(validateEndpointHandler)
53+
54+
// Disable the EC2 Instance Metadata service if the environment variable is
55+
// set. This shortcirctes the service's functionality to always fail to
56+
// send requests.
57+
if strings.ToLower(os.Getenv(disableServiceEnvVar)) == "true" {
58+
svc.Handlers.Send.SwapNamed(aws.NamedHandler{
59+
Name: defaults.SendHandler.Name,
60+
Fn: func(r *aws.Request) {
61+
r.HTTPResponse = &http.Response{
62+
Header: http.Header{},
63+
}
64+
r.Error = awserr.New(
65+
aws.ErrCodeRequestCanceled,
66+
"EC2 IMDS access disabled via "+disableServiceEnvVar+" env var",
67+
nil)
68+
},
69+
})
70+
}
71+
72+
return svc
73+
}
74+
75+
func httpClientZero(c *http.Client) bool {
76+
return c == nil || (c.Transport == nil && c.CheckRedirect == nil && c.Jar == nil && c.Timeout == 0)
77+
}
78+
79+
type metadataOutput struct {
80+
Content string
81+
}
82+
83+
func unmarshalHandler(r *aws.Request) {
84+
defer r.HTTPResponse.Body.Close()
85+
b := &bytes.Buffer{}
86+
if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
87+
r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err)
88+
return
89+
}
90+
91+
if data, ok := r.Data.(*metadataOutput); ok {
92+
data.Content = b.String()
93+
}
94+
}
95+
96+
func unmarshalError(r *aws.Request) {
97+
defer r.HTTPResponse.Body.Close()
98+
b := &bytes.Buffer{}
99+
if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
100+
r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err)
101+
return
102+
}
103+
104+
// Response body format is not consistent between metadata endpoints.
105+
// Grab the error message as a string and include that as the source error
106+
r.Error = awserr.New("EC2MetadataError", "failed to make Client request", errors.New(b.String()))
107+
}
108+
109+
func validateEndpointHandler(r *aws.Request) {
110+
if r.Metadata.Endpoint == "" {
111+
r.Error = aws.ErrMissingEndpoint
112+
}
113+
}

0 commit comments

Comments
 (0)