-
Notifications
You must be signed in to change notification settings - Fork 78
/
aws.go
138 lines (123 loc) · 4.27 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
128
129
130
131
132
133
134
135
136
137
138
// Package aws implements wrappers for AWS API calls.
package aws
import (
"errors"
"fmt"
"os"
"path/filepath"
"github.com/aws/aws-k8s-tester/pkg/fileutil"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/sts"
"go.uber.org/zap"
"k8s.io/client-go/util/homedir"
)
// Config defines a top-level AWS API configuration to create a session.
type Config struct {
// Logger is the log object.
Logger *zap.Logger
// DebugAPICalls is true to log all AWS API call debugging messages.
DebugAPICalls bool
// Region is a separate AWS geographic area for EKS service.
// Each AWS Region has multiple, isolated locations known as Availability Zones.
Region string
// ResolverURL is a custom resolver URL.
ResolverURL string
// SigningName is the API signing name.
SigningName string
}
// New creates a new AWS session.
// Specify a custom endpoint for tests.
func New(cfg *Config) (ss *session.Session, stsOutput *sts.GetCallerIdentityOutput, awsCredsPath string, err error) {
if cfg == nil {
return nil, nil, "", errors.New("got empty config")
}
if cfg.Logger == nil {
return nil, nil, "", fmt.Errorf("missing logger")
}
if cfg.Region == "" {
return nil, nil, "", fmt.Errorf("missing region")
}
awsConfig := aws.Config{
Region: aws.String(cfg.Region),
CredentialsChainVerboseErrors: aws.Bool(true),
Logger: toLogger(cfg.Logger),
}
// Credential is the path to the shared credentials file.
//
// If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the
// env value is empty will default to current user's home directory.
// Linux/OSX: "$HOME/.aws/credentials"
// Windows: "%USERPROFILE%\.aws\credentials"
//
// See https://pkg.go.dev/github.com/aws/aws-sdk-go/aws/credentials#SharedCredentialsProvider.
// See https://pkg.go.dev/github.com/aws/aws-sdk-go/aws/session#hdr-Environment_Variables.
awsCredsPath = filepath.Join(homedir.HomeDir(), ".aws", "credentials")
if os.Getenv("AWS_SHARED_CREDENTIALS_FILE") != "" {
awsCredsPath = os.Getenv("AWS_SHARED_CREDENTIALS_FILE")
}
if fileutil.Exist(awsCredsPath) {
cfg.Logger.Info("creating session from AWS cred file", zap.String("path", awsCredsPath))
// TODO: support temporary credentials with refresh mechanism
} else {
cfg.Logger.Info("cannot find AWS cred file", zap.String("path", awsCredsPath))
if os.Getenv("AWS_ACCESS_KEY_ID") == "" ||
os.Getenv("AWS_SECRET_ACCESS_KEY") == "" {
cfg.Logger.Info("cannot create a session from env vars")
} else {
cfg.Logger.Info("creating a session from env vars")
}
}
if cfg.DebugAPICalls {
lvl := aws.LogDebug |
aws.LogDebugWithEventStreamBody |
aws.LogDebugWithHTTPBody |
aws.LogDebugWithRequestRetries |
aws.LogDebugWithRequestErrors
awsConfig.LogLevel = &lvl
}
var stsSession *session.Session
stsSession, err = session.NewSession(&awsConfig)
if err != nil {
return nil, nil, "", err
}
stsSvc := sts.New(stsSession)
stsOutput, err = stsSvc.GetCallerIdentity(&sts.GetCallerIdentityInput{})
if err != nil {
return nil, nil, "", err
}
cfg.Logger.Info(
"creating AWS session",
zap.String("account-id", *stsOutput.Account),
zap.String("user-id", *stsOutput.UserId),
zap.String("arn", *stsOutput.Arn),
)
resolver := endpoints.DefaultResolver()
if cfg.ResolverURL != "" && cfg.SigningName == "" {
return nil, nil, "", fmt.Errorf("got empty signing name for resolver %q", cfg.ResolverURL)
}
// support test endpoint (e.g. https://api.beta.us-west-2.wesley.amazonaws.com)
if cfg.ResolverURL != "" {
cfg.Logger.Info(
"setting custom resolver",
zap.String("resolver-url", cfg.ResolverURL),
zap.String("signing-name", cfg.SigningName),
)
resolver = endpoints.ResolverFunc(func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
if service == "eks" {
return endpoints.ResolvedEndpoint{
URL: cfg.ResolverURL,
SigningName: cfg.SigningName,
}, nil
}
return endpoints.DefaultResolver().EndpointFor(service, region, optFns...)
})
}
awsConfig.EndpointResolver = resolver
ss, err = session.NewSession(&awsConfig)
if err != nil {
return nil, nil, "", err
}
return ss, stsOutput, awsCredsPath, err
}