mirror of https://github.com/kubernetes/kops.git
Use AWS SDK to fetch metadata
Previously the EC2 metadata service was straightforward HTTP, but IMDS v2 now requires managing a session token (and is more secure for it). We now use the AWS SDK when retrieving metadata; it automatically supports IMDS v2.
This commit is contained in:
parent
f94371075b
commit
7d7b8969ea
|
@ -27,6 +27,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/denverdino/aliyungo/oss"
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"google.golang.org/api/option"
|
||||
|
@ -69,11 +71,13 @@ func WithBackoff(backoff wait.Backoff) VFSOption {
|
|||
}
|
||||
}
|
||||
|
||||
// ReadLocation reads a file from a vfs URL
|
||||
// ReadFile reads a file from a vfs URL
|
||||
// It supports additional schemes which don't (yet) have full VFS implementations:
|
||||
// metadata: reads from instance metadata on GCE/AWS
|
||||
// http / https: reads from HTTP
|
||||
func (c *VFSContext) ReadFile(location string, options ...VFSOption) ([]byte, error) {
|
||||
ctx := context.TODO()
|
||||
|
||||
var opts vfsOptions
|
||||
// Exponential backoff, starting with 500 milliseconds, doubling each time, 5 steps
|
||||
opts.backoff = wait.Backoff{
|
||||
|
@ -102,8 +106,7 @@ func (c *VFSContext) ReadFile(location string, options ...VFSOption) ([]byte, er
|
|||
httpHeaders["Metadata-Flavor"] = "Google"
|
||||
return c.readHTTPLocation(httpURL, httpHeaders, opts)
|
||||
case "aws":
|
||||
httpURL := "http://169.254.169.254/latest/" + u.Path
|
||||
return c.readHTTPLocation(httpURL, nil, opts)
|
||||
return c.readAWSMetadata(ctx, u.Path)
|
||||
case "digitalocean":
|
||||
httpURL := "http://169.254.169.254/metadata/v1" + u.Path
|
||||
return c.readHTTPLocation(httpURL, nil, opts)
|
||||
|
@ -169,6 +172,24 @@ func (c *VFSContext) BuildVfsPath(p string) (Path, error) {
|
|||
return nil, fmt.Errorf("unknown / unhandled path type: %q", p)
|
||||
}
|
||||
|
||||
// readAWSMetadata reads the specified path from the AWS EC2 metadata service
|
||||
func (c *VFSContext) readAWSMetadata(ctx context.Context, path string) ([]byte, error) {
|
||||
awsSession, err := session.NewSession()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building AWS session: %v", err)
|
||||
}
|
||||
client := ec2metadata.New(awsSession)
|
||||
if strings.HasPrefix(path, "/meta-data/") {
|
||||
s, err := client.GetMetadataWithContext(ctx, strings.TrimPrefix(path, "/meta-data/"))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading from AWS metadata service: %v", err)
|
||||
}
|
||||
return []byte(s), nil
|
||||
}
|
||||
// There are others (e.g. user-data), but as we don't use them yet let's not expose them
|
||||
return nil, fmt.Errorf("unhandled aws metadata path %q", path)
|
||||
}
|
||||
|
||||
// readHTTPLocation reads an http (or https) url.
|
||||
// It returns the contents, or an error on any non-200 response. On a 404, it will return os.ErrNotExist
|
||||
// It will retry a few times on a 500 class error
|
||||
|
|
Loading…
Reference in New Issue