Compare commits
No commits in common. "750a4dc3db46ec9fd9095822429e2be853d72746" and "13a8481f221a5f7f19dfcaf78a0063b041fe2dc7" have entirely different histories.
750a4dc3db
...
13a8481f22
9
.idea/legalgo-BE-go.iml
generated
9
.idea/legalgo-BE-go.iml
generated
@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="WEB_MODULE" version="4">
|
|
||||||
<component name="Go" enabled="true" />
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
119
.idea/workspace.xml
generated
119
.idea/workspace.xml
generated
@ -1,119 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="AutoImportSettings">
|
|
||||||
<option name="autoReloadType" value="ALL" />
|
|
||||||
</component>
|
|
||||||
<component name="ChangeListManager">
|
|
||||||
<list default="true" id="e5a7c631-b0eb-4bcf-9341-cd30afbc8d51" name="Changes" comment="">
|
|
||||||
<change afterPath="$PROJECT_DIR$/.idea/legalgo-BE-go.iml" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/config/auth.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/config/configs.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/config/db.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/config/http.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/config/jwt.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/config/module.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/config/oss.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/config/server.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/development.yaml" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/internal/accessor/oss/oss.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/internal/accessor/oss/upload.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/internal/api/http/oss/module.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/internal/api/http/oss/upload.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/internal/domain/oss/oss.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/internal/services/oss/impl.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/internal/services/oss/init.go" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/k8s/staging/deployment.yaml" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/k8s/staging/ingress.yaml" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/k8s/staging/namespace.yaml" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/k8s/staging/service.yaml" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/cmd/gorm/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/cmd/gorm/main.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/cmd/legalgo/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/cmd/legalgo/main.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/database/new_db.go" beforeDir="false" afterPath="$PROJECT_DIR$/database/new_db.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/go.mod" beforeDir="false" afterPath="$PROJECT_DIR$/go.mod" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/go.sum" beforeDir="false" afterPath="$PROJECT_DIR$/go.sum" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/internal/accessor/module.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/accessor/module.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/internal/api/http/router.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/api/http/router.go" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/internal/services/module.go" beforeDir="false" afterPath="$PROJECT_DIR$/internal/services/module.go" afterDir="false" />
|
|
||||||
</list>
|
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
|
||||||
</component>
|
|
||||||
<component name="FileTemplateManagerImpl">
|
|
||||||
<option name="RECENT_TEMPLATES">
|
|
||||||
<list>
|
|
||||||
<option value="Go File" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="GOROOT" url="file:///opt/homebrew/Cellar/go/1.24.0/libexec" />
|
|
||||||
<component name="Git.Settings">
|
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
|
||||||
</component>
|
|
||||||
<component name="MarkdownSettingsMigration">
|
|
||||||
<option name="stateVersion" value="1" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectId" id="2tlQuDgnVjD2XCHsYVtzhu4hYTb" />
|
|
||||||
<component name="ProjectViewState">
|
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
|
||||||
<option name="showLibraryContents" value="true" />
|
|
||||||
</component>
|
|
||||||
<component name="PropertiesComponent"><![CDATA[{
|
|
||||||
"keyToString": {
|
|
||||||
"ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
|
||||||
"DefaultGoTemplateProperty": "Go File",
|
|
||||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
|
||||||
"RunOnceActivity.go.formatter.settings.were.checked": "true",
|
|
||||||
"RunOnceActivity.go.migrated.go.modules.settings": "true",
|
|
||||||
"RunOnceActivity.go.modules.go.list.on.any.changes.was.set": "true",
|
|
||||||
"RunOnceActivity.go.vendoring.notification.had.been.shown": "true",
|
|
||||||
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
|
||||||
"WebServerToolWindowFactoryState": "false",
|
|
||||||
"configurable..is.expanded": "false",
|
|
||||||
"configurable.GoLibrariesConfigurable.is.expanded": "true",
|
|
||||||
"go.import.settings.migrated": "true",
|
|
||||||
"go.sdk.automatically.set": "true",
|
|
||||||
"last_opened_file_path": "/Users/aditya.siregar/Personal/Altru/legalgo-news/legalgo-BE-go",
|
|
||||||
"node.js.detected.package.eslint": "true",
|
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
|
||||||
"settings.editor.selected.configurable": "go.sdk"
|
|
||||||
}
|
|
||||||
}]]></component>
|
|
||||||
<component name="RecentsManager">
|
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
|
||||||
<recent name="$PROJECT_DIR$" />
|
|
||||||
<recent name="$PROJECT_DIR$/internal/api/http/oss" />
|
|
||||||
<recent name="$PROJECT_DIR$/internal/services" />
|
|
||||||
<recent name="$PROJECT_DIR$/internal/accessor" />
|
|
||||||
<recent name="$PROJECT_DIR$/config" />
|
|
||||||
</key>
|
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
|
||||||
<recent name="$PROJECT_DIR$/internal/api/http/oss" />
|
|
||||||
</key>
|
|
||||||
</component>
|
|
||||||
<component name="RunManager">
|
|
||||||
<configuration name="go build legalgo-BE-go/cmd/legalgo" type="GoApplicationRunConfiguration" factoryName="Go Application" temporary="true" nameIsGenerated="true">
|
|
||||||
<module name="legalgo-BE-go" />
|
|
||||||
<working_directory value="$PROJECT_DIR$" />
|
|
||||||
<kind value="PACKAGE" />
|
|
||||||
<package value="legalgo-BE-go/cmd/legalgo" />
|
|
||||||
<directory value="$PROJECT_DIR$" />
|
|
||||||
<filePath value="$PROJECT_DIR$/cmd/legalgo/main.go" />
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
<recent_temporary>
|
|
||||||
<list>
|
|
||||||
<item itemvalue="Go Build.go build legalgo-BE-go/cmd/legalgo" />
|
|
||||||
</list>
|
|
||||||
</recent_temporary>
|
|
||||||
</component>
|
|
||||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
|
||||||
<option name="version" value="3" />
|
|
||||||
</component>
|
|
||||||
<component name="VgoProject">
|
|
||||||
<settings-migrated>true</settings-migrated>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@ -24,8 +24,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config.InitEnv()
|
config.InitEnv()
|
||||||
cfg := config.LoadConfig()
|
db, err := database.NewDB()
|
||||||
db, err := database.NewDB(cfg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to connect to database: %v", err)
|
log.Fatalf("failed to connect to database: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,11 +49,10 @@ func run(lc fx.Lifecycle, db *database.DB, apiRouter chi.Router) {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := fx.New(
|
app := fx.New(
|
||||||
config.Module,
|
|
||||||
database.Module,
|
database.Module,
|
||||||
repository.Module,
|
repository.Module,
|
||||||
services.Module,
|
|
||||||
internalhttp.Module,
|
internalhttp.Module,
|
||||||
|
services.Module,
|
||||||
fx.Invoke(run),
|
fx.Invoke(run),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type AuthConfig struct {
|
|
||||||
jwtTokenExpiresTTL int
|
|
||||||
jwtTokenSecret string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *AuthConfig) AccessTokenSecret() string {
|
|
||||||
return c.jwtTokenSecret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *AuthConfig) AccessTokenExpiresDate() time.Time {
|
|
||||||
duration := time.Duration(c.jwtTokenExpiresTTL)
|
|
||||||
return time.Now().UTC().Add(time.Minute * duration)
|
|
||||||
}
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
_ "gopkg.in/yaml.v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
YAML_PATH = "%s"
|
|
||||||
ENV_MODE = "ENV_MODE"
|
|
||||||
DEFAULT_ENV_MODE = "development"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
validEnvMode = map[string]struct{}{
|
|
||||||
"local": {},
|
|
||||||
"development": {},
|
|
||||||
"production": {},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
Server Server `mapstructure:"server"`
|
|
||||||
Database Database `mapstructure:"postgresql"`
|
|
||||||
Jwt Jwt `mapstructure:"jwt"`
|
|
||||||
OSSConfig OSSConfig `mapstructure:"oss"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
config *Config
|
|
||||||
configOnce sync.Once
|
|
||||||
)
|
|
||||||
|
|
||||||
func LoadConfig() *Config {
|
|
||||||
envMode := os.Getenv(ENV_MODE)
|
|
||||||
if _, ok := validEnvMode[envMode]; !ok {
|
|
||||||
envMode = DEFAULT_ENV_MODE // default env mode
|
|
||||||
}
|
|
||||||
cfgFilePath := fmt.Sprintf(YAML_PATH, envMode)
|
|
||||||
|
|
||||||
configOnce.Do(func() {
|
|
||||||
v := viper.New()
|
|
||||||
v.SetConfigType("yaml")
|
|
||||||
v.AddConfigPath(".")
|
|
||||||
v.SetConfigName(cfgFilePath)
|
|
||||||
if err := v.ReadInConfig(); err != nil {
|
|
||||||
panic(fmt.Errorf("failed to read config file: %s", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
config = &Config{}
|
|
||||||
if err := v.Unmarshal(config); err != nil {
|
|
||||||
panic(fmt.Errorf("failed to unmarshal config: %s", err))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Config) Auth() *AuthConfig {
|
|
||||||
return &AuthConfig{
|
|
||||||
jwtTokenSecret: c.Jwt.Token.Secret,
|
|
||||||
jwtTokenExpiresTTL: c.Jwt.Token.ExpiresTTL,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
28
config/db.go
28
config/db.go
@ -1,28 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Database struct {
|
|
||||||
Host string `mapstructure:"host"`
|
|
||||||
Port string `mapstructure:"port"`
|
|
||||||
DB string `mapstructure:"db"`
|
|
||||||
Driver string `mapstructure:"driver"`
|
|
||||||
Username string `mapstructure:"username"`
|
|
||||||
Password string `mapstructure:"password"`
|
|
||||||
SslMode string `mapstructure:"ssl-mode"`
|
|
||||||
Debug bool `mapstructure:"debug"`
|
|
||||||
MaxIdleConnectionsInSecond int `mapstructure:"max-idle-connections-in-second"`
|
|
||||||
MaxOpenConnectionsInSecond int `mapstructure:"max-open-connections-in-second"`
|
|
||||||
ConnectionMaxLifetimeInSecond int64 `mapstructure:"connection-max-life-time-in-second"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Database) DSN() string {
|
|
||||||
return fmt.Sprintf("host=%s port=%s dbname=%s user=%s password=%s sslmode=%s", c.Host, c.Port, c.DB, c.Username, c.Password, c.SslMode)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c Database) ConnectionMaxLifetime() time.Duration {
|
|
||||||
return time.Duration(c.ConnectionMaxLifetimeInSecond) * time.Second
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type httpConfig struct {
|
|
||||||
host string
|
|
||||||
port int
|
|
||||||
detailedError bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *httpConfig) Address() string {
|
|
||||||
return fmt.Sprintf("%s:%d", c.host, c.port)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *httpConfig) DetailedError() bool {
|
|
||||||
return c.detailedError
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
type Jwt struct {
|
|
||||||
Token Token `mapstructure:"token"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Token struct {
|
|
||||||
ExpiresTTL int `mapstructure:"expires-ttl"`
|
|
||||||
Secret string `mapstructure:"secret"`
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.uber.org/fx"
|
|
||||||
)
|
|
||||||
|
|
||||||
var Module = fx.Module("config",
|
|
||||||
fx.Provide(
|
|
||||||
LoadConfig,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
type OSSConfig struct {
|
|
||||||
AccessKeyID string `mapstructure:"access_key_id"`
|
|
||||||
AccessKeySecret string `mapstructure:"access_key_secret"`
|
|
||||||
Endpoint string `mapstructure:"endpoint"`
|
|
||||||
BucketName string `mapstructure:"bucket_name"`
|
|
||||||
PhotoFolder string `mapstructure:"photo_folder"`
|
|
||||||
LogLevel string `mapstructure:"log_level"`
|
|
||||||
HostURL string `mapstructure:"host_url"`
|
|
||||||
PublicURL string `mapstructure:"public_url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c OSSConfig) GetAccessKeyID() string {
|
|
||||||
return c.AccessKeyID
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c OSSConfig) GetAccessKeySecret() string {
|
|
||||||
return c.AccessKeySecret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c OSSConfig) GetEndpoint() string {
|
|
||||||
return c.Endpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c OSSConfig) GetBucketName() string {
|
|
||||||
return c.BucketName
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c OSSConfig) GetLogLevel() string {
|
|
||||||
return c.LogLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c OSSConfig) GetHostURL() string {
|
|
||||||
return c.HostURL
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c OSSConfig) GetPublicURL() string {
|
|
||||||
return c.PublicURL
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c OSSConfig) GetPhotoFolder() string {
|
|
||||||
return c.PhotoFolder
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
type Server struct {
|
|
||||||
Port string `mapstructure:"port"`
|
|
||||||
BaseUrl string `mapstructure:"common-url"`
|
|
||||||
LocalUrl string `mapstructure:"local-url"`
|
|
||||||
}
|
|
||||||
@ -13,14 +13,14 @@ type DB struct {
|
|||||||
*gorm.DB
|
*gorm.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDB(cfg *config.Config) (*DB, error) {
|
func NewDB() (*DB, error) {
|
||||||
dsn := fmt.Sprintf(
|
dsn := fmt.Sprintf(
|
||||||
"host=%s user=%s password=%s dbname=%s port=%v sslmode=disable",
|
"host=%s user=%s password=%s dbname=%s port=%v sslmode=disable",
|
||||||
cfg.Database.Host,
|
config.DB_HOST,
|
||||||
cfg.Database.Username,
|
config.DB_USER,
|
||||||
cfg.Database.Password,
|
config.DB_PASSWORD,
|
||||||
cfg.Database.DB,
|
config.DB_NAME,
|
||||||
cfg.Database.Port,
|
config.DB_PORT,
|
||||||
)
|
)
|
||||||
|
|
||||||
if dsn == "" {
|
if dsn == "" {
|
||||||
|
|||||||
@ -1,31 +0,0 @@
|
|||||||
server:
|
|
||||||
base-url: https://api.legalgo.id/core
|
|
||||||
local-url: http://localhost:3300
|
|
||||||
port: 3300
|
|
||||||
|
|
||||||
jwt:
|
|
||||||
token:
|
|
||||||
expires-ttl: 1440
|
|
||||||
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
|
|
||||||
|
|
||||||
postgresql:
|
|
||||||
host: 62.72.45.250
|
|
||||||
port: 20826
|
|
||||||
driver: postgres
|
|
||||||
db: legalgonews-dev
|
|
||||||
username: legalgo_admin
|
|
||||||
password: 'K4K!2Kg7c@KW6H&4A2aBy2dFCRY3Sh'
|
|
||||||
ssl-mode: disable
|
|
||||||
max-idle-connections-in-second: 600
|
|
||||||
max-open-connections-in-second: 600
|
|
||||||
connection-max-life-time-in-second: 600
|
|
||||||
debug: false
|
|
||||||
|
|
||||||
oss:
|
|
||||||
access_key_id: cf9a475e18bc7626cbdbf09709d82a64
|
|
||||||
access_key_secret: 91f3321294d3e23035427a0ecb893ada
|
|
||||||
endpoint: sin1.contabostorage.com
|
|
||||||
bucket_name: legalgonews-dev
|
|
||||||
log_level: Error
|
|
||||||
host_url: https://sin1.contabostorage.com
|
|
||||||
public_url: https://sin1.contabostorage.com/fda98c2228f246f29a7e466b86b3b9e7
|
|
||||||
25
go.mod
25
go.mod
@ -1,48 +1,31 @@
|
|||||||
module legalgo-BE-go
|
module legalgo-BE-go
|
||||||
|
|
||||||
go 1.24
|
go 1.24.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
github.com/spf13/viper v1.19.0
|
|
||||||
go.uber.org/fx v1.23.0
|
go.uber.org/fx v1.23.0
|
||||||
golang.org/x/crypto v0.34.0
|
golang.org/x/crypto v0.34.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gorm.io/driver/postgres v1.5.11
|
||||||
gorm.io/driver/postgres v1.4.7
|
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
|
||||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
|
||||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
github.com/jackc/pgx/v5 v5.2.0 // indirect
|
github.com/jackc/pgx/v5 v5.7.2 // indirect
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/magiconair/properties v1.8.7 // indirect
|
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
|
||||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
|
||||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
|
||||||
github.com/spf13/afero v1.11.0 // indirect
|
|
||||||
github.com/spf13/cast v1.6.0 // indirect
|
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
|
||||||
github.com/subosito/gotenv v1.6.0 // indirect
|
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
|
||||||
golang.org/x/net v0.34.0 // indirect
|
golang.org/x/net v0.34.0 // indirect
|
||||||
golang.org/x/text v0.22.0 // indirect
|
golang.org/x/text v0.22.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/aws/aws-sdk-go v1.50.0
|
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/go-chi/chi/v5 v5.2.1
|
github.com/go-chi/chi/v5 v5.2.1
|
||||||
|
|||||||
125
go.sum
125
go.sum
@ -1,22 +1,14 @@
|
|||||||
github.com/aws/aws-sdk-go v1.50.0 h1:HBtrLeO+QyDKnc3t1+5DR1RxodOHCGr8ZcrHudpv7jI=
|
|
||||||
github.com/aws/aws-sdk-go v1.50.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
|
|
||||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||||
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
|
||||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
|
||||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
|
||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
|
||||||
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||||
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
|
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
|
||||||
@ -33,89 +25,35 @@ github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0
|
|||||||
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
|
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
|
||||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
|
||||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
github.com/jackc/pgx/v5 v5.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8=
|
github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
|
||||||
github.com/jackc/pgx/v5 v5.2.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk=
|
github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
||||||
github.com/jackc/puddle/v2 v2.1.2/go.mod h1:2lpufsF5mRHO6SuZkm0fNYxM6SWHfvyFj62KwNzgels=
|
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
|
||||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
|
||||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
|
||||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
|
||||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
|
||||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
|
||||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/redis/go-redis/v9 v9.7.1 h1:4LhKRCIduqXqtvCUlaq9c8bdHOkICjDMrr1+Zb3osAc=
|
github.com/redis/go-redis/v9 v9.7.1 h1:4LhKRCIduqXqtvCUlaq9c8bdHOkICjDMrr1+Zb3osAc=
|
||||||
github.com/redis/go-redis/v9 v9.7.1/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
github.com/redis/go-redis/v9 v9.7.1/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
||||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
|
||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
|
||||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
|
||||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
|
||||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
|
||||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
|
||||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
|
||||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
|
||||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
|
||||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
|
||||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
|
||||||
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
|
|
||||||
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
|
||||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
|
||||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
|
||||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
|
||||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
|
||||||
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
|
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
|
||||||
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
|
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
|
||||||
go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
|
go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
|
||||||
@ -126,67 +64,22 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
|||||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
|
||||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
||||||
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
|
|
||||||
golang.org/x/crypto v0.34.0 h1:+/C6tk6rf/+t5DhUketUbD1aNGqiSX3j15Z6xuIDlBA=
|
golang.org/x/crypto v0.34.0 h1:+/C6tk6rf/+t5DhUketUbD1aNGqiSX3j15Z6xuIDlBA=
|
||||||
golang.org/x/crypto v0.34.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
golang.org/x/crypto v0.34.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
|
||||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
|
||||||
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
|
||||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
|
||||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|
||||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
|
||||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|
||||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
|
||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
|
||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gorm.io/driver/postgres v1.4.7 h1:J06jXZCNq7Pdf7LIPn8tZn9LsWjd81BRSKveKNr0ZfA=
|
gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314=
|
||||||
gorm.io/driver/postgres v1.4.7/go.mod h1:UJChCNLFKeBqQRE+HrkFUbKbq9idPXmTOk2u4Wok8S4=
|
gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
|
||||||
gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
|
||||||
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||||
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package repository
|
|||||||
import (
|
import (
|
||||||
categoryrepository "legalgo-BE-go/internal/accessor/category"
|
categoryrepository "legalgo-BE-go/internal/accessor/category"
|
||||||
newsrepository "legalgo-BE-go/internal/accessor/news"
|
newsrepository "legalgo-BE-go/internal/accessor/news"
|
||||||
"legalgo-BE-go/internal/accessor/oss"
|
|
||||||
redisaccessor "legalgo-BE-go/internal/accessor/redis"
|
redisaccessor "legalgo-BE-go/internal/accessor/redis"
|
||||||
staffrepository "legalgo-BE-go/internal/accessor/staff"
|
staffrepository "legalgo-BE-go/internal/accessor/staff"
|
||||||
subscriberepository "legalgo-BE-go/internal/accessor/subscribe"
|
subscriberepository "legalgo-BE-go/internal/accessor/subscribe"
|
||||||
@ -23,5 +22,4 @@ var Module = fx.Module("repository", fx.Provide(
|
|||||||
tagrepository.New,
|
tagrepository.New,
|
||||||
categoryrepository.New,
|
categoryrepository.New,
|
||||||
newsrepository.New,
|
newsrepository.New,
|
||||||
oss.New,
|
|
||||||
))
|
))
|
||||||
|
|||||||
@ -1,70 +0,0 @@
|
|||||||
package oss
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"legalgo-BE-go/config"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
|
||||||
"github.com/aws/aws-sdk-go/service/s3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type OSSConfig interface {
|
|
||||||
GetAccessKeyID() string
|
|
||||||
GetAccessKeySecret() string
|
|
||||||
GetEndpoint() string
|
|
||||||
GetBucketName() string
|
|
||||||
GetHostURL() string
|
|
||||||
GetPublicURL() string
|
|
||||||
}
|
|
||||||
|
|
||||||
const _awsRegion = "us-east-1"
|
|
||||||
const _s3ACL = "public-read"
|
|
||||||
|
|
||||||
type OssRepositoryImpl struct {
|
|
||||||
s3 *s3.S3
|
|
||||||
cfg OSSConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(cfg *config.Config) OSSRepository {
|
|
||||||
ossCfg := cfg.OSSConfig
|
|
||||||
sess, err := session.NewSession(&aws.Config{
|
|
||||||
S3ForcePathStyle: aws.Bool(true),
|
|
||||||
Endpoint: aws.String(ossCfg.GetEndpoint()),
|
|
||||||
Region: aws.String(_awsRegion),
|
|
||||||
Credentials: credentials.NewStaticCredentials(ossCfg.GetAccessKeyID(), ossCfg.GetAccessKeySecret(), ""),
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to create AWS session:", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &OssRepositoryImpl{
|
|
||||||
s3: s3.New(sess),
|
|
||||||
cfg: ossCfg,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *OssRepositoryImpl) UploadFile(ctx context.Context, fileName string, fileContent []byte) (fileUrl string, err error) {
|
|
||||||
reader := bytes.NewReader(fileContent)
|
|
||||||
|
|
||||||
_, err = r.s3.PutObject(&s3.PutObjectInput{
|
|
||||||
Bucket: aws.String(r.cfg.GetBucketName()),
|
|
||||||
Key: aws.String(fileName),
|
|
||||||
Body: reader,
|
|
||||||
ACL: aws.String(_s3ACL),
|
|
||||||
})
|
|
||||||
|
|
||||||
return r.GetPublicURL(fileName), err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *OssRepositoryImpl) GetPublicURL(fileName string) string {
|
|
||||||
if fileName == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s:%s%s", r.cfg.GetPublicURL(), r.cfg.GetBucketName(), fileName)
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
package oss
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
)
|
|
||||||
|
|
||||||
type OSSRepository interface {
|
|
||||||
UploadFile(ctx context.Context, fileName string, fileContent []byte) (fileUrl string, err error)
|
|
||||||
GetPublicURL(fileName string) string
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
package osshttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.uber.org/fx"
|
|
||||||
)
|
|
||||||
|
|
||||||
var Module = fx.Module("upload",
|
|
||||||
fx.Invoke(
|
|
||||||
RegisterUploadFile,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
@ -1,92 +0,0 @@
|
|||||||
package osshttp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
oss2 "legalgo-BE-go/internal/domain/oss"
|
|
||||||
"legalgo-BE-go/internal/services/oss"
|
|
||||||
"legalgo-BE-go/internal/utilities/response"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
|
||||||
)
|
|
||||||
|
|
||||||
const _oneMB = 1 << 20
|
|
||||||
const _maxUploadSize = 2 * _oneMB
|
|
||||||
const _folderName = "/file"
|
|
||||||
|
|
||||||
func RegisterUploadFile(ossService oss.OSSService, router chi.Router) {
|
|
||||||
router.Post("/file", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
ctx := r.Context()
|
|
||||||
|
|
||||||
// Limit the size of the request body to prevent very large uploads.
|
|
||||||
r.Body = http.MaxBytesReader(w, r.Body, int64(_maxUploadSize))
|
|
||||||
if err := r.ParseMultipartForm(int64(_maxUploadSize)); err != nil {
|
|
||||||
response.ResponseWithErrorCode(
|
|
||||||
ctx,
|
|
||||||
w,
|
|
||||||
err,
|
|
||||||
response.ErrBadRequest.Code,
|
|
||||||
response.ErrBadRequest.HttpCode,
|
|
||||||
"Failed to parse multipart form",
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the file from the form.
|
|
||||||
file, header, err := r.FormFile("file")
|
|
||||||
if err != nil {
|
|
||||||
response.ResponseWithErrorCode(
|
|
||||||
ctx,
|
|
||||||
w,
|
|
||||||
err,
|
|
||||||
response.ErrBadRequest.Code,
|
|
||||||
response.ErrBadRequest.HttpCode,
|
|
||||||
"Failed to retrieve file",
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
// Check if file size exceeds the maximum limit.
|
|
||||||
if header.Size > int64(_maxUploadSize) {
|
|
||||||
response.ResponseWithErrorCode(
|
|
||||||
ctx,
|
|
||||||
w,
|
|
||||||
fmt.Errorf("file too big"),
|
|
||||||
response.ErrBadRequest.Code,
|
|
||||||
response.ErrBadRequest.HttpCode,
|
|
||||||
fmt.Sprintf("The file is too big. The maximum size is %d MB", _maxUploadSize/_oneMB),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare the request for the OSS service.
|
|
||||||
uploadReq := &oss2.UploadFileRequest{
|
|
||||||
FileHeader: header,
|
|
||||||
FolderName: _folderName,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the OSS service to handle the file upload.
|
|
||||||
result, err := ossService.UploadFile(ctx, uploadReq)
|
|
||||||
if err != nil {
|
|
||||||
response.ResponseWithErrorCode(
|
|
||||||
ctx,
|
|
||||||
w,
|
|
||||||
err,
|
|
||||||
response.ErrBadRequest.Code,
|
|
||||||
response.ErrBadRequest.HttpCode,
|
|
||||||
err.Error(),
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a successful JSON response.
|
|
||||||
response.RespondJsonSuccess(ctx, w, struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
Data interface{} `json:"data"`
|
|
||||||
}{
|
|
||||||
Message: "File uploaded successfully.",
|
|
||||||
Data: result,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -4,7 +4,6 @@ import (
|
|||||||
authhttp "legalgo-BE-go/internal/api/http/auth"
|
authhttp "legalgo-BE-go/internal/api/http/auth"
|
||||||
categoryhttp "legalgo-BE-go/internal/api/http/category"
|
categoryhttp "legalgo-BE-go/internal/api/http/category"
|
||||||
newshttp "legalgo-BE-go/internal/api/http/news"
|
newshttp "legalgo-BE-go/internal/api/http/news"
|
||||||
osshttp "legalgo-BE-go/internal/api/http/oss"
|
|
||||||
subscribeplanhttp "legalgo-BE-go/internal/api/http/subscribe_plan"
|
subscribeplanhttp "legalgo-BE-go/internal/api/http/subscribe_plan"
|
||||||
taghttp "legalgo-BE-go/internal/api/http/tag"
|
taghttp "legalgo-BE-go/internal/api/http/tag"
|
||||||
|
|
||||||
@ -26,7 +25,6 @@ var Module = fx.Module("router",
|
|||||||
taghttp.Module,
|
taghttp.Module,
|
||||||
categoryhttp.Module,
|
categoryhttp.Module,
|
||||||
newshttp.Module,
|
newshttp.Module,
|
||||||
osshttp.Module,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func initRouter() chi.Router {
|
func initRouter() chi.Router {
|
||||||
|
|||||||
@ -1,24 +0,0 @@
|
|||||||
package oss
|
|
||||||
|
|
||||||
import "mime/multipart"
|
|
||||||
|
|
||||||
type UploadFileRequest struct {
|
|
||||||
FileHeader *multipart.FileHeader
|
|
||||||
FolderName string
|
|
||||||
FileSize int64 `validate:"max=10000000"` // 10Mb = 10000000 byte
|
|
||||||
Ext string `validate:"oneof=.png .jpeg .jpg .pdf .xlsx .csv"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DownloadFileRequest struct {
|
|
||||||
FileName string `query:"file_name" validate:"required"`
|
|
||||||
FolderName string `query:"folder_name" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type UploadFileResponse struct {
|
|
||||||
FilePath string `json:"file_path"`
|
|
||||||
FileUrl string `json:"file_url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DownloadFileResponse struct {
|
|
||||||
FileUrl string `json:"file_url"`
|
|
||||||
}
|
|
||||||
@ -4,7 +4,6 @@ import (
|
|||||||
serviceauth "legalgo-BE-go/internal/services/auth"
|
serviceauth "legalgo-BE-go/internal/services/auth"
|
||||||
categorysvc "legalgo-BE-go/internal/services/category"
|
categorysvc "legalgo-BE-go/internal/services/category"
|
||||||
newssvc "legalgo-BE-go/internal/services/news"
|
newssvc "legalgo-BE-go/internal/services/news"
|
||||||
"legalgo-BE-go/internal/services/oss"
|
|
||||||
subscribesvc "legalgo-BE-go/internal/services/subscribe"
|
subscribesvc "legalgo-BE-go/internal/services/subscribe"
|
||||||
subscribeplansvc "legalgo-BE-go/internal/services/subscribe_plan"
|
subscribeplansvc "legalgo-BE-go/internal/services/subscribe_plan"
|
||||||
tagsvc "legalgo-BE-go/internal/services/tag"
|
tagsvc "legalgo-BE-go/internal/services/tag"
|
||||||
@ -20,6 +19,5 @@ var Module = fx.Module("services",
|
|||||||
tagsvc.New,
|
tagsvc.New,
|
||||||
categorysvc.New,
|
categorysvc.New,
|
||||||
newssvc.New,
|
newssvc.New,
|
||||||
oss.NewOSSService,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,62 +0,0 @@
|
|||||||
package oss
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
oss2 "legalgo-BE-go/internal/accessor/oss"
|
|
||||||
"legalgo-BE-go/internal/domain/oss"
|
|
||||||
"path"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-playground/validator/v10"
|
|
||||||
)
|
|
||||||
|
|
||||||
type OssService struct {
|
|
||||||
ossRepo oss2.OSSRepository
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewOSSService(ossRepo oss2.OSSRepository) OSSService {
|
|
||||||
return &OssService{
|
|
||||||
ossRepo: ossRepo,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *OssService) UploadFile(ctx context.Context, req *oss.UploadFileRequest) (*oss.UploadFileResponse, error) {
|
|
||||||
file := req.FileHeader
|
|
||||||
req.FileSize = file.Size
|
|
||||||
req.Ext = path.Ext(file.Filename)
|
|
||||||
validate := validator.New()
|
|
||||||
if err := validate.Struct(req); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open the file and read its content
|
|
||||||
srcFile, err := file.Open()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer srcFile.Close()
|
|
||||||
|
|
||||||
fileContent := make([]byte, file.Size)
|
|
||||||
_, err = srcFile.Read(fileContent)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
filePath := fmt.Sprintf("%v/%v%v", req.FolderName, s.GenerateFileName(), req.Ext)
|
|
||||||
fileUrl, err := s.ossRepo.UploadFile(ctx, filePath, fileContent)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &oss.UploadFileResponse{
|
|
||||||
FilePath: filePath,
|
|
||||||
FileUrl: fileUrl,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *OssService) GenerateFileName() string {
|
|
||||||
return fmt.Sprintf("%v-%v", uuid.New(), strconv.Itoa(int(time.Now().Unix())))
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
package oss
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"legalgo-BE-go/internal/domain/oss"
|
|
||||||
)
|
|
||||||
|
|
||||||
type OSSService interface {
|
|
||||||
UploadFile(ctx context.Context, req *oss.UploadFileRequest) (*oss.UploadFileResponse, error)
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: legalgonews-backend
|
|
||||||
namespace: altru-staging
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: legalgonews-backend
|
|
||||||
replicas: 1
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: legalgonews-backend
|
|
||||||
spec:
|
|
||||||
serviceAccountName: custom-serviceaccount
|
|
||||||
containers:
|
|
||||||
- name: legalgonews-backend
|
|
||||||
image: registry.gitlab.com/altru.id/legalgo/legalgonews-backend:<VERSION>
|
|
||||||
ports:
|
|
||||||
- containerPort: 3000
|
|
||||||
volumeMounts:
|
|
||||||
- mountPath: "/"
|
|
||||||
name: legalgonews-backend-secret
|
|
||||||
readOnly: true
|
|
||||||
volumes:
|
|
||||||
- name: legalgonews-backend-secret
|
|
||||||
secret:
|
|
||||||
secretName: legalgonews-backend-secret
|
|
||||||
imagePullSecrets:
|
|
||||||
- name: regcred
|
|
||||||
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: legalgonews-backend
|
|
||||||
namespace: altru-staging
|
|
||||||
annotations:
|
|
||||||
kubernetes.io/ingress.class: "nginx" # Add this line
|
|
||||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
|
||||||
nginx.ingress.kubernetes.io/ingress-class: "nginx" # Add this line
|
|
||||||
spec:
|
|
||||||
rules:
|
|
||||||
- host: "legalgonews-be.app-dev.altru.id"
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- pathType: Prefix
|
|
||||||
path: /
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: legalgonews-backend
|
|
||||||
port:
|
|
||||||
number: 3300
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- "legalgonews-be.app-dev.altru.id"
|
|
||||||
secretName: legalgonews-be-app-dev-biz-id-tls
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: altru-staging
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: legalgonews-backend
|
|
||||||
namespace: altru-staging
|
|
||||||
labels:
|
|
||||||
run: legalgonews-backend
|
|
||||||
spec:
|
|
||||||
ports:
|
|
||||||
- port: 3300
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: 3300
|
|
||||||
selector:
|
|
||||||
app: legalgonews-backend
|
|
||||||
type: ClusterIP
|
|
||||||
202
vendor/github.com/aws/aws-sdk-go/LICENSE.txt
generated
vendored
202
vendor/github.com/aws/aws-sdk-go/LICENSE.txt
generated
vendored
@ -1,202 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
3
vendor/github.com/aws/aws-sdk-go/NOTICE.txt
generated
vendored
3
vendor/github.com/aws/aws-sdk-go/NOTICE.txt
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
AWS SDK for Go
|
|
||||||
Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
||||||
Copyright 2014-2015 Stripe, Inc.
|
|
||||||
93
vendor/github.com/aws/aws-sdk-go/aws/arn/arn.go
generated
vendored
93
vendor/github.com/aws/aws-sdk-go/aws/arn/arn.go
generated
vendored
@ -1,93 +0,0 @@
|
|||||||
// Package arn provides a parser for interacting with Amazon Resource Names.
|
|
||||||
package arn
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
arnDelimiter = ":"
|
|
||||||
arnSections = 6
|
|
||||||
arnPrefix = "arn:"
|
|
||||||
|
|
||||||
// zero-indexed
|
|
||||||
sectionPartition = 1
|
|
||||||
sectionService = 2
|
|
||||||
sectionRegion = 3
|
|
||||||
sectionAccountID = 4
|
|
||||||
sectionResource = 5
|
|
||||||
|
|
||||||
// errors
|
|
||||||
invalidPrefix = "arn: invalid prefix"
|
|
||||||
invalidSections = "arn: not enough sections"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ARN captures the individual fields of an Amazon Resource Name.
|
|
||||||
// See http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html for more information.
|
|
||||||
type ARN struct {
|
|
||||||
// The partition that the resource is in. For standard AWS regions, the partition is "aws". If you have resources in
|
|
||||||
// other partitions, the partition is "aws-partitionname". For example, the partition for resources in the China
|
|
||||||
// (Beijing) region is "aws-cn".
|
|
||||||
Partition string
|
|
||||||
|
|
||||||
// The service namespace that identifies the AWS product (for example, Amazon S3, IAM, or Amazon RDS). For a list of
|
|
||||||
// namespaces, see
|
|
||||||
// http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-aws-service-namespaces.
|
|
||||||
Service string
|
|
||||||
|
|
||||||
// The region the resource resides in. Note that the ARNs for some resources do not require a region, so this
|
|
||||||
// component might be omitted.
|
|
||||||
Region string
|
|
||||||
|
|
||||||
// The ID of the AWS account that owns the resource, without the hyphens. For example, 123456789012. Note that the
|
|
||||||
// ARNs for some resources don't require an account number, so this component might be omitted.
|
|
||||||
AccountID string
|
|
||||||
|
|
||||||
// The content of this part of the ARN varies by service. It often includes an indicator of the type of resource —
|
|
||||||
// for example, an IAM user or Amazon RDS database - followed by a slash (/) or a colon (:), followed by the
|
|
||||||
// resource name itself. Some services allows paths for resource names, as described in
|
|
||||||
// http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arns-paths.
|
|
||||||
Resource string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse parses an ARN into its constituent parts.
|
|
||||||
//
|
|
||||||
// Some example ARNs:
|
|
||||||
// arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment
|
|
||||||
// arn:aws:iam::123456789012:user/David
|
|
||||||
// arn:aws:rds:eu-west-1:123456789012:db:mysql-db
|
|
||||||
// arn:aws:s3:::my_corporate_bucket/exampleobject.png
|
|
||||||
func Parse(arn string) (ARN, error) {
|
|
||||||
if !strings.HasPrefix(arn, arnPrefix) {
|
|
||||||
return ARN{}, errors.New(invalidPrefix)
|
|
||||||
}
|
|
||||||
sections := strings.SplitN(arn, arnDelimiter, arnSections)
|
|
||||||
if len(sections) != arnSections {
|
|
||||||
return ARN{}, errors.New(invalidSections)
|
|
||||||
}
|
|
||||||
return ARN{
|
|
||||||
Partition: sections[sectionPartition],
|
|
||||||
Service: sections[sectionService],
|
|
||||||
Region: sections[sectionRegion],
|
|
||||||
AccountID: sections[sectionAccountID],
|
|
||||||
Resource: sections[sectionResource],
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsARN returns whether the given string is an ARN by looking for
|
|
||||||
// whether the string starts with "arn:" and contains the correct number
|
|
||||||
// of sections delimited by colons(:).
|
|
||||||
func IsARN(arn string) bool {
|
|
||||||
return strings.HasPrefix(arn, arnPrefix) && strings.Count(arn, ":") >= arnSections-1
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the canonical representation of the ARN
|
|
||||||
func (arn ARN) String() string {
|
|
||||||
return arnPrefix +
|
|
||||||
arn.Partition + arnDelimiter +
|
|
||||||
arn.Service + arnDelimiter +
|
|
||||||
arn.Region + arnDelimiter +
|
|
||||||
arn.AccountID + arnDelimiter +
|
|
||||||
arn.Resource
|
|
||||||
}
|
|
||||||
50
vendor/github.com/aws/aws-sdk-go/aws/auth/bearer/token.go
generated
vendored
50
vendor/github.com/aws/aws-sdk-go/aws/auth/bearer/token.go
generated
vendored
@ -1,50 +0,0 @@
|
|||||||
package bearer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Token provides a type wrapping a bearer token and expiration metadata.
|
|
||||||
type Token struct {
|
|
||||||
Value string
|
|
||||||
|
|
||||||
CanExpire bool
|
|
||||||
Expires time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expired returns if the token's Expires time is before or equal to the time
|
|
||||||
// provided. If CanExpire is false, Expired will always return false.
|
|
||||||
func (t Token) Expired(now time.Time) bool {
|
|
||||||
if !t.CanExpire {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
now = now.Round(0)
|
|
||||||
return now.Equal(t.Expires) || now.After(t.Expires)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenProvider provides interface for retrieving bearer tokens.
|
|
||||||
type TokenProvider interface {
|
|
||||||
RetrieveBearerToken(aws.Context) (Token, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenProviderFunc provides a helper utility to wrap a function as a type
|
|
||||||
// that implements the TokenProvider interface.
|
|
||||||
type TokenProviderFunc func(aws.Context) (Token, error)
|
|
||||||
|
|
||||||
// RetrieveBearerToken calls the wrapped function, returning the Token or
|
|
||||||
// error.
|
|
||||||
func (fn TokenProviderFunc) RetrieveBearerToken(ctx aws.Context) (Token, error) {
|
|
||||||
return fn(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StaticTokenProvider provides a utility for wrapping a static bearer token
|
|
||||||
// value within an implementation of a token provider.
|
|
||||||
type StaticTokenProvider struct {
|
|
||||||
Token Token
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetrieveBearerToken returns the static token specified.
|
|
||||||
func (s StaticTokenProvider) RetrieveBearerToken(aws.Context) (Token, error) {
|
|
||||||
return s.Token, nil
|
|
||||||
}
|
|
||||||
164
vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go
generated
vendored
164
vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go
generated
vendored
@ -1,164 +0,0 @@
|
|||||||
// Package awserr represents API error interface accessors for the SDK.
|
|
||||||
package awserr
|
|
||||||
|
|
||||||
// An Error wraps lower level errors with code, message and an original error.
|
|
||||||
// The underlying concrete error type may also satisfy other interfaces which
|
|
||||||
// can be to used to obtain more specific information about the error.
|
|
||||||
//
|
|
||||||
// Calling Error() or String() will always include the full information about
|
|
||||||
// an error based on its underlying type.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// output, err := s3manage.Upload(svc, input, opts)
|
|
||||||
// if err != nil {
|
|
||||||
// if awsErr, ok := err.(awserr.Error); ok {
|
|
||||||
// // Get error details
|
|
||||||
// log.Println("Error:", awsErr.Code(), awsErr.Message())
|
|
||||||
//
|
|
||||||
// // Prints out full error message, including original error if there was one.
|
|
||||||
// log.Println("Error:", awsErr.Error())
|
|
||||||
//
|
|
||||||
// // Get original error
|
|
||||||
// if origErr := awsErr.OrigErr(); origErr != nil {
|
|
||||||
// // operate on original error.
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// fmt.Println(err.Error())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
type Error interface {
|
|
||||||
// Satisfy the generic error interface.
|
|
||||||
error
|
|
||||||
|
|
||||||
// Returns the short phrase depicting the classification of the error.
|
|
||||||
Code() string
|
|
||||||
|
|
||||||
// Returns the error details message.
|
|
||||||
Message() string
|
|
||||||
|
|
||||||
// Returns the original error if one was set. Nil is returned if not set.
|
|
||||||
OrigErr() error
|
|
||||||
}
|
|
||||||
|
|
||||||
// BatchError is a batch of errors which also wraps lower level errors with
|
|
||||||
// code, message, and original errors. Calling Error() will include all errors
|
|
||||||
// that occurred in the batch.
|
|
||||||
//
|
|
||||||
// Deprecated: Replaced with BatchedErrors. Only defined for backwards
|
|
||||||
// compatibility.
|
|
||||||
type BatchError interface {
|
|
||||||
// Satisfy the generic error interface.
|
|
||||||
error
|
|
||||||
|
|
||||||
// Returns the short phrase depicting the classification of the error.
|
|
||||||
Code() string
|
|
||||||
|
|
||||||
// Returns the error details message.
|
|
||||||
Message() string
|
|
||||||
|
|
||||||
// Returns the original error if one was set. Nil is returned if not set.
|
|
||||||
OrigErrs() []error
|
|
||||||
}
|
|
||||||
|
|
||||||
// BatchedErrors is a batch of errors which also wraps lower level errors with
|
|
||||||
// code, message, and original errors. Calling Error() will include all errors
|
|
||||||
// that occurred in the batch.
|
|
||||||
//
|
|
||||||
// Replaces BatchError
|
|
||||||
type BatchedErrors interface {
|
|
||||||
// Satisfy the base Error interface.
|
|
||||||
Error
|
|
||||||
|
|
||||||
// Returns the original error if one was set. Nil is returned if not set.
|
|
||||||
OrigErrs() []error
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns an Error object described by the code, message, and origErr.
|
|
||||||
//
|
|
||||||
// If origErr satisfies the Error interface it will not be wrapped within a new
|
|
||||||
// Error object and will instead be returned.
|
|
||||||
func New(code, message string, origErr error) Error {
|
|
||||||
var errs []error
|
|
||||||
if origErr != nil {
|
|
||||||
errs = append(errs, origErr)
|
|
||||||
}
|
|
||||||
return newBaseError(code, message, errs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBatchError returns an BatchedErrors with a collection of errors as an
|
|
||||||
// array of errors.
|
|
||||||
func NewBatchError(code, message string, errs []error) BatchedErrors {
|
|
||||||
return newBaseError(code, message, errs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A RequestFailure is an interface to extract request failure information from
|
|
||||||
// an Error such as the request ID of the failed request returned by a service.
|
|
||||||
// RequestFailures may not always have a requestID value if the request failed
|
|
||||||
// prior to reaching the service such as a connection error.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// output, err := s3manage.Upload(svc, input, opts)
|
|
||||||
// if err != nil {
|
|
||||||
// if reqerr, ok := err.(RequestFailure); ok {
|
|
||||||
// log.Println("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID())
|
|
||||||
// } else {
|
|
||||||
// log.Println("Error:", err.Error())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Combined with awserr.Error:
|
|
||||||
//
|
|
||||||
// output, err := s3manage.Upload(svc, input, opts)
|
|
||||||
// if err != nil {
|
|
||||||
// if awsErr, ok := err.(awserr.Error); ok {
|
|
||||||
// // Generic AWS Error with Code, Message, and original error (if any)
|
|
||||||
// fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr())
|
|
||||||
//
|
|
||||||
// if reqErr, ok := err.(awserr.RequestFailure); ok {
|
|
||||||
// // A service error occurred
|
|
||||||
// fmt.Println(reqErr.StatusCode(), reqErr.RequestID())
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// fmt.Println(err.Error())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
type RequestFailure interface {
|
|
||||||
Error
|
|
||||||
|
|
||||||
// The status code of the HTTP response.
|
|
||||||
StatusCode() int
|
|
||||||
|
|
||||||
// The request ID returned by the service for a request failure. This will
|
|
||||||
// be empty if no request ID is available such as the request failed due
|
|
||||||
// to a connection error.
|
|
||||||
RequestID() string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRequestFailure returns a wrapped error with additional information for
|
|
||||||
// request status code, and service requestID.
|
|
||||||
//
|
|
||||||
// Should be used to wrap all request which involve service requests. Even if
|
|
||||||
// the request failed without a service response, but had an HTTP status code
|
|
||||||
// that may be meaningful.
|
|
||||||
func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure {
|
|
||||||
return newRequestError(err, statusCode, reqID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalError provides the interface for the SDK failing to unmarshal data.
|
|
||||||
type UnmarshalError interface {
|
|
||||||
awsError
|
|
||||||
Bytes() []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUnmarshalError returns an initialized UnmarshalError error wrapper adding
|
|
||||||
// the bytes that fail to unmarshal to the error.
|
|
||||||
func NewUnmarshalError(err error, msg string, bytes []byte) UnmarshalError {
|
|
||||||
return &unmarshalError{
|
|
||||||
awsError: New("UnmarshalError", msg, err),
|
|
||||||
bytes: bytes,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
221
vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go
generated
vendored
221
vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go
generated
vendored
@ -1,221 +0,0 @@
|
|||||||
package awserr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SprintError returns a string of the formatted error code.
|
|
||||||
//
|
|
||||||
// Both extra and origErr are optional. If they are included their lines
|
|
||||||
// will be added, but if they are not included their lines will be ignored.
|
|
||||||
func SprintError(code, message, extra string, origErr error) string {
|
|
||||||
msg := fmt.Sprintf("%s: %s", code, message)
|
|
||||||
if extra != "" {
|
|
||||||
msg = fmt.Sprintf("%s\n\t%s", msg, extra)
|
|
||||||
}
|
|
||||||
if origErr != nil {
|
|
||||||
msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error())
|
|
||||||
}
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
|
|
||||||
// A baseError wraps the code and message which defines an error. It also
|
|
||||||
// can be used to wrap an original error object.
|
|
||||||
//
|
|
||||||
// Should be used as the root for errors satisfying the awserr.Error. Also
|
|
||||||
// for any error which does not fit into a specific error wrapper type.
|
|
||||||
type baseError struct {
|
|
||||||
// Classification of error
|
|
||||||
code string
|
|
||||||
|
|
||||||
// Detailed information about error
|
|
||||||
message string
|
|
||||||
|
|
||||||
// Optional original error this error is based off of. Allows building
|
|
||||||
// chained errors.
|
|
||||||
errs []error
|
|
||||||
}
|
|
||||||
|
|
||||||
// newBaseError returns an error object for the code, message, and errors.
|
|
||||||
//
|
|
||||||
// code is a short no whitespace phrase depicting the classification of
|
|
||||||
// the error that is being created.
|
|
||||||
//
|
|
||||||
// message is the free flow string containing detailed information about the
|
|
||||||
// error.
|
|
||||||
//
|
|
||||||
// origErrs is the error objects which will be nested under the new errors to
|
|
||||||
// be returned.
|
|
||||||
func newBaseError(code, message string, origErrs []error) *baseError {
|
|
||||||
b := &baseError{
|
|
||||||
code: code,
|
|
||||||
message: message,
|
|
||||||
errs: origErrs,
|
|
||||||
}
|
|
||||||
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns the string representation of the error.
|
|
||||||
//
|
|
||||||
// See ErrorWithExtra for formatting.
|
|
||||||
//
|
|
||||||
// Satisfies the error interface.
|
|
||||||
func (b baseError) Error() string {
|
|
||||||
size := len(b.errs)
|
|
||||||
if size > 0 {
|
|
||||||
return SprintError(b.code, b.message, "", errorList(b.errs))
|
|
||||||
}
|
|
||||||
|
|
||||||
return SprintError(b.code, b.message, "", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
// Alias for Error to satisfy the stringer interface.
|
|
||||||
func (b baseError) String() string {
|
|
||||||
return b.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Code returns the short phrase depicting the classification of the error.
|
|
||||||
func (b baseError) Code() string {
|
|
||||||
return b.code
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message returns the error details message.
|
|
||||||
func (b baseError) Message() string {
|
|
||||||
return b.message
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErr returns the original error if one was set. Nil is returned if no
|
|
||||||
// error was set. This only returns the first element in the list. If the full
|
|
||||||
// list is needed, use BatchedErrors.
|
|
||||||
func (b baseError) OrigErr() error {
|
|
||||||
switch len(b.errs) {
|
|
||||||
case 0:
|
|
||||||
return nil
|
|
||||||
case 1:
|
|
||||||
return b.errs[0]
|
|
||||||
default:
|
|
||||||
if err, ok := b.errs[0].(Error); ok {
|
|
||||||
return NewBatchError(err.Code(), err.Message(), b.errs[1:])
|
|
||||||
}
|
|
||||||
return NewBatchError("BatchedErrors",
|
|
||||||
"multiple errors occurred", b.errs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErrs returns the original errors if one was set. An empty slice is
|
|
||||||
// returned if no error was set.
|
|
||||||
func (b baseError) OrigErrs() []error {
|
|
||||||
return b.errs
|
|
||||||
}
|
|
||||||
|
|
||||||
// So that the Error interface type can be included as an anonymous field
|
|
||||||
// in the requestError struct and not conflict with the error.Error() method.
|
|
||||||
type awsError Error
|
|
||||||
|
|
||||||
// A requestError wraps a request or service error.
|
|
||||||
//
|
|
||||||
// Composed of baseError for code, message, and original error.
|
|
||||||
type requestError struct {
|
|
||||||
awsError
|
|
||||||
statusCode int
|
|
||||||
requestID string
|
|
||||||
bytes []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// newRequestError returns a wrapped error with additional information for
|
|
||||||
// request status code, and service requestID.
|
|
||||||
//
|
|
||||||
// Should be used to wrap all request which involve service requests. Even if
|
|
||||||
// the request failed without a service response, but had an HTTP status code
|
|
||||||
// that may be meaningful.
|
|
||||||
//
|
|
||||||
// Also wraps original errors via the baseError.
|
|
||||||
func newRequestError(err Error, statusCode int, requestID string) *requestError {
|
|
||||||
return &requestError{
|
|
||||||
awsError: err,
|
|
||||||
statusCode: statusCode,
|
|
||||||
requestID: requestID,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns the string representation of the error.
|
|
||||||
// Satisfies the error interface.
|
|
||||||
func (r requestError) Error() string {
|
|
||||||
extra := fmt.Sprintf("status code: %d, request id: %s",
|
|
||||||
r.statusCode, r.requestID)
|
|
||||||
return SprintError(r.Code(), r.Message(), extra, r.OrigErr())
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
// Alias for Error to satisfy the stringer interface.
|
|
||||||
func (r requestError) String() string {
|
|
||||||
return r.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// StatusCode returns the wrapped status code for the error
|
|
||||||
func (r requestError) StatusCode() int {
|
|
||||||
return r.statusCode
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestID returns the wrapped requestID
|
|
||||||
func (r requestError) RequestID() string {
|
|
||||||
return r.requestID
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErrs returns the original errors if one was set. An empty slice is
|
|
||||||
// returned if no error was set.
|
|
||||||
func (r requestError) OrigErrs() []error {
|
|
||||||
if b, ok := r.awsError.(BatchedErrors); ok {
|
|
||||||
return b.OrigErrs()
|
|
||||||
}
|
|
||||||
return []error{r.OrigErr()}
|
|
||||||
}
|
|
||||||
|
|
||||||
type unmarshalError struct {
|
|
||||||
awsError
|
|
||||||
bytes []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns the string representation of the error.
|
|
||||||
// Satisfies the error interface.
|
|
||||||
func (e unmarshalError) Error() string {
|
|
||||||
extra := hex.Dump(e.bytes)
|
|
||||||
return SprintError(e.Code(), e.Message(), extra, e.OrigErr())
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
// Alias for Error to satisfy the stringer interface.
|
|
||||||
func (e unmarshalError) String() string {
|
|
||||||
return e.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bytes returns the bytes that failed to unmarshal.
|
|
||||||
func (e unmarshalError) Bytes() []byte {
|
|
||||||
return e.bytes
|
|
||||||
}
|
|
||||||
|
|
||||||
// An error list that satisfies the golang interface
|
|
||||||
type errorList []error
|
|
||||||
|
|
||||||
// Error returns the string representation of the error.
|
|
||||||
//
|
|
||||||
// Satisfies the error interface.
|
|
||||||
func (e errorList) Error() string {
|
|
||||||
msg := ""
|
|
||||||
// How do we want to handle the array size being zero
|
|
||||||
if size := len(e); size > 0 {
|
|
||||||
for i := 0; i < size; i++ {
|
|
||||||
msg += e[i].Error()
|
|
||||||
// We check the next index to see if it is within the slice.
|
|
||||||
// If it is, then we append a newline. We do this, because unit tests
|
|
||||||
// could be broken with the additional '\n'
|
|
||||||
if i+1 < size {
|
|
||||||
msg += "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
108
vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go
generated
vendored
108
vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go
generated
vendored
@ -1,108 +0,0 @@
|
|||||||
package awsutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"reflect"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Copy deeply copies a src structure to dst. Useful for copying request and
|
|
||||||
// response structures.
|
|
||||||
//
|
|
||||||
// Can copy between structs of different type, but will only copy fields which
|
|
||||||
// are assignable, and exist in both structs. Fields which are not assignable,
|
|
||||||
// or do not exist in both structs are ignored.
|
|
||||||
func Copy(dst, src interface{}) {
|
|
||||||
dstval := reflect.ValueOf(dst)
|
|
||||||
if !dstval.IsValid() {
|
|
||||||
panic("Copy dst cannot be nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
rcopy(dstval, reflect.ValueOf(src), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyOf returns a copy of src while also allocating the memory for dst.
|
|
||||||
// src must be a pointer type or this operation will fail.
|
|
||||||
func CopyOf(src interface{}) (dst interface{}) {
|
|
||||||
dsti := reflect.New(reflect.TypeOf(src).Elem())
|
|
||||||
dst = dsti.Interface()
|
|
||||||
rcopy(dsti, reflect.ValueOf(src), true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// rcopy performs a recursive copy of values from the source to destination.
|
|
||||||
//
|
|
||||||
// root is used to skip certain aspects of the copy which are not valid
|
|
||||||
// for the root node of a object.
|
|
||||||
func rcopy(dst, src reflect.Value, root bool) {
|
|
||||||
if !src.IsValid() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch src.Kind() {
|
|
||||||
case reflect.Ptr:
|
|
||||||
if _, ok := src.Interface().(io.Reader); ok {
|
|
||||||
if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() {
|
|
||||||
dst.Elem().Set(src)
|
|
||||||
} else if dst.CanSet() {
|
|
||||||
dst.Set(src)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
e := src.Type().Elem()
|
|
||||||
if dst.CanSet() && !src.IsNil() {
|
|
||||||
if _, ok := src.Interface().(*time.Time); !ok {
|
|
||||||
dst.Set(reflect.New(e))
|
|
||||||
} else {
|
|
||||||
tempValue := reflect.New(e)
|
|
||||||
tempValue.Elem().Set(src.Elem())
|
|
||||||
// Sets time.Time's unexported values
|
|
||||||
dst.Set(tempValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if src.Elem().IsValid() {
|
|
||||||
// Keep the current root state since the depth hasn't changed
|
|
||||||
rcopy(dst.Elem(), src.Elem(), root)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Struct:
|
|
||||||
t := dst.Type()
|
|
||||||
for i := 0; i < t.NumField(); i++ {
|
|
||||||
name := t.Field(i).Name
|
|
||||||
srcVal := src.FieldByName(name)
|
|
||||||
dstVal := dst.FieldByName(name)
|
|
||||||
if srcVal.IsValid() && dstVal.CanSet() {
|
|
||||||
rcopy(dstVal, srcVal, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Slice:
|
|
||||||
if src.IsNil() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
|
|
||||||
dst.Set(s)
|
|
||||||
for i := 0; i < src.Len(); i++ {
|
|
||||||
rcopy(dst.Index(i), src.Index(i), false)
|
|
||||||
}
|
|
||||||
case reflect.Map:
|
|
||||||
if src.IsNil() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
s := reflect.MakeMap(src.Type())
|
|
||||||
dst.Set(s)
|
|
||||||
for _, k := range src.MapKeys() {
|
|
||||||
v := src.MapIndex(k)
|
|
||||||
v2 := reflect.New(v.Type()).Elem()
|
|
||||||
rcopy(v2, v, false)
|
|
||||||
dst.SetMapIndex(k, v2)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
// Assign the value if possible. If its not assignable, the value would
|
|
||||||
// need to be converted and the impact of that may be unexpected, or is
|
|
||||||
// not compatible with the dst type.
|
|
||||||
if src.Type().AssignableTo(dst.Type()) {
|
|
||||||
dst.Set(src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
27
vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go
generated
vendored
27
vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go
generated
vendored
@ -1,27 +0,0 @@
|
|||||||
package awsutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DeepEqual returns if the two values are deeply equal like reflect.DeepEqual.
|
|
||||||
// In addition to this, this method will also dereference the input values if
|
|
||||||
// possible so the DeepEqual performed will not fail if one parameter is a
|
|
||||||
// pointer and the other is not.
|
|
||||||
//
|
|
||||||
// DeepEqual will not perform indirection of nested values of the input parameters.
|
|
||||||
func DeepEqual(a, b interface{}) bool {
|
|
||||||
ra := reflect.Indirect(reflect.ValueOf(a))
|
|
||||||
rb := reflect.Indirect(reflect.ValueOf(b))
|
|
||||||
|
|
||||||
if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid {
|
|
||||||
// If the elements are both nil, and of the same type they are equal
|
|
||||||
// If they are of different types they are not equal
|
|
||||||
return reflect.TypeOf(a) == reflect.TypeOf(b)
|
|
||||||
} else if raValid != rbValid {
|
|
||||||
// Both values must be valid to be equal
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return reflect.DeepEqual(ra.Interface(), rb.Interface())
|
|
||||||
}
|
|
||||||
221
vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
generated
vendored
221
vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
generated
vendored
@ -1,221 +0,0 @@
|
|||||||
package awsutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/jmespath/go-jmespath"
|
|
||||||
)
|
|
||||||
|
|
||||||
var indexRe = regexp.MustCompile(`(.+)\[(-?\d+)?\]$`)
|
|
||||||
|
|
||||||
// rValuesAtPath returns a slice of values found in value v. The values
|
|
||||||
// in v are explored recursively so all nested values are collected.
|
|
||||||
func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTerm bool) []reflect.Value {
|
|
||||||
pathparts := strings.Split(path, "||")
|
|
||||||
if len(pathparts) > 1 {
|
|
||||||
for _, pathpart := range pathparts {
|
|
||||||
vals := rValuesAtPath(v, pathpart, createPath, caseSensitive, nilTerm)
|
|
||||||
if len(vals) > 0 {
|
|
||||||
return vals
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
values := []reflect.Value{reflect.Indirect(reflect.ValueOf(v))}
|
|
||||||
components := strings.Split(path, ".")
|
|
||||||
for len(values) > 0 && len(components) > 0 {
|
|
||||||
var index *int64
|
|
||||||
var indexStar bool
|
|
||||||
c := strings.TrimSpace(components[0])
|
|
||||||
if c == "" { // no actual component, illegal syntax
|
|
||||||
return nil
|
|
||||||
} else if caseSensitive && c != "*" && strings.ToLower(c[0:1]) == c[0:1] {
|
|
||||||
// TODO normalize case for user
|
|
||||||
return nil // don't support unexported fields
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse this component
|
|
||||||
if m := indexRe.FindStringSubmatch(c); m != nil {
|
|
||||||
c = m[1]
|
|
||||||
if m[2] == "" {
|
|
||||||
index = nil
|
|
||||||
indexStar = true
|
|
||||||
} else {
|
|
||||||
i, _ := strconv.ParseInt(m[2], 10, 32)
|
|
||||||
index = &i
|
|
||||||
indexStar = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nextvals := []reflect.Value{}
|
|
||||||
for _, value := range values {
|
|
||||||
// pull component name out of struct member
|
|
||||||
if value.Kind() != reflect.Struct {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if c == "*" { // pull all members
|
|
||||||
for i := 0; i < value.NumField(); i++ {
|
|
||||||
if f := reflect.Indirect(value.Field(i)); f.IsValid() {
|
|
||||||
nextvals = append(nextvals, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
value = value.FieldByNameFunc(func(name string) bool {
|
|
||||||
if c == name {
|
|
||||||
return true
|
|
||||||
} else if !caseSensitive && strings.EqualFold(name, c) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if nilTerm && value.Kind() == reflect.Ptr && len(components[1:]) == 0 {
|
|
||||||
if !value.IsNil() {
|
|
||||||
value.Set(reflect.Zero(value.Type()))
|
|
||||||
}
|
|
||||||
return []reflect.Value{value}
|
|
||||||
}
|
|
||||||
|
|
||||||
if createPath && value.Kind() == reflect.Ptr && value.IsNil() {
|
|
||||||
// TODO if the value is the terminus it should not be created
|
|
||||||
// if the value to be set to its position is nil.
|
|
||||||
value.Set(reflect.New(value.Type().Elem()))
|
|
||||||
value = value.Elem()
|
|
||||||
} else {
|
|
||||||
value = reflect.Indirect(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
|
|
||||||
if !createPath && value.IsNil() {
|
|
||||||
value = reflect.ValueOf(nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if value.IsValid() {
|
|
||||||
nextvals = append(nextvals, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
values = nextvals
|
|
||||||
|
|
||||||
if indexStar || index != nil {
|
|
||||||
nextvals = []reflect.Value{}
|
|
||||||
for _, valItem := range values {
|
|
||||||
value := reflect.Indirect(valItem)
|
|
||||||
if value.Kind() != reflect.Slice {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if indexStar { // grab all indices
|
|
||||||
for i := 0; i < value.Len(); i++ {
|
|
||||||
idx := reflect.Indirect(value.Index(i))
|
|
||||||
if idx.IsValid() {
|
|
||||||
nextvals = append(nextvals, idx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// pull out index
|
|
||||||
i := int(*index)
|
|
||||||
if i >= value.Len() { // check out of bounds
|
|
||||||
if createPath {
|
|
||||||
// TODO resize slice
|
|
||||||
} else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else if i < 0 { // support negative indexing
|
|
||||||
i = value.Len() + i
|
|
||||||
}
|
|
||||||
value = reflect.Indirect(value.Index(i))
|
|
||||||
|
|
||||||
if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
|
|
||||||
if !createPath && value.IsNil() {
|
|
||||||
value = reflect.ValueOf(nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if value.IsValid() {
|
|
||||||
nextvals = append(nextvals, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
values = nextvals
|
|
||||||
}
|
|
||||||
|
|
||||||
components = components[1:]
|
|
||||||
}
|
|
||||||
return values
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValuesAtPath returns a list of values at the case insensitive lexical
|
|
||||||
// path inside of a structure.
|
|
||||||
func ValuesAtPath(i interface{}, path string) ([]interface{}, error) {
|
|
||||||
result, err := jmespath.Search(path, i)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v := reflect.ValueOf(result)
|
|
||||||
if !v.IsValid() || (v.Kind() == reflect.Ptr && v.IsNil()) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
if s, ok := result.([]interface{}); ok {
|
|
||||||
return s, err
|
|
||||||
}
|
|
||||||
if v.Kind() == reflect.Map && v.Len() == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
if v.Kind() == reflect.Slice {
|
|
||||||
out := make([]interface{}, v.Len())
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
|
||||||
out[i] = v.Index(i).Interface()
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return []interface{}{result}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetValueAtPath sets a value at the case insensitive lexical path inside
|
|
||||||
// of a structure.
|
|
||||||
func SetValueAtPath(i interface{}, path string, v interface{}) {
|
|
||||||
rvals := rValuesAtPath(i, path, true, false, v == nil)
|
|
||||||
for _, rval := range rvals {
|
|
||||||
if rval.Kind() == reflect.Ptr && rval.IsNil() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
setValue(rval, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setValue(dstVal reflect.Value, src interface{}) {
|
|
||||||
if dstVal.Kind() == reflect.Ptr {
|
|
||||||
dstVal = reflect.Indirect(dstVal)
|
|
||||||
}
|
|
||||||
srcVal := reflect.ValueOf(src)
|
|
||||||
|
|
||||||
if !srcVal.IsValid() { // src is literal nil
|
|
||||||
if dstVal.CanAddr() {
|
|
||||||
// Convert to pointer so that pointer's value can be nil'ed
|
|
||||||
// dstVal = dstVal.Addr()
|
|
||||||
}
|
|
||||||
dstVal.Set(reflect.Zero(dstVal.Type()))
|
|
||||||
|
|
||||||
} else if srcVal.Kind() == reflect.Ptr {
|
|
||||||
if srcVal.IsNil() {
|
|
||||||
srcVal = reflect.Zero(dstVal.Type())
|
|
||||||
} else {
|
|
||||||
srcVal = reflect.ValueOf(src).Elem()
|
|
||||||
}
|
|
||||||
dstVal.Set(srcVal)
|
|
||||||
} else {
|
|
||||||
dstVal.Set(srcVal)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
123
vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go
generated
vendored
123
vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go
generated
vendored
@ -1,123 +0,0 @@
|
|||||||
package awsutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Prettify returns the string representation of a value.
|
|
||||||
func Prettify(i interface{}) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
prettify(reflect.ValueOf(i), 0, &buf)
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// prettify will recursively walk value v to build a textual
|
|
||||||
// representation of the value.
|
|
||||||
func prettify(v reflect.Value, indent int, buf *bytes.Buffer) {
|
|
||||||
for v.Kind() == reflect.Ptr {
|
|
||||||
v = v.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
switch v.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
strtype := v.Type().String()
|
|
||||||
if strtype == "time.Time" {
|
|
||||||
fmt.Fprintf(buf, "%s", v.Interface())
|
|
||||||
break
|
|
||||||
} else if strings.HasPrefix(strtype, "io.") {
|
|
||||||
buf.WriteString("<buffer>")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString("{\n")
|
|
||||||
|
|
||||||
names := []string{}
|
|
||||||
for i := 0; i < v.Type().NumField(); i++ {
|
|
||||||
name := v.Type().Field(i).Name
|
|
||||||
f := v.Field(i)
|
|
||||||
if name[0:1] == strings.ToLower(name[0:1]) {
|
|
||||||
continue // ignore unexported fields
|
|
||||||
}
|
|
||||||
if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() {
|
|
||||||
continue // ignore unset fields
|
|
||||||
}
|
|
||||||
names = append(names, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, n := range names {
|
|
||||||
val := v.FieldByName(n)
|
|
||||||
ft, ok := v.Type().FieldByName(n)
|
|
||||||
if !ok {
|
|
||||||
panic(fmt.Sprintf("expected to find field %v on type %v, but was not found", n, v.Type()))
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
|
||||||
buf.WriteString(n + ": ")
|
|
||||||
|
|
||||||
if tag := ft.Tag.Get("sensitive"); tag == "true" {
|
|
||||||
buf.WriteString("<sensitive>")
|
|
||||||
} else {
|
|
||||||
prettify(val, indent+2, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
if i < len(names)-1 {
|
|
||||||
buf.WriteString(",\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
|
||||||
case reflect.Slice:
|
|
||||||
strtype := v.Type().String()
|
|
||||||
if strtype == "[]uint8" {
|
|
||||||
fmt.Fprintf(buf, "<binary> len %d", v.Len())
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
nl, id, id2 := "", "", ""
|
|
||||||
if v.Len() > 3 {
|
|
||||||
nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
|
|
||||||
}
|
|
||||||
buf.WriteString("[" + nl)
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
|
||||||
buf.WriteString(id2)
|
|
||||||
prettify(v.Index(i), indent+2, buf)
|
|
||||||
|
|
||||||
if i < v.Len()-1 {
|
|
||||||
buf.WriteString("," + nl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString(nl + id + "]")
|
|
||||||
case reflect.Map:
|
|
||||||
buf.WriteString("{\n")
|
|
||||||
|
|
||||||
for i, k := range v.MapKeys() {
|
|
||||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
|
||||||
buf.WriteString(k.String() + ": ")
|
|
||||||
prettify(v.MapIndex(k), indent+2, buf)
|
|
||||||
|
|
||||||
if i < v.Len()-1 {
|
|
||||||
buf.WriteString(",\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
|
||||||
default:
|
|
||||||
if !v.IsValid() {
|
|
||||||
fmt.Fprint(buf, "<invalid value>")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
format := "%v"
|
|
||||||
switch v.Interface().(type) {
|
|
||||||
case string:
|
|
||||||
format = "%q"
|
|
||||||
case io.ReadSeeker, io.Reader:
|
|
||||||
format = "buffer(%p)"
|
|
||||||
}
|
|
||||||
fmt.Fprintf(buf, format, v.Interface())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
90
vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go
generated
vendored
90
vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go
generated
vendored
@ -1,90 +0,0 @@
|
|||||||
package awsutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StringValue returns the string representation of a value.
|
|
||||||
//
|
|
||||||
// Deprecated: Use Prettify instead.
|
|
||||||
func StringValue(i interface{}) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
stringValue(reflect.ValueOf(i), 0, &buf)
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) {
|
|
||||||
for v.Kind() == reflect.Ptr {
|
|
||||||
v = v.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
switch v.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
buf.WriteString("{\n")
|
|
||||||
|
|
||||||
for i := 0; i < v.Type().NumField(); i++ {
|
|
||||||
ft := v.Type().Field(i)
|
|
||||||
fv := v.Field(i)
|
|
||||||
|
|
||||||
if ft.Name[0:1] == strings.ToLower(ft.Name[0:1]) {
|
|
||||||
continue // ignore unexported fields
|
|
||||||
}
|
|
||||||
if (fv.Kind() == reflect.Ptr || fv.Kind() == reflect.Slice) && fv.IsNil() {
|
|
||||||
continue // ignore unset fields
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
|
||||||
buf.WriteString(ft.Name + ": ")
|
|
||||||
|
|
||||||
if tag := ft.Tag.Get("sensitive"); tag == "true" {
|
|
||||||
buf.WriteString("<sensitive>")
|
|
||||||
} else {
|
|
||||||
stringValue(fv, indent+2, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString(",\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
|
||||||
case reflect.Slice:
|
|
||||||
nl, id, id2 := "", "", ""
|
|
||||||
if v.Len() > 3 {
|
|
||||||
nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
|
|
||||||
}
|
|
||||||
buf.WriteString("[" + nl)
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
|
||||||
buf.WriteString(id2)
|
|
||||||
stringValue(v.Index(i), indent+2, buf)
|
|
||||||
|
|
||||||
if i < v.Len()-1 {
|
|
||||||
buf.WriteString("," + nl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString(nl + id + "]")
|
|
||||||
case reflect.Map:
|
|
||||||
buf.WriteString("{\n")
|
|
||||||
|
|
||||||
for i, k := range v.MapKeys() {
|
|
||||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
|
||||||
buf.WriteString(k.String() + ": ")
|
|
||||||
stringValue(v.MapIndex(k), indent+2, buf)
|
|
||||||
|
|
||||||
if i < v.Len()-1 {
|
|
||||||
buf.WriteString(",\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
|
||||||
default:
|
|
||||||
format := "%v"
|
|
||||||
switch v.Interface().(type) {
|
|
||||||
case string:
|
|
||||||
format = "%q"
|
|
||||||
}
|
|
||||||
fmt.Fprintf(buf, format, v.Interface())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
94
vendor/github.com/aws/aws-sdk-go/aws/client/client.go
generated
vendored
94
vendor/github.com/aws/aws-sdk-go/aws/client/client.go
generated
vendored
@ -1,94 +0,0 @@
|
|||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Config provides configuration to a service client instance.
|
|
||||||
type Config struct {
|
|
||||||
Config *aws.Config
|
|
||||||
Handlers request.Handlers
|
|
||||||
PartitionID string
|
|
||||||
Endpoint string
|
|
||||||
SigningRegion string
|
|
||||||
SigningName string
|
|
||||||
ResolvedRegion string
|
|
||||||
|
|
||||||
// States that the signing name did not come from a modeled source but
|
|
||||||
// was derived based on other data. Used by service client constructors
|
|
||||||
// to determine if the signin name can be overridden based on metadata the
|
|
||||||
// service has.
|
|
||||||
SigningNameDerived bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConfigProvider provides a generic way for a service client to receive
|
|
||||||
// the ClientConfig without circular dependencies.
|
|
||||||
type ConfigProvider interface {
|
|
||||||
ClientConfig(serviceName string, cfgs ...*aws.Config) Config
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConfigNoResolveEndpointProvider same as ConfigProvider except it will not
|
|
||||||
// resolve the endpoint automatically. The service client's endpoint must be
|
|
||||||
// provided via the aws.Config.Endpoint field.
|
|
||||||
type ConfigNoResolveEndpointProvider interface {
|
|
||||||
ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) Config
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Client implements the base client request and response handling
|
|
||||||
// used by all service clients.
|
|
||||||
type Client struct {
|
|
||||||
request.Retryer
|
|
||||||
metadata.ClientInfo
|
|
||||||
|
|
||||||
Config aws.Config
|
|
||||||
Handlers request.Handlers
|
|
||||||
}
|
|
||||||
|
|
||||||
// New will return a pointer to a new initialized service client.
|
|
||||||
func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, options ...func(*Client)) *Client {
|
|
||||||
svc := &Client{
|
|
||||||
Config: cfg,
|
|
||||||
ClientInfo: info,
|
|
||||||
Handlers: handlers.Copy(),
|
|
||||||
}
|
|
||||||
|
|
||||||
switch retryer, ok := cfg.Retryer.(request.Retryer); {
|
|
||||||
case ok:
|
|
||||||
svc.Retryer = retryer
|
|
||||||
case cfg.Retryer != nil && cfg.Logger != nil:
|
|
||||||
s := fmt.Sprintf("WARNING: %T does not implement request.Retryer; using DefaultRetryer instead", cfg.Retryer)
|
|
||||||
cfg.Logger.Log(s)
|
|
||||||
fallthrough
|
|
||||||
default:
|
|
||||||
maxRetries := aws.IntValue(cfg.MaxRetries)
|
|
||||||
if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries {
|
|
||||||
maxRetries = DefaultRetryerMaxNumRetries
|
|
||||||
}
|
|
||||||
svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries}
|
|
||||||
}
|
|
||||||
|
|
||||||
svc.AddDebugHandlers()
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(svc)
|
|
||||||
}
|
|
||||||
|
|
||||||
return svc
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRequest returns a new Request pointer for the service API
|
|
||||||
// operation and parameters.
|
|
||||||
func (c *Client) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request {
|
|
||||||
return request.New(c.Config, c.ClientInfo, c.Handlers, c.Retryer, operation, params, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddDebugHandlers injects debug logging handlers into the service to log request
|
|
||||||
// debug information.
|
|
||||||
func (c *Client) AddDebugHandlers() {
|
|
||||||
c.Handlers.Send.PushFrontNamed(LogHTTPRequestHandler)
|
|
||||||
c.Handlers.Send.PushBackNamed(LogHTTPResponseHandler)
|
|
||||||
}
|
|
||||||
177
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
177
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
@ -1,177 +0,0 @@
|
|||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sdkrand"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DefaultRetryer implements basic retry logic using exponential backoff for
|
|
||||||
// most services. If you want to implement custom retry logic, you can implement the
|
|
||||||
// request.Retryer interface.
|
|
||||||
//
|
|
||||||
type DefaultRetryer struct {
|
|
||||||
// Num max Retries is the number of max retries that will be performed.
|
|
||||||
// By default, this is zero.
|
|
||||||
NumMaxRetries int
|
|
||||||
|
|
||||||
// MinRetryDelay is the minimum retry delay after which retry will be performed.
|
|
||||||
// If not set, the value is 0ns.
|
|
||||||
MinRetryDelay time.Duration
|
|
||||||
|
|
||||||
// MinThrottleRetryDelay is the minimum retry delay when throttled.
|
|
||||||
// If not set, the value is 0ns.
|
|
||||||
MinThrottleDelay time.Duration
|
|
||||||
|
|
||||||
// MaxRetryDelay is the maximum retry delay before which retry must be performed.
|
|
||||||
// If not set, the value is 0ns.
|
|
||||||
MaxRetryDelay time.Duration
|
|
||||||
|
|
||||||
// MaxThrottleDelay is the maximum retry delay when throttled.
|
|
||||||
// If not set, the value is 0ns.
|
|
||||||
MaxThrottleDelay time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DefaultRetryerMaxNumRetries sets maximum number of retries
|
|
||||||
DefaultRetryerMaxNumRetries = 3
|
|
||||||
|
|
||||||
// DefaultRetryerMinRetryDelay sets minimum retry delay
|
|
||||||
DefaultRetryerMinRetryDelay = 30 * time.Millisecond
|
|
||||||
|
|
||||||
// DefaultRetryerMinThrottleDelay sets minimum delay when throttled
|
|
||||||
DefaultRetryerMinThrottleDelay = 500 * time.Millisecond
|
|
||||||
|
|
||||||
// DefaultRetryerMaxRetryDelay sets maximum retry delay
|
|
||||||
DefaultRetryerMaxRetryDelay = 300 * time.Second
|
|
||||||
|
|
||||||
// DefaultRetryerMaxThrottleDelay sets maximum delay when throttled
|
|
||||||
DefaultRetryerMaxThrottleDelay = 300 * time.Second
|
|
||||||
)
|
|
||||||
|
|
||||||
// MaxRetries returns the number of maximum returns the service will use to make
|
|
||||||
// an individual API request.
|
|
||||||
func (d DefaultRetryer) MaxRetries() int {
|
|
||||||
return d.NumMaxRetries
|
|
||||||
}
|
|
||||||
|
|
||||||
// setRetryerDefaults sets the default values of the retryer if not set
|
|
||||||
func (d *DefaultRetryer) setRetryerDefaults() {
|
|
||||||
if d.MinRetryDelay == 0 {
|
|
||||||
d.MinRetryDelay = DefaultRetryerMinRetryDelay
|
|
||||||
}
|
|
||||||
if d.MaxRetryDelay == 0 {
|
|
||||||
d.MaxRetryDelay = DefaultRetryerMaxRetryDelay
|
|
||||||
}
|
|
||||||
if d.MinThrottleDelay == 0 {
|
|
||||||
d.MinThrottleDelay = DefaultRetryerMinThrottleDelay
|
|
||||||
}
|
|
||||||
if d.MaxThrottleDelay == 0 {
|
|
||||||
d.MaxThrottleDelay = DefaultRetryerMaxThrottleDelay
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetryRules returns the delay duration before retrying this request again
|
|
||||||
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
|
|
||||||
|
|
||||||
// if number of max retries is zero, no retries will be performed.
|
|
||||||
if d.NumMaxRetries == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets default value for retryer members
|
|
||||||
d.setRetryerDefaults()
|
|
||||||
|
|
||||||
// minDelay is the minimum retryer delay
|
|
||||||
minDelay := d.MinRetryDelay
|
|
||||||
|
|
||||||
var initialDelay time.Duration
|
|
||||||
|
|
||||||
isThrottle := r.IsErrorThrottle()
|
|
||||||
if isThrottle {
|
|
||||||
if delay, ok := getRetryAfterDelay(r); ok {
|
|
||||||
initialDelay = delay
|
|
||||||
}
|
|
||||||
minDelay = d.MinThrottleDelay
|
|
||||||
}
|
|
||||||
|
|
||||||
retryCount := r.RetryCount
|
|
||||||
|
|
||||||
// maxDelay the maximum retryer delay
|
|
||||||
maxDelay := d.MaxRetryDelay
|
|
||||||
|
|
||||||
if isThrottle {
|
|
||||||
maxDelay = d.MaxThrottleDelay
|
|
||||||
}
|
|
||||||
|
|
||||||
var delay time.Duration
|
|
||||||
|
|
||||||
// Logic to cap the retry count based on the minDelay provided
|
|
||||||
actualRetryCount := int(math.Log2(float64(minDelay))) + 1
|
|
||||||
if actualRetryCount < 63-retryCount {
|
|
||||||
delay = time.Duration(1<<uint64(retryCount)) * getJitterDelay(minDelay)
|
|
||||||
if delay > maxDelay {
|
|
||||||
delay = getJitterDelay(maxDelay / 2)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
delay = getJitterDelay(maxDelay / 2)
|
|
||||||
}
|
|
||||||
return delay + initialDelay
|
|
||||||
}
|
|
||||||
|
|
||||||
// getJitterDelay returns a jittered delay for retry
|
|
||||||
func getJitterDelay(duration time.Duration) time.Duration {
|
|
||||||
return time.Duration(sdkrand.SeededRand.Int63n(int64(duration)) + int64(duration))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShouldRetry returns true if the request should be retried.
|
|
||||||
func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
|
|
||||||
|
|
||||||
// ShouldRetry returns false if number of max retries is 0.
|
|
||||||
if d.NumMaxRetries == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// If one of the other handlers already set the retry state
|
|
||||||
// we don't want to override it based on the service's state
|
|
||||||
if r.Retryable != nil {
|
|
||||||
return *r.Retryable
|
|
||||||
}
|
|
||||||
return r.IsErrorRetryable() || r.IsErrorThrottle()
|
|
||||||
}
|
|
||||||
|
|
||||||
// This will look in the Retry-After header, RFC 7231, for how long
|
|
||||||
// it will wait before attempting another request
|
|
||||||
func getRetryAfterDelay(r *request.Request) (time.Duration, bool) {
|
|
||||||
if !canUseRetryAfterHeader(r) {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
delayStr := r.HTTPResponse.Header.Get("Retry-After")
|
|
||||||
if len(delayStr) == 0 {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
delay, err := strconv.Atoi(delayStr)
|
|
||||||
if err != nil {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
return time.Duration(delay) * time.Second, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Will look at the status code to see if the retry header pertains to
|
|
||||||
// the status code.
|
|
||||||
func canUseRetryAfterHeader(r *request.Request) bool {
|
|
||||||
switch r.HTTPResponse.StatusCode {
|
|
||||||
case 429:
|
|
||||||
case 503:
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
206
vendor/github.com/aws/aws-sdk-go/aws/client/logger.go
generated
vendored
206
vendor/github.com/aws/aws-sdk-go/aws/client/logger.go
generated
vendored
@ -1,206 +0,0 @@
|
|||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http/httputil"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
const logReqMsg = `DEBUG: Request %s/%s Details:
|
|
||||||
---[ REQUEST POST-SIGN ]-----------------------------
|
|
||||||
%s
|
|
||||||
-----------------------------------------------------`
|
|
||||||
|
|
||||||
const logReqErrMsg = `DEBUG ERROR: Request %s/%s:
|
|
||||||
---[ REQUEST DUMP ERROR ]-----------------------------
|
|
||||||
%s
|
|
||||||
------------------------------------------------------`
|
|
||||||
|
|
||||||
type logWriter struct {
|
|
||||||
// Logger is what we will use to log the payload of a response.
|
|
||||||
Logger aws.Logger
|
|
||||||
// buf stores the contents of what has been read
|
|
||||||
buf *bytes.Buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *logWriter) Write(b []byte) (int, error) {
|
|
||||||
return logger.buf.Write(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
type teeReaderCloser struct {
|
|
||||||
// io.Reader will be a tee reader that is used during logging.
|
|
||||||
// This structure will read from a body and write the contents to a logger.
|
|
||||||
io.Reader
|
|
||||||
// Source is used just to close when we are done reading.
|
|
||||||
Source io.ReadCloser
|
|
||||||
}
|
|
||||||
|
|
||||||
func (reader *teeReaderCloser) Close() error {
|
|
||||||
return reader.Source.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogHTTPRequestHandler is a SDK request handler to log the HTTP request sent
|
|
||||||
// to a service. Will include the HTTP request body if the LogLevel of the
|
|
||||||
// request matches LogDebugWithHTTPBody.
|
|
||||||
var LogHTTPRequestHandler = request.NamedHandler{
|
|
||||||
Name: "awssdk.client.LogRequest",
|
|
||||||
Fn: logRequest,
|
|
||||||
}
|
|
||||||
|
|
||||||
func logRequest(r *request.Request) {
|
|
||||||
if !r.Config.LogLevel.AtLeast(aws.LogDebug) || r.Config.Logger == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
|
||||||
bodySeekable := aws.IsReaderSeekable(r.Body)
|
|
||||||
|
|
||||||
b, err := httputil.DumpRequestOut(r.HTTPRequest, logBody)
|
|
||||||
if err != nil {
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if logBody {
|
|
||||||
if !bodySeekable {
|
|
||||||
r.SetReaderBody(aws.ReadSeekCloser(r.HTTPRequest.Body))
|
|
||||||
}
|
|
||||||
// Reset the request body because dumpRequest will re-wrap the
|
|
||||||
// r.HTTPRequest's Body as a NoOpCloser and will not be reset after
|
|
||||||
// read by the HTTP client reader.
|
|
||||||
if err := r.Error; err != nil {
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logReqMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogHTTPRequestHeaderHandler is a SDK request handler to log the HTTP request sent
|
|
||||||
// to a service. Will only log the HTTP request's headers. The request payload
|
|
||||||
// will not be read.
|
|
||||||
var LogHTTPRequestHeaderHandler = request.NamedHandler{
|
|
||||||
Name: "awssdk.client.LogRequestHeader",
|
|
||||||
Fn: logRequestHeader,
|
|
||||||
}
|
|
||||||
|
|
||||||
func logRequestHeader(r *request.Request) {
|
|
||||||
if !r.Config.LogLevel.AtLeast(aws.LogDebug) || r.Config.Logger == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := httputil.DumpRequestOut(r.HTTPRequest, false)
|
|
||||||
if err != nil {
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logReqMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
const logRespMsg = `DEBUG: Response %s/%s Details:
|
|
||||||
---[ RESPONSE ]--------------------------------------
|
|
||||||
%s
|
|
||||||
-----------------------------------------------------`
|
|
||||||
|
|
||||||
const logRespErrMsg = `DEBUG ERROR: Response %s/%s:
|
|
||||||
---[ RESPONSE DUMP ERROR ]-----------------------------
|
|
||||||
%s
|
|
||||||
-----------------------------------------------------`
|
|
||||||
|
|
||||||
// LogHTTPResponseHandler is a SDK request handler to log the HTTP response
|
|
||||||
// received from a service. Will include the HTTP response body if the LogLevel
|
|
||||||
// of the request matches LogDebugWithHTTPBody.
|
|
||||||
var LogHTTPResponseHandler = request.NamedHandler{
|
|
||||||
Name: "awssdk.client.LogResponse",
|
|
||||||
Fn: logResponse,
|
|
||||||
}
|
|
||||||
|
|
||||||
func logResponse(r *request.Request) {
|
|
||||||
if !r.Config.LogLevel.AtLeast(aws.LogDebug) || r.Config.Logger == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
lw := &logWriter{r.Config.Logger, bytes.NewBuffer(nil)}
|
|
||||||
|
|
||||||
if r.HTTPResponse == nil {
|
|
||||||
lw.Logger.Log(fmt.Sprintf(logRespErrMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, "request's HTTPResponse is nil"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
|
||||||
if logBody {
|
|
||||||
r.HTTPResponse.Body = &teeReaderCloser{
|
|
||||||
Reader: io.TeeReader(r.HTTPResponse.Body, lw),
|
|
||||||
Source: r.HTTPResponse.Body,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handlerFn := func(req *request.Request) {
|
|
||||||
b, err := httputil.DumpResponse(req.HTTPResponse, false)
|
|
||||||
if err != nil {
|
|
||||||
lw.Logger.Log(fmt.Sprintf(logRespErrMsg,
|
|
||||||
req.ClientInfo.ServiceName, req.Operation.Name, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
lw.Logger.Log(fmt.Sprintf(logRespMsg,
|
|
||||||
req.ClientInfo.ServiceName, req.Operation.Name, string(b)))
|
|
||||||
|
|
||||||
if logBody {
|
|
||||||
b, err := ioutil.ReadAll(lw.buf)
|
|
||||||
if err != nil {
|
|
||||||
lw.Logger.Log(fmt.Sprintf(logRespErrMsg,
|
|
||||||
req.ClientInfo.ServiceName, req.Operation.Name, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
lw.Logger.Log(string(b))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handlerName = "awsdk.client.LogResponse.ResponseBody"
|
|
||||||
|
|
||||||
r.Handlers.Unmarshal.SetBackNamed(request.NamedHandler{
|
|
||||||
Name: handlerName, Fn: handlerFn,
|
|
||||||
})
|
|
||||||
r.Handlers.UnmarshalError.SetBackNamed(request.NamedHandler{
|
|
||||||
Name: handlerName, Fn: handlerFn,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogHTTPResponseHeaderHandler is a SDK request handler to log the HTTP
|
|
||||||
// response received from a service. Will only log the HTTP response's headers.
|
|
||||||
// The response payload will not be read.
|
|
||||||
var LogHTTPResponseHeaderHandler = request.NamedHandler{
|
|
||||||
Name: "awssdk.client.LogResponseHeader",
|
|
||||||
Fn: logResponseHeader,
|
|
||||||
}
|
|
||||||
|
|
||||||
func logResponseHeader(r *request.Request) {
|
|
||||||
if !r.Config.LogLevel.AtLeast(aws.LogDebug) || r.Config.Logger == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := httputil.DumpResponse(r.HTTPResponse, false)
|
|
||||||
if err != nil {
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logRespMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
|
|
||||||
}
|
|
||||||
15
vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go
generated
vendored
15
vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go
generated
vendored
@ -1,15 +0,0 @@
|
|||||||
package metadata
|
|
||||||
|
|
||||||
// ClientInfo wraps immutable data from the client.Client structure.
|
|
||||||
type ClientInfo struct {
|
|
||||||
ServiceName string
|
|
||||||
ServiceID string
|
|
||||||
APIVersion string
|
|
||||||
PartitionID string
|
|
||||||
Endpoint string
|
|
||||||
SigningName string
|
|
||||||
SigningRegion string
|
|
||||||
JSONVersion string
|
|
||||||
TargetPrefix string
|
|
||||||
ResolvedRegion string
|
|
||||||
}
|
|
||||||
28
vendor/github.com/aws/aws-sdk-go/aws/client/no_op_retryer.go
generated
vendored
28
vendor/github.com/aws/aws-sdk-go/aws/client/no_op_retryer.go
generated
vendored
@ -1,28 +0,0 @@
|
|||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NoOpRetryer provides a retryer that performs no retries.
|
|
||||||
// It should be used when we do not want retries to be performed.
|
|
||||||
type NoOpRetryer struct{}
|
|
||||||
|
|
||||||
// MaxRetries returns the number of maximum returns the service will use to make
|
|
||||||
// an individual API; For NoOpRetryer the MaxRetries will always be zero.
|
|
||||||
func (d NoOpRetryer) MaxRetries() int {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShouldRetry will always return false for NoOpRetryer, as it should never retry.
|
|
||||||
func (d NoOpRetryer) ShouldRetry(_ *request.Request) bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetryRules returns the delay duration before retrying this request again;
|
|
||||||
// since NoOpRetryer does not retry, RetryRules always returns 0.
|
|
||||||
func (d NoOpRetryer) RetryRules(_ *request.Request) time.Duration {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
670
vendor/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
670
vendor/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
@ -1,670 +0,0 @@
|
|||||||
package aws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/endpoints"
|
|
||||||
)
|
|
||||||
|
|
||||||
// UseServiceDefaultRetries instructs the config to use the service's own
|
|
||||||
// default number of retries. This will be the default action if
|
|
||||||
// Config.MaxRetries is nil also.
|
|
||||||
const UseServiceDefaultRetries = -1
|
|
||||||
|
|
||||||
// RequestRetryer is an alias for a type that implements the request.Retryer
|
|
||||||
// interface.
|
|
||||||
type RequestRetryer interface{}
|
|
||||||
|
|
||||||
// A Config provides service configuration for service clients. By default,
|
|
||||||
// all clients will use the defaults.DefaultConfig structure.
|
|
||||||
//
|
|
||||||
// // Create Session with MaxRetries configuration to be shared by multiple
|
|
||||||
// // service clients.
|
|
||||||
// sess := session.Must(session.NewSession(&aws.Config{
|
|
||||||
// MaxRetries: aws.Int(3),
|
|
||||||
// }))
|
|
||||||
//
|
|
||||||
// // Create S3 service client with a specific Region.
|
|
||||||
// svc := s3.New(sess, &aws.Config{
|
|
||||||
// Region: aws.String("us-west-2"),
|
|
||||||
// })
|
|
||||||
type Config struct {
|
|
||||||
// Enables verbose error printing of all credential chain errors.
|
|
||||||
// Should be used when wanting to see all errors while attempting to
|
|
||||||
// retrieve credentials.
|
|
||||||
CredentialsChainVerboseErrors *bool
|
|
||||||
|
|
||||||
// The credentials object to use when signing requests. Defaults to a
|
|
||||||
// chain of credential providers to search for credentials in environment
|
|
||||||
// variables, shared credential file, and EC2 Instance Roles.
|
|
||||||
Credentials *credentials.Credentials
|
|
||||||
|
|
||||||
// An optional endpoint URL (hostname only or fully qualified URI)
|
|
||||||
// that overrides the default generated endpoint for a client. Set this
|
|
||||||
// to `nil` or the value to `""` to use the default generated endpoint.
|
|
||||||
//
|
|
||||||
// Note: You must still provide a `Region` value when specifying an
|
|
||||||
// endpoint for a client.
|
|
||||||
Endpoint *string
|
|
||||||
|
|
||||||
// The resolver to use for looking up endpoints for AWS service clients
|
|
||||||
// to use based on region.
|
|
||||||
EndpointResolver endpoints.Resolver
|
|
||||||
|
|
||||||
// EnforceShouldRetryCheck is used in the AfterRetryHandler to always call
|
|
||||||
// ShouldRetry regardless of whether or not if request.Retryable is set.
|
|
||||||
// This will utilize ShouldRetry method of custom retryers. If EnforceShouldRetryCheck
|
|
||||||
// is not set, then ShouldRetry will only be called if request.Retryable is nil.
|
|
||||||
// Proper handling of the request.Retryable field is important when setting this field.
|
|
||||||
EnforceShouldRetryCheck *bool
|
|
||||||
|
|
||||||
// The region to send requests to. This parameter is required and must
|
|
||||||
// be configured globally or on a per-client basis unless otherwise
|
|
||||||
// noted. A full list of regions is found in the "Regions and Endpoints"
|
|
||||||
// document.
|
|
||||||
//
|
|
||||||
// See http://docs.aws.amazon.com/general/latest/gr/rande.html for AWS
|
|
||||||
// Regions and Endpoints.
|
|
||||||
Region *string
|
|
||||||
|
|
||||||
// Set this to `true` to disable SSL when sending requests. Defaults
|
|
||||||
// to `false`.
|
|
||||||
DisableSSL *bool
|
|
||||||
|
|
||||||
// The HTTP client to use when sending requests. Defaults to
|
|
||||||
// `http.DefaultClient`.
|
|
||||||
HTTPClient *http.Client
|
|
||||||
|
|
||||||
// An integer value representing the logging level. The default log level
|
|
||||||
// is zero (LogOff), which represents no logging. To enable logging set
|
|
||||||
// to a LogLevel Value.
|
|
||||||
LogLevel *LogLevelType
|
|
||||||
|
|
||||||
// The logger writer interface to write logging messages to. Defaults to
|
|
||||||
// standard out.
|
|
||||||
Logger Logger
|
|
||||||
|
|
||||||
// The maximum number of times that a request will be retried for failures.
|
|
||||||
// Defaults to -1, which defers the max retry setting to the service
|
|
||||||
// specific configuration.
|
|
||||||
MaxRetries *int
|
|
||||||
|
|
||||||
// Retryer guides how HTTP requests should be retried in case of
|
|
||||||
// recoverable failures.
|
|
||||||
//
|
|
||||||
// When nil or the value does not implement the request.Retryer interface,
|
|
||||||
// the client.DefaultRetryer will be used.
|
|
||||||
//
|
|
||||||
// When both Retryer and MaxRetries are non-nil, the former is used and
|
|
||||||
// the latter ignored.
|
|
||||||
//
|
|
||||||
// To set the Retryer field in a type-safe manner and with chaining, use
|
|
||||||
// the request.WithRetryer helper function:
|
|
||||||
//
|
|
||||||
// cfg := request.WithRetryer(aws.NewConfig(), myRetryer)
|
|
||||||
//
|
|
||||||
Retryer RequestRetryer
|
|
||||||
|
|
||||||
// Disables semantic parameter validation, which validates input for
|
|
||||||
// missing required fields and/or other semantic request input errors.
|
|
||||||
DisableParamValidation *bool
|
|
||||||
|
|
||||||
// Disables the computation of request and response checksums, e.g.,
|
|
||||||
// CRC32 checksums in Amazon DynamoDB.
|
|
||||||
DisableComputeChecksums *bool
|
|
||||||
|
|
||||||
// Set this to `true` to force the request to use path-style addressing,
|
|
||||||
// i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client
|
|
||||||
// will use virtual hosted bucket addressing when possible
|
|
||||||
// (`http://BUCKET.s3.amazonaws.com/KEY`).
|
|
||||||
//
|
|
||||||
// Note: This configuration option is specific to the Amazon S3 service.
|
|
||||||
//
|
|
||||||
// See http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html
|
|
||||||
// for Amazon S3: Virtual Hosting of Buckets
|
|
||||||
S3ForcePathStyle *bool
|
|
||||||
|
|
||||||
// Set this to `true` to disable the SDK adding the `Expect: 100-Continue`
|
|
||||||
// header to PUT requests over 2MB of content. 100-Continue instructs the
|
|
||||||
// HTTP client not to send the body until the service responds with a
|
|
||||||
// `continue` status. This is useful to prevent sending the request body
|
|
||||||
// until after the request is authenticated, and validated.
|
|
||||||
//
|
|
||||||
// http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
|
|
||||||
//
|
|
||||||
// 100-Continue is only enabled for Go 1.6 and above. See `http.Transport`'s
|
|
||||||
// `ExpectContinueTimeout` for information on adjusting the continue wait
|
|
||||||
// timeout. https://golang.org/pkg/net/http/#Transport
|
|
||||||
//
|
|
||||||
// You should use this flag to disable 100-Continue if you experience issues
|
|
||||||
// with proxies or third party S3 compatible services.
|
|
||||||
S3Disable100Continue *bool
|
|
||||||
|
|
||||||
// Set this to `true` to enable S3 Accelerate feature. For all operations
|
|
||||||
// compatible with S3 Accelerate will use the accelerate endpoint for
|
|
||||||
// requests. Requests not compatible will fall back to normal S3 requests.
|
|
||||||
//
|
|
||||||
// The bucket must be enable for accelerate to be used with S3 client with
|
|
||||||
// accelerate enabled. If the bucket is not enabled for accelerate an error
|
|
||||||
// will be returned. The bucket name must be DNS compatible to also work
|
|
||||||
// with accelerate.
|
|
||||||
S3UseAccelerate *bool
|
|
||||||
|
|
||||||
// S3DisableContentMD5Validation config option is temporarily disabled,
|
|
||||||
// For S3 GetObject API calls, #1837.
|
|
||||||
//
|
|
||||||
// Set this to `true` to disable the S3 service client from automatically
|
|
||||||
// adding the ContentMD5 to S3 Object Put and Upload API calls. This option
|
|
||||||
// will also disable the SDK from performing object ContentMD5 validation
|
|
||||||
// on GetObject API calls.
|
|
||||||
S3DisableContentMD5Validation *bool
|
|
||||||
|
|
||||||
// Set this to `true` to have the S3 service client to use the region specified
|
|
||||||
// in the ARN, when an ARN is provided as an argument to a bucket parameter.
|
|
||||||
S3UseARNRegion *bool
|
|
||||||
|
|
||||||
// Set this to `true` to enable the SDK to unmarshal API response header maps to
|
|
||||||
// normalized lower case map keys.
|
|
||||||
//
|
|
||||||
// For example S3's X-Amz-Meta prefixed header will be unmarshaled to lower case
|
|
||||||
// Metadata member's map keys. The value of the header in the map is unaffected.
|
|
||||||
//
|
|
||||||
// The AWS SDK for Go v2, uses lower case header maps by default. The v1
|
|
||||||
// SDK provides this opt-in for this option, for backwards compatibility.
|
|
||||||
LowerCaseHeaderMaps *bool
|
|
||||||
|
|
||||||
// Set this to `true` to disable the EC2Metadata client from overriding the
|
|
||||||
// default http.Client's Timeout. This is helpful if you do not want the
|
|
||||||
// EC2Metadata client to create a new http.Client. This options is only
|
|
||||||
// meaningful if you're not already using a custom HTTP client with the
|
|
||||||
// SDK. Enabled by default.
|
|
||||||
//
|
|
||||||
// Must be set and provided to the session.NewSession() in order to disable
|
|
||||||
// the EC2Metadata overriding the timeout for default credentials chain.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// sess := session.Must(session.NewSession(aws.NewConfig()
|
|
||||||
// .WithEC2MetadataDisableTimeoutOverride(true)))
|
|
||||||
//
|
|
||||||
// svc := s3.New(sess)
|
|
||||||
//
|
|
||||||
EC2MetadataDisableTimeoutOverride *bool
|
|
||||||
|
|
||||||
// Set this to `false` to disable EC2Metadata client from falling back to IMDSv1.
|
|
||||||
// By default, EC2 role credentials will fall back to IMDSv1 as needed for backwards compatibility.
|
|
||||||
// You can disable this behavior by explicitly setting this flag to `false`. When false, the EC2Metadata
|
|
||||||
// client will return any errors encountered from attempting to fetch a token instead of silently
|
|
||||||
// using the insecure data flow of IMDSv1.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// sess := session.Must(session.NewSession(aws.NewConfig()
|
|
||||||
// .WithEC2MetadataEnableFallback(false)))
|
|
||||||
//
|
|
||||||
// svc := s3.New(sess)
|
|
||||||
//
|
|
||||||
// See [configuring IMDS] for more information.
|
|
||||||
//
|
|
||||||
// [configuring IMDS]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html
|
|
||||||
EC2MetadataEnableFallback *bool
|
|
||||||
|
|
||||||
// Instructs the endpoint to be generated for a service client to
|
|
||||||
// be the dual stack endpoint. The dual stack endpoint will support
|
|
||||||
// both IPv4 and IPv6 addressing.
|
|
||||||
//
|
|
||||||
// Setting this for a service which does not support dual stack will fail
|
|
||||||
// to make requests. It is not recommended to set this value on the session
|
|
||||||
// as it will apply to all service clients created with the session. Even
|
|
||||||
// services which don't support dual stack endpoints.
|
|
||||||
//
|
|
||||||
// If the Endpoint config value is also provided the UseDualStack flag
|
|
||||||
// will be ignored.
|
|
||||||
//
|
|
||||||
// Only supported with.
|
|
||||||
//
|
|
||||||
// sess := session.Must(session.NewSession())
|
|
||||||
//
|
|
||||||
// svc := s3.New(sess, &aws.Config{
|
|
||||||
// UseDualStack: aws.Bool(true),
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// Deprecated: This option will continue to function for S3 and S3 Control for backwards compatibility.
|
|
||||||
// UseDualStackEndpoint should be used to enable usage of a service's dual-stack endpoint for all service clients
|
|
||||||
// moving forward. For S3 and S3 Control, when UseDualStackEndpoint is set to a non-zero value it takes higher
|
|
||||||
// precedence then this option.
|
|
||||||
UseDualStack *bool
|
|
||||||
|
|
||||||
// Sets the resolver to resolve a dual-stack endpoint for the service.
|
|
||||||
UseDualStackEndpoint endpoints.DualStackEndpointState
|
|
||||||
|
|
||||||
// UseFIPSEndpoint specifies the resolver must resolve a FIPS endpoint.
|
|
||||||
UseFIPSEndpoint endpoints.FIPSEndpointState
|
|
||||||
|
|
||||||
// SleepDelay is an override for the func the SDK will call when sleeping
|
|
||||||
// during the lifecycle of a request. Specifically this will be used for
|
|
||||||
// request delays. This value should only be used for testing. To adjust
|
|
||||||
// the delay of a request see the aws/client.DefaultRetryer and
|
|
||||||
// aws/request.Retryer.
|
|
||||||
//
|
|
||||||
// SleepDelay will prevent any Context from being used for canceling retry
|
|
||||||
// delay of an API operation. It is recommended to not use SleepDelay at all
|
|
||||||
// and specify a Retryer instead.
|
|
||||||
SleepDelay func(time.Duration)
|
|
||||||
|
|
||||||
// DisableRestProtocolURICleaning will not clean the URL path when making rest protocol requests.
|
|
||||||
// Will default to false. This would only be used for empty directory names in s3 requests.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// sess := session.Must(session.NewSession(&aws.Config{
|
|
||||||
// DisableRestProtocolURICleaning: aws.Bool(true),
|
|
||||||
// }))
|
|
||||||
//
|
|
||||||
// svc := s3.New(sess)
|
|
||||||
// out, err := svc.GetObject(&s3.GetObjectInput {
|
|
||||||
// Bucket: aws.String("bucketname"),
|
|
||||||
// Key: aws.String("//foo//bar//moo"),
|
|
||||||
// })
|
|
||||||
DisableRestProtocolURICleaning *bool
|
|
||||||
|
|
||||||
// EnableEndpointDiscovery will allow for endpoint discovery on operations that
|
|
||||||
// have the definition in its model. By default, endpoint discovery is off.
|
|
||||||
// To use EndpointDiscovery, Endpoint should be unset or set to an empty string.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// sess := session.Must(session.NewSession(&aws.Config{
|
|
||||||
// EnableEndpointDiscovery: aws.Bool(true),
|
|
||||||
// }))
|
|
||||||
//
|
|
||||||
// svc := s3.New(sess)
|
|
||||||
// out, err := svc.GetObject(&s3.GetObjectInput {
|
|
||||||
// Bucket: aws.String("bucketname"),
|
|
||||||
// Key: aws.String("/foo/bar/moo"),
|
|
||||||
// })
|
|
||||||
EnableEndpointDiscovery *bool
|
|
||||||
|
|
||||||
// DisableEndpointHostPrefix will disable the SDK's behavior of prefixing
|
|
||||||
// request endpoint hosts with modeled information.
|
|
||||||
//
|
|
||||||
// Disabling this feature is useful when you want to use local endpoints
|
|
||||||
// for testing that do not support the modeled host prefix pattern.
|
|
||||||
DisableEndpointHostPrefix *bool
|
|
||||||
|
|
||||||
// STSRegionalEndpoint will enable regional or legacy endpoint resolving
|
|
||||||
STSRegionalEndpoint endpoints.STSRegionalEndpoint
|
|
||||||
|
|
||||||
// S3UsEast1RegionalEndpoint will enable regional or legacy endpoint resolving
|
|
||||||
S3UsEast1RegionalEndpoint endpoints.S3UsEast1RegionalEndpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewConfig returns a new Config pointer that can be chained with builder
|
|
||||||
// methods to set multiple configuration values inline without using pointers.
|
|
||||||
//
|
|
||||||
// // Create Session with MaxRetries configuration to be shared by multiple
|
|
||||||
// // service clients.
|
|
||||||
// sess := session.Must(session.NewSession(aws.NewConfig().
|
|
||||||
// WithMaxRetries(3),
|
|
||||||
// ))
|
|
||||||
//
|
|
||||||
// // Create S3 service client with a specific Region.
|
|
||||||
// svc := s3.New(sess, aws.NewConfig().
|
|
||||||
// WithRegion("us-west-2"),
|
|
||||||
// )
|
|
||||||
func NewConfig() *Config {
|
|
||||||
return &Config{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithCredentialsChainVerboseErrors sets a config verbose errors boolean and returning
|
|
||||||
// a Config pointer.
|
|
||||||
func (c *Config) WithCredentialsChainVerboseErrors(verboseErrs bool) *Config {
|
|
||||||
c.CredentialsChainVerboseErrors = &verboseErrs
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithCredentials sets a config Credentials value returning a Config pointer
|
|
||||||
// for chaining.
|
|
||||||
func (c *Config) WithCredentials(creds *credentials.Credentials) *Config {
|
|
||||||
c.Credentials = creds
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithEndpoint sets a config Endpoint value returning a Config pointer for
|
|
||||||
// chaining.
|
|
||||||
func (c *Config) WithEndpoint(endpoint string) *Config {
|
|
||||||
c.Endpoint = &endpoint
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithEndpointResolver sets a config EndpointResolver value returning a
|
|
||||||
// Config pointer for chaining.
|
|
||||||
func (c *Config) WithEndpointResolver(resolver endpoints.Resolver) *Config {
|
|
||||||
c.EndpointResolver = resolver
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithRegion sets a config Region value returning a Config pointer for
|
|
||||||
// chaining.
|
|
||||||
func (c *Config) WithRegion(region string) *Config {
|
|
||||||
c.Region = ®ion
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithDisableSSL sets a config DisableSSL value returning a Config pointer
|
|
||||||
// for chaining.
|
|
||||||
func (c *Config) WithDisableSSL(disable bool) *Config {
|
|
||||||
c.DisableSSL = &disable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithHTTPClient sets a config HTTPClient value returning a Config pointer
|
|
||||||
// for chaining.
|
|
||||||
func (c *Config) WithHTTPClient(client *http.Client) *Config {
|
|
||||||
c.HTTPClient = client
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithMaxRetries sets a config MaxRetries value returning a Config pointer
|
|
||||||
// for chaining.
|
|
||||||
func (c *Config) WithMaxRetries(max int) *Config {
|
|
||||||
c.MaxRetries = &max
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithDisableParamValidation sets a config DisableParamValidation value
|
|
||||||
// returning a Config pointer for chaining.
|
|
||||||
func (c *Config) WithDisableParamValidation(disable bool) *Config {
|
|
||||||
c.DisableParamValidation = &disable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithDisableComputeChecksums sets a config DisableComputeChecksums value
|
|
||||||
// returning a Config pointer for chaining.
|
|
||||||
func (c *Config) WithDisableComputeChecksums(disable bool) *Config {
|
|
||||||
c.DisableComputeChecksums = &disable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithLogLevel sets a config LogLevel value returning a Config pointer for
|
|
||||||
// chaining.
|
|
||||||
func (c *Config) WithLogLevel(level LogLevelType) *Config {
|
|
||||||
c.LogLevel = &level
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithLogger sets a config Logger value returning a Config pointer for
|
|
||||||
// chaining.
|
|
||||||
func (c *Config) WithLogger(logger Logger) *Config {
|
|
||||||
c.Logger = logger
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithS3ForcePathStyle sets a config S3ForcePathStyle value returning a Config
|
|
||||||
// pointer for chaining.
|
|
||||||
func (c *Config) WithS3ForcePathStyle(force bool) *Config {
|
|
||||||
c.S3ForcePathStyle = &force
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithS3Disable100Continue sets a config S3Disable100Continue value returning
|
|
||||||
// a Config pointer for chaining.
|
|
||||||
func (c *Config) WithS3Disable100Continue(disable bool) *Config {
|
|
||||||
c.S3Disable100Continue = &disable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithS3UseAccelerate sets a config S3UseAccelerate value returning a Config
|
|
||||||
// pointer for chaining.
|
|
||||||
func (c *Config) WithS3UseAccelerate(enable bool) *Config {
|
|
||||||
c.S3UseAccelerate = &enable
|
|
||||||
return c
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithS3DisableContentMD5Validation sets a config
|
|
||||||
// S3DisableContentMD5Validation value returning a Config pointer for chaining.
|
|
||||||
func (c *Config) WithS3DisableContentMD5Validation(enable bool) *Config {
|
|
||||||
c.S3DisableContentMD5Validation = &enable
|
|
||||||
return c
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithS3UseARNRegion sets a config S3UseARNRegion value and
|
|
||||||
// returning a Config pointer for chaining
|
|
||||||
func (c *Config) WithS3UseARNRegion(enable bool) *Config {
|
|
||||||
c.S3UseARNRegion = &enable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithUseDualStack sets a config UseDualStack value returning a Config
|
|
||||||
// pointer for chaining.
|
|
||||||
func (c *Config) WithUseDualStack(enable bool) *Config {
|
|
||||||
c.UseDualStack = &enable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithUseFIPSEndpoint sets a config UseFIPSEndpoint value returning a Config
|
|
||||||
// pointer for chaining.
|
|
||||||
func (c *Config) WithUseFIPSEndpoint(enable bool) *Config {
|
|
||||||
if enable {
|
|
||||||
c.UseFIPSEndpoint = endpoints.FIPSEndpointStateEnabled
|
|
||||||
} else {
|
|
||||||
c.UseFIPSEndpoint = endpoints.FIPSEndpointStateDisabled
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value
|
|
||||||
// returning a Config pointer for chaining.
|
|
||||||
func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config {
|
|
||||||
c.EC2MetadataDisableTimeoutOverride = &enable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithEC2MetadataEnableFallback sets a config EC2MetadataEnableFallback value
|
|
||||||
// returning a Config pointer for chaining.
|
|
||||||
func (c *Config) WithEC2MetadataEnableFallback(v bool) *Config {
|
|
||||||
c.EC2MetadataEnableFallback = &v
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithSleepDelay overrides the function used to sleep while waiting for the
|
|
||||||
// next retry. Defaults to time.Sleep.
|
|
||||||
func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config {
|
|
||||||
c.SleepDelay = fn
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithEndpointDiscovery will set whether or not to use endpoint discovery.
|
|
||||||
func (c *Config) WithEndpointDiscovery(t bool) *Config {
|
|
||||||
c.EnableEndpointDiscovery = &t
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithDisableEndpointHostPrefix will set whether or not to use modeled host prefix
|
|
||||||
// when making requests.
|
|
||||||
func (c *Config) WithDisableEndpointHostPrefix(t bool) *Config {
|
|
||||||
c.DisableEndpointHostPrefix = &t
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithSTSRegionalEndpoint will set whether or not to use regional endpoint flag
|
|
||||||
// when resolving the endpoint for a service
|
|
||||||
func (c *Config) WithSTSRegionalEndpoint(sre endpoints.STSRegionalEndpoint) *Config {
|
|
||||||
c.STSRegionalEndpoint = sre
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithS3UsEast1RegionalEndpoint will set whether or not to use regional endpoint flag
|
|
||||||
// when resolving the endpoint for a service
|
|
||||||
func (c *Config) WithS3UsEast1RegionalEndpoint(sre endpoints.S3UsEast1RegionalEndpoint) *Config {
|
|
||||||
c.S3UsEast1RegionalEndpoint = sre
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithLowerCaseHeaderMaps sets a config LowerCaseHeaderMaps value
|
|
||||||
// returning a Config pointer for chaining.
|
|
||||||
func (c *Config) WithLowerCaseHeaderMaps(t bool) *Config {
|
|
||||||
c.LowerCaseHeaderMaps = &t
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithDisableRestProtocolURICleaning sets a config DisableRestProtocolURICleaning value
|
|
||||||
// returning a Config pointer for chaining.
|
|
||||||
func (c *Config) WithDisableRestProtocolURICleaning(t bool) *Config {
|
|
||||||
c.DisableRestProtocolURICleaning = &t
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// MergeIn merges the passed in configs into the existing config object.
|
|
||||||
func (c *Config) MergeIn(cfgs ...*Config) {
|
|
||||||
for _, other := range cfgs {
|
|
||||||
mergeInConfig(c, other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func mergeInConfig(dst *Config, other *Config) {
|
|
||||||
if other == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.CredentialsChainVerboseErrors != nil {
|
|
||||||
dst.CredentialsChainVerboseErrors = other.CredentialsChainVerboseErrors
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.Credentials != nil {
|
|
||||||
dst.Credentials = other.Credentials
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.Endpoint != nil {
|
|
||||||
dst.Endpoint = other.Endpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.EndpointResolver != nil {
|
|
||||||
dst.EndpointResolver = other.EndpointResolver
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.Region != nil {
|
|
||||||
dst.Region = other.Region
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.DisableSSL != nil {
|
|
||||||
dst.DisableSSL = other.DisableSSL
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.HTTPClient != nil {
|
|
||||||
dst.HTTPClient = other.HTTPClient
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.LogLevel != nil {
|
|
||||||
dst.LogLevel = other.LogLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.Logger != nil {
|
|
||||||
dst.Logger = other.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.MaxRetries != nil {
|
|
||||||
dst.MaxRetries = other.MaxRetries
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.Retryer != nil {
|
|
||||||
dst.Retryer = other.Retryer
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.DisableParamValidation != nil {
|
|
||||||
dst.DisableParamValidation = other.DisableParamValidation
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.DisableComputeChecksums != nil {
|
|
||||||
dst.DisableComputeChecksums = other.DisableComputeChecksums
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.S3ForcePathStyle != nil {
|
|
||||||
dst.S3ForcePathStyle = other.S3ForcePathStyle
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.S3Disable100Continue != nil {
|
|
||||||
dst.S3Disable100Continue = other.S3Disable100Continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.S3UseAccelerate != nil {
|
|
||||||
dst.S3UseAccelerate = other.S3UseAccelerate
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.S3DisableContentMD5Validation != nil {
|
|
||||||
dst.S3DisableContentMD5Validation = other.S3DisableContentMD5Validation
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.S3UseARNRegion != nil {
|
|
||||||
dst.S3UseARNRegion = other.S3UseARNRegion
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.UseDualStack != nil {
|
|
||||||
dst.UseDualStack = other.UseDualStack
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.UseDualStackEndpoint != endpoints.DualStackEndpointStateUnset {
|
|
||||||
dst.UseDualStackEndpoint = other.UseDualStackEndpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.EC2MetadataDisableTimeoutOverride != nil {
|
|
||||||
dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.EC2MetadataEnableFallback != nil {
|
|
||||||
dst.EC2MetadataEnableFallback = other.EC2MetadataEnableFallback
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.SleepDelay != nil {
|
|
||||||
dst.SleepDelay = other.SleepDelay
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.DisableRestProtocolURICleaning != nil {
|
|
||||||
dst.DisableRestProtocolURICleaning = other.DisableRestProtocolURICleaning
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.EnforceShouldRetryCheck != nil {
|
|
||||||
dst.EnforceShouldRetryCheck = other.EnforceShouldRetryCheck
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.EnableEndpointDiscovery != nil {
|
|
||||||
dst.EnableEndpointDiscovery = other.EnableEndpointDiscovery
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.DisableEndpointHostPrefix != nil {
|
|
||||||
dst.DisableEndpointHostPrefix = other.DisableEndpointHostPrefix
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.STSRegionalEndpoint != endpoints.UnsetSTSEndpoint {
|
|
||||||
dst.STSRegionalEndpoint = other.STSRegionalEndpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.S3UsEast1RegionalEndpoint != endpoints.UnsetS3UsEast1Endpoint {
|
|
||||||
dst.S3UsEast1RegionalEndpoint = other.S3UsEast1RegionalEndpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.LowerCaseHeaderMaps != nil {
|
|
||||||
dst.LowerCaseHeaderMaps = other.LowerCaseHeaderMaps
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.UseDualStackEndpoint != endpoints.DualStackEndpointStateUnset {
|
|
||||||
dst.UseDualStackEndpoint = other.UseDualStackEndpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.UseFIPSEndpoint != endpoints.FIPSEndpointStateUnset {
|
|
||||||
dst.UseFIPSEndpoint = other.UseFIPSEndpoint
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy will return a shallow copy of the Config object. If any additional
|
|
||||||
// configurations are provided they will be merged into the new config returned.
|
|
||||||
func (c *Config) Copy(cfgs ...*Config) *Config {
|
|
||||||
dst := &Config{}
|
|
||||||
dst.MergeIn(c)
|
|
||||||
|
|
||||||
for _, cfg := range cfgs {
|
|
||||||
dst.MergeIn(cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
38
vendor/github.com/aws/aws-sdk-go/aws/context_1_5.go
generated
vendored
38
vendor/github.com/aws/aws-sdk-go/aws/context_1_5.go
generated
vendored
@ -1,38 +0,0 @@
|
|||||||
//go:build !go1.9
|
|
||||||
// +build !go1.9
|
|
||||||
|
|
||||||
package aws
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
// Context is an copy of the Go v1.7 stdlib's context.Context interface.
|
|
||||||
// It is represented as a SDK interface to enable you to use the "WithContext"
|
|
||||||
// API methods with Go v1.6 and a Context type such as golang.org/x/net/context.
|
|
||||||
//
|
|
||||||
// See https://golang.org/pkg/context on how to use contexts.
|
|
||||||
type Context interface {
|
|
||||||
// Deadline returns the time when work done on behalf of this context
|
|
||||||
// should be canceled. Deadline returns ok==false when no deadline is
|
|
||||||
// set. Successive calls to Deadline return the same results.
|
|
||||||
Deadline() (deadline time.Time, ok bool)
|
|
||||||
|
|
||||||
// Done returns a channel that's closed when work done on behalf of this
|
|
||||||
// context should be canceled. Done may return nil if this context can
|
|
||||||
// never be canceled. Successive calls to Done return the same value.
|
|
||||||
Done() <-chan struct{}
|
|
||||||
|
|
||||||
// Err returns a non-nil error value after Done is closed. Err returns
|
|
||||||
// Canceled if the context was canceled or DeadlineExceeded if the
|
|
||||||
// context's deadline passed. No other values for Err are defined.
|
|
||||||
// After Done is closed, successive calls to Err return the same value.
|
|
||||||
Err() error
|
|
||||||
|
|
||||||
// Value returns the value associated with this context for key, or nil
|
|
||||||
// if no value is associated with key. Successive calls to Value with
|
|
||||||
// the same key returns the same result.
|
|
||||||
//
|
|
||||||
// Use context values only for request-scoped data that transits
|
|
||||||
// processes and API boundaries, not for passing optional parameters to
|
|
||||||
// functions.
|
|
||||||
Value(key interface{}) interface{}
|
|
||||||
}
|
|
||||||
12
vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go
generated
vendored
12
vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
//go:build go1.9
|
|
||||||
// +build go1.9
|
|
||||||
|
|
||||||
package aws
|
|
||||||
|
|
||||||
import "context"
|
|
||||||
|
|
||||||
// Context is an alias of the Go stdlib's context.Context interface.
|
|
||||||
// It can be used within the SDK's API operation "WithContext" methods.
|
|
||||||
//
|
|
||||||
// See https://golang.org/pkg/context on how to use contexts.
|
|
||||||
type Context = context.Context
|
|
||||||
23
vendor/github.com/aws/aws-sdk-go/aws/context_background_1_5.go
generated
vendored
23
vendor/github.com/aws/aws-sdk-go/aws/context_background_1_5.go
generated
vendored
@ -1,23 +0,0 @@
|
|||||||
//go:build !go1.7
|
|
||||||
// +build !go1.7
|
|
||||||
|
|
||||||
package aws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/aws/aws-sdk-go/internal/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BackgroundContext returns a context that will never be canceled, has no
|
|
||||||
// values, and no deadline. This context is used by the SDK to provide
|
|
||||||
// backwards compatibility with non-context API operations and functionality.
|
|
||||||
//
|
|
||||||
// Go 1.6 and before:
|
|
||||||
// This context function is equivalent to context.Background in the Go stdlib.
|
|
||||||
//
|
|
||||||
// Go 1.7 and later:
|
|
||||||
// The context returned will be the value returned by context.Background()
|
|
||||||
//
|
|
||||||
// See https://golang.org/pkg/context for more information on Contexts.
|
|
||||||
func BackgroundContext() Context {
|
|
||||||
return context.BackgroundCtx
|
|
||||||
}
|
|
||||||
21
vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go
generated
vendored
21
vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
//go:build go1.7
|
|
||||||
// +build go1.7
|
|
||||||
|
|
||||||
package aws
|
|
||||||
|
|
||||||
import "context"
|
|
||||||
|
|
||||||
// BackgroundContext returns a context that will never be canceled, has no
|
|
||||||
// values, and no deadline. This context is used by the SDK to provide
|
|
||||||
// backwards compatibility with non-context API operations and functionality.
|
|
||||||
//
|
|
||||||
// Go 1.6 and before:
|
|
||||||
// This context function is equivalent to context.Background in the Go stdlib.
|
|
||||||
//
|
|
||||||
// Go 1.7 and later:
|
|
||||||
// The context returned will be the value returned by context.Background()
|
|
||||||
//
|
|
||||||
// See https://golang.org/pkg/context for more information on Contexts.
|
|
||||||
func BackgroundContext() Context {
|
|
||||||
return context.Background()
|
|
||||||
}
|
|
||||||
24
vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go
generated
vendored
24
vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go
generated
vendored
@ -1,24 +0,0 @@
|
|||||||
package aws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SleepWithContext will wait for the timer duration to expire, or the context
|
|
||||||
// is canceled. Which ever happens first. If the context is canceled the Context's
|
|
||||||
// error will be returned.
|
|
||||||
//
|
|
||||||
// Expects Context to always return a non-nil error if the Done channel is closed.
|
|
||||||
func SleepWithContext(ctx Context, dur time.Duration) error {
|
|
||||||
t := time.NewTimer(dur)
|
|
||||||
defer t.Stop()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-t.C:
|
|
||||||
break
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
918
vendor/github.com/aws/aws-sdk-go/aws/convert_types.go
generated
vendored
918
vendor/github.com/aws/aws-sdk-go/aws/convert_types.go
generated
vendored
@ -1,918 +0,0 @@
|
|||||||
package aws
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
// String returns a pointer to the string value passed in.
|
|
||||||
func String(v string) *string {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringValue returns the value of the string pointer passed in or
|
|
||||||
// "" if the pointer is nil.
|
|
||||||
func StringValue(v *string) string {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringSlice converts a slice of string values into a slice of
|
|
||||||
// string pointers
|
|
||||||
func StringSlice(src []string) []*string {
|
|
||||||
dst := make([]*string, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringValueSlice converts a slice of string pointers into a slice of
|
|
||||||
// string values
|
|
||||||
func StringValueSlice(src []*string) []string {
|
|
||||||
dst := make([]string, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringMap converts a string map of string values into a string
|
|
||||||
// map of string pointers
|
|
||||||
func StringMap(src map[string]string) map[string]*string {
|
|
||||||
dst := make(map[string]*string)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringValueMap converts a string map of string pointers into a string
|
|
||||||
// map of string values
|
|
||||||
func StringValueMap(src map[string]*string) map[string]string {
|
|
||||||
dst := make(map[string]string)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bool returns a pointer to the bool value passed in.
|
|
||||||
func Bool(v bool) *bool {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolValue returns the value of the bool pointer passed in or
|
|
||||||
// false if the pointer is nil.
|
|
||||||
func BoolValue(v *bool) bool {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolSlice converts a slice of bool values into a slice of
|
|
||||||
// bool pointers
|
|
||||||
func BoolSlice(src []bool) []*bool {
|
|
||||||
dst := make([]*bool, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolValueSlice converts a slice of bool pointers into a slice of
|
|
||||||
// bool values
|
|
||||||
func BoolValueSlice(src []*bool) []bool {
|
|
||||||
dst := make([]bool, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolMap converts a string map of bool values into a string
|
|
||||||
// map of bool pointers
|
|
||||||
func BoolMap(src map[string]bool) map[string]*bool {
|
|
||||||
dst := make(map[string]*bool)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolValueMap converts a string map of bool pointers into a string
|
|
||||||
// map of bool values
|
|
||||||
func BoolValueMap(src map[string]*bool) map[string]bool {
|
|
||||||
dst := make(map[string]bool)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int returns a pointer to the int value passed in.
|
|
||||||
func Int(v int) *int {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntValue returns the value of the int pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func IntValue(v *int) int {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntSlice converts a slice of int values into a slice of
|
|
||||||
// int pointers
|
|
||||||
func IntSlice(src []int) []*int {
|
|
||||||
dst := make([]*int, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntValueSlice converts a slice of int pointers into a slice of
|
|
||||||
// int values
|
|
||||||
func IntValueSlice(src []*int) []int {
|
|
||||||
dst := make([]int, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntMap converts a string map of int values into a string
|
|
||||||
// map of int pointers
|
|
||||||
func IntMap(src map[string]int) map[string]*int {
|
|
||||||
dst := make(map[string]*int)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntValueMap converts a string map of int pointers into a string
|
|
||||||
// map of int values
|
|
||||||
func IntValueMap(src map[string]*int) map[string]int {
|
|
||||||
dst := make(map[string]int)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint returns a pointer to the uint value passed in.
|
|
||||||
func Uint(v uint) *uint {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// UintValue returns the value of the uint pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func UintValue(v *uint) uint {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// UintSlice converts a slice of uint values uinto a slice of
|
|
||||||
// uint pointers
|
|
||||||
func UintSlice(src []uint) []*uint {
|
|
||||||
dst := make([]*uint, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// UintValueSlice converts a slice of uint pointers uinto a slice of
|
|
||||||
// uint values
|
|
||||||
func UintValueSlice(src []*uint) []uint {
|
|
||||||
dst := make([]uint, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// UintMap converts a string map of uint values uinto a string
|
|
||||||
// map of uint pointers
|
|
||||||
func UintMap(src map[string]uint) map[string]*uint {
|
|
||||||
dst := make(map[string]*uint)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// UintValueMap converts a string map of uint pointers uinto a string
|
|
||||||
// map of uint values
|
|
||||||
func UintValueMap(src map[string]*uint) map[string]uint {
|
|
||||||
dst := make(map[string]uint)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int8 returns a pointer to the int8 value passed in.
|
|
||||||
func Int8(v int8) *int8 {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int8Value returns the value of the int8 pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func Int8Value(v *int8) int8 {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int8Slice converts a slice of int8 values into a slice of
|
|
||||||
// int8 pointers
|
|
||||||
func Int8Slice(src []int8) []*int8 {
|
|
||||||
dst := make([]*int8, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int8ValueSlice converts a slice of int8 pointers into a slice of
|
|
||||||
// int8 values
|
|
||||||
func Int8ValueSlice(src []*int8) []int8 {
|
|
||||||
dst := make([]int8, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int8Map converts a string map of int8 values into a string
|
|
||||||
// map of int8 pointers
|
|
||||||
func Int8Map(src map[string]int8) map[string]*int8 {
|
|
||||||
dst := make(map[string]*int8)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int8ValueMap converts a string map of int8 pointers into a string
|
|
||||||
// map of int8 values
|
|
||||||
func Int8ValueMap(src map[string]*int8) map[string]int8 {
|
|
||||||
dst := make(map[string]int8)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int16 returns a pointer to the int16 value passed in.
|
|
||||||
func Int16(v int16) *int16 {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int16Value returns the value of the int16 pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func Int16Value(v *int16) int16 {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int16Slice converts a slice of int16 values into a slice of
|
|
||||||
// int16 pointers
|
|
||||||
func Int16Slice(src []int16) []*int16 {
|
|
||||||
dst := make([]*int16, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int16ValueSlice converts a slice of int16 pointers into a slice of
|
|
||||||
// int16 values
|
|
||||||
func Int16ValueSlice(src []*int16) []int16 {
|
|
||||||
dst := make([]int16, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int16Map converts a string map of int16 values into a string
|
|
||||||
// map of int16 pointers
|
|
||||||
func Int16Map(src map[string]int16) map[string]*int16 {
|
|
||||||
dst := make(map[string]*int16)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int16ValueMap converts a string map of int16 pointers into a string
|
|
||||||
// map of int16 values
|
|
||||||
func Int16ValueMap(src map[string]*int16) map[string]int16 {
|
|
||||||
dst := make(map[string]int16)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int32 returns a pointer to the int32 value passed in.
|
|
||||||
func Int32(v int32) *int32 {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int32Value returns the value of the int32 pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func Int32Value(v *int32) int32 {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int32Slice converts a slice of int32 values into a slice of
|
|
||||||
// int32 pointers
|
|
||||||
func Int32Slice(src []int32) []*int32 {
|
|
||||||
dst := make([]*int32, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int32ValueSlice converts a slice of int32 pointers into a slice of
|
|
||||||
// int32 values
|
|
||||||
func Int32ValueSlice(src []*int32) []int32 {
|
|
||||||
dst := make([]int32, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int32Map converts a string map of int32 values into a string
|
|
||||||
// map of int32 pointers
|
|
||||||
func Int32Map(src map[string]int32) map[string]*int32 {
|
|
||||||
dst := make(map[string]*int32)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int32ValueMap converts a string map of int32 pointers into a string
|
|
||||||
// map of int32 values
|
|
||||||
func Int32ValueMap(src map[string]*int32) map[string]int32 {
|
|
||||||
dst := make(map[string]int32)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64 returns a pointer to the int64 value passed in.
|
|
||||||
func Int64(v int64) *int64 {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64Value returns the value of the int64 pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func Int64Value(v *int64) int64 {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64Slice converts a slice of int64 values into a slice of
|
|
||||||
// int64 pointers
|
|
||||||
func Int64Slice(src []int64) []*int64 {
|
|
||||||
dst := make([]*int64, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64ValueSlice converts a slice of int64 pointers into a slice of
|
|
||||||
// int64 values
|
|
||||||
func Int64ValueSlice(src []*int64) []int64 {
|
|
||||||
dst := make([]int64, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64Map converts a string map of int64 values into a string
|
|
||||||
// map of int64 pointers
|
|
||||||
func Int64Map(src map[string]int64) map[string]*int64 {
|
|
||||||
dst := make(map[string]*int64)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64ValueMap converts a string map of int64 pointers into a string
|
|
||||||
// map of int64 values
|
|
||||||
func Int64ValueMap(src map[string]*int64) map[string]int64 {
|
|
||||||
dst := make(map[string]int64)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint8 returns a pointer to the uint8 value passed in.
|
|
||||||
func Uint8(v uint8) *uint8 {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint8Value returns the value of the uint8 pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func Uint8Value(v *uint8) uint8 {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint8Slice converts a slice of uint8 values into a slice of
|
|
||||||
// uint8 pointers
|
|
||||||
func Uint8Slice(src []uint8) []*uint8 {
|
|
||||||
dst := make([]*uint8, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint8ValueSlice converts a slice of uint8 pointers into a slice of
|
|
||||||
// uint8 values
|
|
||||||
func Uint8ValueSlice(src []*uint8) []uint8 {
|
|
||||||
dst := make([]uint8, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint8Map converts a string map of uint8 values into a string
|
|
||||||
// map of uint8 pointers
|
|
||||||
func Uint8Map(src map[string]uint8) map[string]*uint8 {
|
|
||||||
dst := make(map[string]*uint8)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint8ValueMap converts a string map of uint8 pointers into a string
|
|
||||||
// map of uint8 values
|
|
||||||
func Uint8ValueMap(src map[string]*uint8) map[string]uint8 {
|
|
||||||
dst := make(map[string]uint8)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint16 returns a pointer to the uint16 value passed in.
|
|
||||||
func Uint16(v uint16) *uint16 {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint16Value returns the value of the uint16 pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func Uint16Value(v *uint16) uint16 {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint16Slice converts a slice of uint16 values into a slice of
|
|
||||||
// uint16 pointers
|
|
||||||
func Uint16Slice(src []uint16) []*uint16 {
|
|
||||||
dst := make([]*uint16, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint16ValueSlice converts a slice of uint16 pointers into a slice of
|
|
||||||
// uint16 values
|
|
||||||
func Uint16ValueSlice(src []*uint16) []uint16 {
|
|
||||||
dst := make([]uint16, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint16Map converts a string map of uint16 values into a string
|
|
||||||
// map of uint16 pointers
|
|
||||||
func Uint16Map(src map[string]uint16) map[string]*uint16 {
|
|
||||||
dst := make(map[string]*uint16)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint16ValueMap converts a string map of uint16 pointers into a string
|
|
||||||
// map of uint16 values
|
|
||||||
func Uint16ValueMap(src map[string]*uint16) map[string]uint16 {
|
|
||||||
dst := make(map[string]uint16)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint32 returns a pointer to the uint32 value passed in.
|
|
||||||
func Uint32(v uint32) *uint32 {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint32Value returns the value of the uint32 pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func Uint32Value(v *uint32) uint32 {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint32Slice converts a slice of uint32 values into a slice of
|
|
||||||
// uint32 pointers
|
|
||||||
func Uint32Slice(src []uint32) []*uint32 {
|
|
||||||
dst := make([]*uint32, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint32ValueSlice converts a slice of uint32 pointers into a slice of
|
|
||||||
// uint32 values
|
|
||||||
func Uint32ValueSlice(src []*uint32) []uint32 {
|
|
||||||
dst := make([]uint32, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint32Map converts a string map of uint32 values into a string
|
|
||||||
// map of uint32 pointers
|
|
||||||
func Uint32Map(src map[string]uint32) map[string]*uint32 {
|
|
||||||
dst := make(map[string]*uint32)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint32ValueMap converts a string map of uint32 pointers into a string
|
|
||||||
// map of uint32 values
|
|
||||||
func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
|
|
||||||
dst := make(map[string]uint32)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint64 returns a pointer to the uint64 value passed in.
|
|
||||||
func Uint64(v uint64) *uint64 {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint64Value returns the value of the uint64 pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func Uint64Value(v *uint64) uint64 {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint64Slice converts a slice of uint64 values into a slice of
|
|
||||||
// uint64 pointers
|
|
||||||
func Uint64Slice(src []uint64) []*uint64 {
|
|
||||||
dst := make([]*uint64, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint64ValueSlice converts a slice of uint64 pointers into a slice of
|
|
||||||
// uint64 values
|
|
||||||
func Uint64ValueSlice(src []*uint64) []uint64 {
|
|
||||||
dst := make([]uint64, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint64Map converts a string map of uint64 values into a string
|
|
||||||
// map of uint64 pointers
|
|
||||||
func Uint64Map(src map[string]uint64) map[string]*uint64 {
|
|
||||||
dst := make(map[string]*uint64)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint64ValueMap converts a string map of uint64 pointers into a string
|
|
||||||
// map of uint64 values
|
|
||||||
func Uint64ValueMap(src map[string]*uint64) map[string]uint64 {
|
|
||||||
dst := make(map[string]uint64)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float32 returns a pointer to the float32 value passed in.
|
|
||||||
func Float32(v float32) *float32 {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float32Value returns the value of the float32 pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func Float32Value(v *float32) float32 {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float32Slice converts a slice of float32 values into a slice of
|
|
||||||
// float32 pointers
|
|
||||||
func Float32Slice(src []float32) []*float32 {
|
|
||||||
dst := make([]*float32, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float32ValueSlice converts a slice of float32 pointers into a slice of
|
|
||||||
// float32 values
|
|
||||||
func Float32ValueSlice(src []*float32) []float32 {
|
|
||||||
dst := make([]float32, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float32Map converts a string map of float32 values into a string
|
|
||||||
// map of float32 pointers
|
|
||||||
func Float32Map(src map[string]float32) map[string]*float32 {
|
|
||||||
dst := make(map[string]*float32)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float32ValueMap converts a string map of float32 pointers into a string
|
|
||||||
// map of float32 values
|
|
||||||
func Float32ValueMap(src map[string]*float32) map[string]float32 {
|
|
||||||
dst := make(map[string]float32)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64 returns a pointer to the float64 value passed in.
|
|
||||||
func Float64(v float64) *float64 {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64Value returns the value of the float64 pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func Float64Value(v *float64) float64 {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64Slice converts a slice of float64 values into a slice of
|
|
||||||
// float64 pointers
|
|
||||||
func Float64Slice(src []float64) []*float64 {
|
|
||||||
dst := make([]*float64, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64ValueSlice converts a slice of float64 pointers into a slice of
|
|
||||||
// float64 values
|
|
||||||
func Float64ValueSlice(src []*float64) []float64 {
|
|
||||||
dst := make([]float64, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64Map converts a string map of float64 values into a string
|
|
||||||
// map of float64 pointers
|
|
||||||
func Float64Map(src map[string]float64) map[string]*float64 {
|
|
||||||
dst := make(map[string]*float64)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64ValueMap converts a string map of float64 pointers into a string
|
|
||||||
// map of float64 values
|
|
||||||
func Float64ValueMap(src map[string]*float64) map[string]float64 {
|
|
||||||
dst := make(map[string]float64)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time returns a pointer to the time.Time value passed in.
|
|
||||||
func Time(v time.Time) *time.Time {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeValue returns the value of the time.Time pointer passed in or
|
|
||||||
// time.Time{} if the pointer is nil.
|
|
||||||
func TimeValue(v *time.Time) time.Time {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return time.Time{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SecondsTimeValue converts an int64 pointer to a time.Time value
|
|
||||||
// representing seconds since Epoch or time.Time{} if the pointer is nil.
|
|
||||||
func SecondsTimeValue(v *int64) time.Time {
|
|
||||||
if v != nil {
|
|
||||||
return time.Unix((*v / 1000), 0)
|
|
||||||
}
|
|
||||||
return time.Time{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MillisecondsTimeValue converts an int64 pointer to a time.Time value
|
|
||||||
// representing milliseconds sinch Epoch or time.Time{} if the pointer is nil.
|
|
||||||
func MillisecondsTimeValue(v *int64) time.Time {
|
|
||||||
if v != nil {
|
|
||||||
return time.Unix(0, (*v * 1000000))
|
|
||||||
}
|
|
||||||
return time.Time{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC".
|
|
||||||
// The result is undefined if the Unix time cannot be represented by an int64.
|
|
||||||
// Which includes calling TimeUnixMilli on a zero Time is undefined.
|
|
||||||
//
|
|
||||||
// This utility is useful for service API's such as CloudWatch Logs which require
|
|
||||||
// their unix time values to be in milliseconds.
|
|
||||||
//
|
|
||||||
// See Go stdlib https://golang.org/pkg/time/#Time.UnixNano for more information.
|
|
||||||
func TimeUnixMilli(t time.Time) int64 {
|
|
||||||
return t.UnixNano() / int64(time.Millisecond/time.Nanosecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeSlice converts a slice of time.Time values into a slice of
|
|
||||||
// time.Time pointers
|
|
||||||
func TimeSlice(src []time.Time) []*time.Time {
|
|
||||||
dst := make([]*time.Time, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeValueSlice converts a slice of time.Time pointers into a slice of
|
|
||||||
// time.Time values
|
|
||||||
func TimeValueSlice(src []*time.Time) []time.Time {
|
|
||||||
dst := make([]time.Time, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeMap converts a string map of time.Time values into a string
|
|
||||||
// map of time.Time pointers
|
|
||||||
func TimeMap(src map[string]time.Time) map[string]*time.Time {
|
|
||||||
dst := make(map[string]*time.Time)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeValueMap converts a string map of time.Time pointers into a string
|
|
||||||
// map of time.Time values
|
|
||||||
func TimeValueMap(src map[string]*time.Time) map[string]time.Time {
|
|
||||||
dst := make(map[string]time.Time)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
4
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/awsinternal.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/awsinternal.go
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
// DO NOT EDIT
|
|
||||||
package corehandlers
|
|
||||||
|
|
||||||
const isAwsInternal = ""
|
|
||||||
232
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
generated
vendored
232
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
generated
vendored
@ -1,232 +0,0 @@
|
|||||||
package corehandlers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Interface for matching types which also have a Len method.
|
|
||||||
type lener interface {
|
|
||||||
Len() int
|
|
||||||
}
|
|
||||||
|
|
||||||
// BuildContentLengthHandler builds the content length of a request based on the body,
|
|
||||||
// or will use the HTTPRequest.Header's "Content-Length" if defined. If unable
|
|
||||||
// to determine request body length and no "Content-Length" was specified it will panic.
|
|
||||||
//
|
|
||||||
// The Content-Length will only be added to the request if the length of the body
|
|
||||||
// is greater than 0. If the body is empty or the current `Content-Length`
|
|
||||||
// header is <= 0, the header will also be stripped.
|
|
||||||
var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLengthHandler", Fn: func(r *request.Request) {
|
|
||||||
var length int64
|
|
||||||
|
|
||||||
if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" {
|
|
||||||
length, _ = strconv.ParseInt(slength, 10, 64)
|
|
||||||
} else {
|
|
||||||
if r.Body != nil {
|
|
||||||
var err error
|
|
||||||
length, err = aws.SeekerLen(r.Body)
|
|
||||||
if err != nil {
|
|
||||||
r.Error = awserr.New(request.ErrCodeSerialization, "failed to get request body's length", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if length > 0 {
|
|
||||||
r.HTTPRequest.ContentLength = length
|
|
||||||
r.HTTPRequest.Header.Set("Content-Length", fmt.Sprintf("%d", length))
|
|
||||||
} else {
|
|
||||||
r.HTTPRequest.ContentLength = 0
|
|
||||||
r.HTTPRequest.Header.Del("Content-Length")
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
||||||
var reStatusCode = regexp.MustCompile(`^(\d{3})`)
|
|
||||||
|
|
||||||
// ValidateReqSigHandler is a request handler to ensure that the request's
|
|
||||||
// signature doesn't expire before it is sent. This can happen when a request
|
|
||||||
// is built and signed significantly before it is sent. Or significant delays
|
|
||||||
// occur when retrying requests that would cause the signature to expire.
|
|
||||||
var ValidateReqSigHandler = request.NamedHandler{
|
|
||||||
Name: "core.ValidateReqSigHandler",
|
|
||||||
Fn: func(r *request.Request) {
|
|
||||||
// Unsigned requests are not signed
|
|
||||||
if r.Config.Credentials == credentials.AnonymousCredentials {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
signedTime := r.Time
|
|
||||||
if !r.LastSignedAt.IsZero() {
|
|
||||||
signedTime = r.LastSignedAt
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5 minutes to allow for some clock skew/delays in transmission.
|
|
||||||
// Would be improved with aws/aws-sdk-go#423
|
|
||||||
if signedTime.Add(5 * time.Minute).After(time.Now()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("request expired, resigning")
|
|
||||||
r.Sign()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendHandler is a request handler to send service request using HTTP client.
|
|
||||||
var SendHandler = request.NamedHandler{
|
|
||||||
Name: "core.SendHandler",
|
|
||||||
Fn: func(r *request.Request) {
|
|
||||||
sender := sendFollowRedirects
|
|
||||||
if r.DisableFollowRedirects {
|
|
||||||
sender = sendWithoutFollowRedirects
|
|
||||||
}
|
|
||||||
|
|
||||||
if request.NoBody == r.HTTPRequest.Body {
|
|
||||||
// Strip off the request body if the NoBody reader was used as a
|
|
||||||
// place holder for a request body. This prevents the SDK from
|
|
||||||
// making requests with a request body when it would be invalid
|
|
||||||
// to do so.
|
|
||||||
//
|
|
||||||
// Use a shallow copy of the http.Request to ensure the race condition
|
|
||||||
// of transport on Body will not trigger
|
|
||||||
reqOrig, reqCopy := r.HTTPRequest, *r.HTTPRequest
|
|
||||||
reqCopy.Body = nil
|
|
||||||
r.HTTPRequest = &reqCopy
|
|
||||||
defer func() {
|
|
||||||
r.HTTPRequest = reqOrig
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
r.HTTPResponse, err = sender(r)
|
|
||||||
if err != nil {
|
|
||||||
handleSendError(r, err)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendFollowRedirects(r *request.Request) (*http.Response, error) {
|
|
||||||
return r.Config.HTTPClient.Do(r.HTTPRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendWithoutFollowRedirects(r *request.Request) (*http.Response, error) {
|
|
||||||
transport := r.Config.HTTPClient.Transport
|
|
||||||
if transport == nil {
|
|
||||||
transport = http.DefaultTransport
|
|
||||||
}
|
|
||||||
|
|
||||||
return transport.RoundTrip(r.HTTPRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleSendError(r *request.Request, err error) {
|
|
||||||
// Prevent leaking if an HTTPResponse was returned. Clean up
|
|
||||||
// the body.
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
r.HTTPResponse.Body.Close()
|
|
||||||
}
|
|
||||||
// Capture the case where url.Error is returned for error processing
|
|
||||||
// response. e.g. 301 without location header comes back as string
|
|
||||||
// error and r.HTTPResponse is nil. Other URL redirect errors will
|
|
||||||
// comeback in a similar method.
|
|
||||||
if e, ok := err.(*url.Error); ok && e.Err != nil {
|
|
||||||
if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil {
|
|
||||||
code, _ := strconv.ParseInt(s[1], 10, 64)
|
|
||||||
r.HTTPResponse = &http.Response{
|
|
||||||
StatusCode: int(code),
|
|
||||||
Status: http.StatusText(int(code)),
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if r.HTTPResponse == nil {
|
|
||||||
// Add a dummy request response object to ensure the HTTPResponse
|
|
||||||
// value is consistent.
|
|
||||||
r.HTTPResponse = &http.Response{
|
|
||||||
StatusCode: int(0),
|
|
||||||
Status: http.StatusText(int(0)),
|
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Catch all request errors, and let the default retrier determine
|
|
||||||
// if the error is retryable.
|
|
||||||
r.Error = awserr.New(request.ErrCodeRequestError, "send request failed", err)
|
|
||||||
|
|
||||||
// Override the error with a context canceled error, if that was canceled.
|
|
||||||
ctx := r.Context()
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
r.Error = awserr.New(request.CanceledErrorCode,
|
|
||||||
"request context canceled", ctx.Err())
|
|
||||||
r.Retryable = aws.Bool(false)
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateResponseHandler is a request handler to validate service response.
|
|
||||||
var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseHandler", Fn: func(r *request.Request) {
|
|
||||||
if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 300 {
|
|
||||||
// this may be replaced by an UnmarshalError handler
|
|
||||||
r.Error = awserr.New("UnknownError", "unknown error", r.Error)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
||||||
// AfterRetryHandler performs final checks to determine if the request should
|
|
||||||
// be retried and how long to delay.
|
|
||||||
var AfterRetryHandler = request.NamedHandler{
|
|
||||||
Name: "core.AfterRetryHandler",
|
|
||||||
Fn: func(r *request.Request) {
|
|
||||||
// If one of the other handlers already set the retry state
|
|
||||||
// we don't want to override it based on the service's state
|
|
||||||
if r.Retryable == nil || aws.BoolValue(r.Config.EnforceShouldRetryCheck) {
|
|
||||||
r.Retryable = aws.Bool(r.ShouldRetry(r))
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.WillRetry() {
|
|
||||||
r.RetryDelay = r.RetryRules(r)
|
|
||||||
|
|
||||||
if sleepFn := r.Config.SleepDelay; sleepFn != nil {
|
|
||||||
// Support SleepDelay for backwards compatibility and testing
|
|
||||||
sleepFn(r.RetryDelay)
|
|
||||||
} else if err := aws.SleepWithContext(r.Context(), r.RetryDelay); err != nil {
|
|
||||||
r.Error = awserr.New(request.CanceledErrorCode,
|
|
||||||
"request context canceled", err)
|
|
||||||
r.Retryable = aws.Bool(false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// when the expired token exception occurs the credentials
|
|
||||||
// need to be expired locally so that the next request to
|
|
||||||
// get credentials will trigger a credentials refresh.
|
|
||||||
if r.IsErrorExpired() {
|
|
||||||
r.Config.Credentials.Expire()
|
|
||||||
}
|
|
||||||
|
|
||||||
r.RetryCount++
|
|
||||||
r.Error = nil
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
||||||
// ValidateEndpointHandler is a request handler to validate a request had the
|
|
||||||
// appropriate Region and Endpoint set. Will set r.Error if the endpoint or
|
|
||||||
// region is not valid.
|
|
||||||
var ValidateEndpointHandler = request.NamedHandler{Name: "core.ValidateEndpointHandler", Fn: func(r *request.Request) {
|
|
||||||
if r.ClientInfo.SigningRegion == "" && aws.StringValue(r.Config.Region) == "" {
|
|
||||||
r.Error = aws.ErrMissingRegion
|
|
||||||
} else if r.ClientInfo.Endpoint == "" {
|
|
||||||
// Was any endpoint provided by the user, or one was derived by the
|
|
||||||
// SDK's endpoint resolver?
|
|
||||||
r.Error = aws.ErrMissingEndpoint
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
17
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
generated
vendored
17
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
package corehandlers
|
|
||||||
|
|
||||||
import "github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
|
|
||||||
// ValidateParametersHandler is a request handler to validate the input parameters.
|
|
||||||
// Validating parameters only has meaning if done prior to the request being sent.
|
|
||||||
var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) {
|
|
||||||
if !r.ParamsFilled() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := r.Params.(request.Validator); ok {
|
|
||||||
if err := v.Validate(); err != nil {
|
|
||||||
r.Error = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
47
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go
generated
vendored
47
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go
generated
vendored
@ -1,47 +0,0 @@
|
|||||||
package corehandlers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SDKVersionUserAgentHandler is a request handler for adding the SDK Version
|
|
||||||
// to the user agent.
|
|
||||||
var SDKVersionUserAgentHandler = request.NamedHandler{
|
|
||||||
Name: "core.SDKVersionUserAgentHandler",
|
|
||||||
Fn: request.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion,
|
|
||||||
runtime.Version(), runtime.GOOS, runtime.GOARCH),
|
|
||||||
}
|
|
||||||
|
|
||||||
const execEnvVar = `AWS_EXECUTION_ENV`
|
|
||||||
const execEnvUAKey = `exec-env`
|
|
||||||
|
|
||||||
// AddHostExecEnvUserAgentHander is a request handler appending the SDK's
|
|
||||||
// execution environment to the user agent.
|
|
||||||
//
|
|
||||||
// If the environment variable AWS_EXECUTION_ENV is set, its value will be
|
|
||||||
// appended to the user agent string.
|
|
||||||
var AddHostExecEnvUserAgentHander = request.NamedHandler{
|
|
||||||
Name: "core.AddHostExecEnvUserAgentHander",
|
|
||||||
Fn: func(r *request.Request) {
|
|
||||||
v := os.Getenv(execEnvVar)
|
|
||||||
if len(v) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
request.AddToUserAgent(r, execEnvUAKey+"/"+v)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var AddAwsInternal = request.NamedHandler{
|
|
||||||
Name: "core.AddAwsInternal",
|
|
||||||
Fn: func(r *request.Request) {
|
|
||||||
if len(isAwsInternal) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
request.AddToUserAgent(r, isAwsInternal)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
100
vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go
generated
vendored
100
vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go
generated
vendored
@ -1,100 +0,0 @@
|
|||||||
package credentials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrNoValidProvidersFoundInChain Is returned when there are no valid
|
|
||||||
// providers in the ChainProvider.
|
|
||||||
//
|
|
||||||
// This has been deprecated. For verbose error messaging set
|
|
||||||
// aws.Config.CredentialsChainVerboseErrors to true.
|
|
||||||
ErrNoValidProvidersFoundInChain = awserr.New("NoCredentialProviders",
|
|
||||||
`no valid providers in chain. Deprecated.
|
|
||||||
For verbose messaging see aws.Config.CredentialsChainVerboseErrors`,
|
|
||||||
nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
// A ChainProvider will search for a provider which returns credentials
|
|
||||||
// and cache that provider until Retrieve is called again.
|
|
||||||
//
|
|
||||||
// The ChainProvider provides a way of chaining multiple providers together
|
|
||||||
// which will pick the first available using priority order of the Providers
|
|
||||||
// in the list.
|
|
||||||
//
|
|
||||||
// If none of the Providers retrieve valid credentials Value, ChainProvider's
|
|
||||||
// Retrieve() will return the error ErrNoValidProvidersFoundInChain.
|
|
||||||
//
|
|
||||||
// If a Provider is found which returns valid credentials Value ChainProvider
|
|
||||||
// will cache that Provider for all calls to IsExpired(), until Retrieve is
|
|
||||||
// called again.
|
|
||||||
//
|
|
||||||
// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider.
|
|
||||||
// In this example EnvProvider will first check if any credentials are available
|
|
||||||
// via the environment variables. If there are none ChainProvider will check
|
|
||||||
// the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider
|
|
||||||
// does not return any credentials ChainProvider will return the error
|
|
||||||
// ErrNoValidProvidersFoundInChain
|
|
||||||
//
|
|
||||||
// creds := credentials.NewChainCredentials(
|
|
||||||
// []credentials.Provider{
|
|
||||||
// &credentials.EnvProvider{},
|
|
||||||
// &ec2rolecreds.EC2RoleProvider{
|
|
||||||
// Client: ec2metadata.New(sess),
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// // Usage of ChainCredentials with aws.Config
|
|
||||||
// svc := ec2.New(session.Must(session.NewSession(&aws.Config{
|
|
||||||
// Credentials: creds,
|
|
||||||
// })))
|
|
||||||
//
|
|
||||||
type ChainProvider struct {
|
|
||||||
Providers []Provider
|
|
||||||
curr Provider
|
|
||||||
VerboseErrors bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewChainCredentials returns a pointer to a new Credentials object
|
|
||||||
// wrapping a chain of providers.
|
|
||||||
func NewChainCredentials(providers []Provider) *Credentials {
|
|
||||||
return NewCredentials(&ChainProvider{
|
|
||||||
Providers: append([]Provider{}, providers...),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve returns the credentials value or error if no provider returned
|
|
||||||
// without error.
|
|
||||||
//
|
|
||||||
// If a provider is found it will be cached and any calls to IsExpired()
|
|
||||||
// will return the expired state of the cached provider.
|
|
||||||
func (c *ChainProvider) Retrieve() (Value, error) {
|
|
||||||
var errs []error
|
|
||||||
for _, p := range c.Providers {
|
|
||||||
creds, err := p.Retrieve()
|
|
||||||
if err == nil {
|
|
||||||
c.curr = p
|
|
||||||
return creds, nil
|
|
||||||
}
|
|
||||||
errs = append(errs, err)
|
|
||||||
}
|
|
||||||
c.curr = nil
|
|
||||||
|
|
||||||
var err error
|
|
||||||
err = ErrNoValidProvidersFoundInChain
|
|
||||||
if c.VerboseErrors {
|
|
||||||
err = awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs)
|
|
||||||
}
|
|
||||||
return Value{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired will returned the expired state of the currently cached provider
|
|
||||||
// if there is one. If there is no current provider, true will be returned.
|
|
||||||
func (c *ChainProvider) IsExpired() bool {
|
|
||||||
if c.curr != nil {
|
|
||||||
return c.curr.IsExpired()
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
23
vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.5.go
generated
vendored
23
vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.5.go
generated
vendored
@ -1,23 +0,0 @@
|
|||||||
//go:build !go1.7
|
|
||||||
// +build !go1.7
|
|
||||||
|
|
||||||
package credentials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/aws/aws-sdk-go/internal/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
// backgroundContext returns a context that will never be canceled, has no
|
|
||||||
// values, and no deadline. This context is used by the SDK to provide
|
|
||||||
// backwards compatibility with non-context API operations and functionality.
|
|
||||||
//
|
|
||||||
// Go 1.6 and before:
|
|
||||||
// This context function is equivalent to context.Background in the Go stdlib.
|
|
||||||
//
|
|
||||||
// Go 1.7 and later:
|
|
||||||
// The context returned will be the value returned by context.Background()
|
|
||||||
//
|
|
||||||
// See https://golang.org/pkg/context for more information on Contexts.
|
|
||||||
func backgroundContext() Context {
|
|
||||||
return context.BackgroundCtx
|
|
||||||
}
|
|
||||||
21
vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.7.go
generated
vendored
21
vendor/github.com/aws/aws-sdk-go/aws/credentials/context_background_go1.7.go
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
//go:build go1.7
|
|
||||||
// +build go1.7
|
|
||||||
|
|
||||||
package credentials
|
|
||||||
|
|
||||||
import "context"
|
|
||||||
|
|
||||||
// backgroundContext returns a context that will never be canceled, has no
|
|
||||||
// values, and no deadline. This context is used by the SDK to provide
|
|
||||||
// backwards compatibility with non-context API operations and functionality.
|
|
||||||
//
|
|
||||||
// Go 1.6 and before:
|
|
||||||
// This context function is equivalent to context.Background in the Go stdlib.
|
|
||||||
//
|
|
||||||
// Go 1.7 and later:
|
|
||||||
// The context returned will be the value returned by context.Background()
|
|
||||||
//
|
|
||||||
// See https://golang.org/pkg/context for more information on Contexts.
|
|
||||||
func backgroundContext() Context {
|
|
||||||
return context.Background()
|
|
||||||
}
|
|
||||||
40
vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.5.go
generated
vendored
40
vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.5.go
generated
vendored
@ -1,40 +0,0 @@
|
|||||||
//go:build !go1.9
|
|
||||||
// +build !go1.9
|
|
||||||
|
|
||||||
package credentials
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
// Context is an copy of the Go v1.7 stdlib's context.Context interface.
|
|
||||||
// It is represented as a SDK interface to enable you to use the "WithContext"
|
|
||||||
// API methods with Go v1.6 and a Context type such as golang.org/x/net/context.
|
|
||||||
//
|
|
||||||
// This type, aws.Context, and context.Context are equivalent.
|
|
||||||
//
|
|
||||||
// See https://golang.org/pkg/context on how to use contexts.
|
|
||||||
type Context interface {
|
|
||||||
// Deadline returns the time when work done on behalf of this context
|
|
||||||
// should be canceled. Deadline returns ok==false when no deadline is
|
|
||||||
// set. Successive calls to Deadline return the same results.
|
|
||||||
Deadline() (deadline time.Time, ok bool)
|
|
||||||
|
|
||||||
// Done returns a channel that's closed when work done on behalf of this
|
|
||||||
// context should be canceled. Done may return nil if this context can
|
|
||||||
// never be canceled. Successive calls to Done return the same value.
|
|
||||||
Done() <-chan struct{}
|
|
||||||
|
|
||||||
// Err returns a non-nil error value after Done is closed. Err returns
|
|
||||||
// Canceled if the context was canceled or DeadlineExceeded if the
|
|
||||||
// context's deadline passed. No other values for Err are defined.
|
|
||||||
// After Done is closed, successive calls to Err return the same value.
|
|
||||||
Err() error
|
|
||||||
|
|
||||||
// Value returns the value associated with this context for key, or nil
|
|
||||||
// if no value is associated with key. Successive calls to Value with
|
|
||||||
// the same key returns the same result.
|
|
||||||
//
|
|
||||||
// Use context values only for request-scoped data that transits
|
|
||||||
// processes and API boundaries, not for passing optional parameters to
|
|
||||||
// functions.
|
|
||||||
Value(key interface{}) interface{}
|
|
||||||
}
|
|
||||||
14
vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.9.go
generated
vendored
14
vendor/github.com/aws/aws-sdk-go/aws/credentials/context_go1.9.go
generated
vendored
@ -1,14 +0,0 @@
|
|||||||
//go:build go1.9
|
|
||||||
// +build go1.9
|
|
||||||
|
|
||||||
package credentials
|
|
||||||
|
|
||||||
import "context"
|
|
||||||
|
|
||||||
// Context is an alias of the Go stdlib's context.Context interface.
|
|
||||||
// It can be used within the SDK's API operation "WithContext" methods.
|
|
||||||
//
|
|
||||||
// This type, aws.Context, and context.Context are equivalent.
|
|
||||||
//
|
|
||||||
// See https://golang.org/pkg/context on how to use contexts.
|
|
||||||
type Context = context.Context
|
|
||||||
383
vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go
generated
vendored
383
vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go
generated
vendored
@ -1,383 +0,0 @@
|
|||||||
// Package credentials provides credential retrieval and management
|
|
||||||
//
|
|
||||||
// The Credentials is the primary method of getting access to and managing
|
|
||||||
// credentials Values. Using dependency injection retrieval of the credential
|
|
||||||
// values is handled by a object which satisfies the Provider interface.
|
|
||||||
//
|
|
||||||
// By default the Credentials.Get() will cache the successful result of a
|
|
||||||
// Provider's Retrieve() until Provider.IsExpired() returns true. At which
|
|
||||||
// point Credentials will call Provider's Retrieve() to get new credential Value.
|
|
||||||
//
|
|
||||||
// The Provider is responsible for determining when credentials Value have expired.
|
|
||||||
// It is also important to note that Credentials will always call Retrieve the
|
|
||||||
// first time Credentials.Get() is called.
|
|
||||||
//
|
|
||||||
// Example of using the environment variable credentials.
|
|
||||||
//
|
|
||||||
// creds := credentials.NewEnvCredentials()
|
|
||||||
//
|
|
||||||
// // Retrieve the credentials value
|
|
||||||
// credValue, err := creds.Get()
|
|
||||||
// if err != nil {
|
|
||||||
// // handle error
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Example of forcing credentials to expire and be refreshed on the next Get().
|
|
||||||
// This may be helpful to proactively expire credentials and refresh them sooner
|
|
||||||
// than they would naturally expire on their own.
|
|
||||||
//
|
|
||||||
// creds := credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{})
|
|
||||||
// creds.Expire()
|
|
||||||
// credsValue, err := creds.Get()
|
|
||||||
// // New credentials will be retrieved instead of from cache.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Custom Provider
|
|
||||||
//
|
|
||||||
// Each Provider built into this package also provides a helper method to generate
|
|
||||||
// a Credentials pointer setup with the provider. To use a custom Provider just
|
|
||||||
// create a type which satisfies the Provider interface and pass it to the
|
|
||||||
// NewCredentials method.
|
|
||||||
//
|
|
||||||
// type MyProvider struct{}
|
|
||||||
// func (m *MyProvider) Retrieve() (Value, error) {...}
|
|
||||||
// func (m *MyProvider) IsExpired() bool {...}
|
|
||||||
//
|
|
||||||
// creds := credentials.NewCredentials(&MyProvider{})
|
|
||||||
// credValue, err := creds.Get()
|
|
||||||
//
|
|
||||||
package credentials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sync/singleflight"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AnonymousCredentials is an empty Credential object that can be used as
|
|
||||||
// dummy placeholder credentials for requests that do not need signed.
|
|
||||||
//
|
|
||||||
// This Credentials can be used to configure a service to not sign requests
|
|
||||||
// when making service API calls. For example, when accessing public
|
|
||||||
// s3 buckets.
|
|
||||||
//
|
|
||||||
// svc := s3.New(session.Must(session.NewSession(&aws.Config{
|
|
||||||
// Credentials: credentials.AnonymousCredentials,
|
|
||||||
// })))
|
|
||||||
// // Access public S3 buckets.
|
|
||||||
var AnonymousCredentials = NewStaticCredentials("", "", "")
|
|
||||||
|
|
||||||
// A Value is the AWS credentials value for individual credential fields.
|
|
||||||
type Value struct {
|
|
||||||
// AWS Access key ID
|
|
||||||
AccessKeyID string
|
|
||||||
|
|
||||||
// AWS Secret Access Key
|
|
||||||
SecretAccessKey string
|
|
||||||
|
|
||||||
// AWS Session Token
|
|
||||||
SessionToken string
|
|
||||||
|
|
||||||
// Provider used to get credentials
|
|
||||||
ProviderName string
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasKeys returns if the credentials Value has both AccessKeyID and
|
|
||||||
// SecretAccessKey value set.
|
|
||||||
func (v Value) HasKeys() bool {
|
|
||||||
return len(v.AccessKeyID) != 0 && len(v.SecretAccessKey) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Provider is the interface for any component which will provide credentials
|
|
||||||
// Value. A provider is required to manage its own Expired state, and what to
|
|
||||||
// be expired means.
|
|
||||||
//
|
|
||||||
// The Provider should not need to implement its own mutexes, because
|
|
||||||
// that will be managed by Credentials.
|
|
||||||
type Provider interface {
|
|
||||||
// Retrieve returns nil if it successfully retrieved the value.
|
|
||||||
// Error is returned if the value were not obtainable, or empty.
|
|
||||||
Retrieve() (Value, error)
|
|
||||||
|
|
||||||
// IsExpired returns if the credentials are no longer valid, and need
|
|
||||||
// to be retrieved.
|
|
||||||
IsExpired() bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProviderWithContext is a Provider that can retrieve credentials with a Context
|
|
||||||
type ProviderWithContext interface {
|
|
||||||
Provider
|
|
||||||
|
|
||||||
RetrieveWithContext(Context) (Value, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// An Expirer is an interface that Providers can implement to expose the expiration
|
|
||||||
// time, if known. If the Provider cannot accurately provide this info,
|
|
||||||
// it should not implement this interface.
|
|
||||||
type Expirer interface {
|
|
||||||
// The time at which the credentials are no longer valid
|
|
||||||
ExpiresAt() time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// An ErrorProvider is a stub credentials provider that always returns an error
|
|
||||||
// this is used by the SDK when construction a known provider is not possible
|
|
||||||
// due to an error.
|
|
||||||
type ErrorProvider struct {
|
|
||||||
// The error to be returned from Retrieve
|
|
||||||
Err error
|
|
||||||
|
|
||||||
// The provider name to set on the Retrieved returned Value
|
|
||||||
ProviderName string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve will always return the error that the ErrorProvider was created with.
|
|
||||||
func (p ErrorProvider) Retrieve() (Value, error) {
|
|
||||||
return Value{ProviderName: p.ProviderName}, p.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired will always return not expired.
|
|
||||||
func (p ErrorProvider) IsExpired() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Expiry provides shared expiration logic to be used by credentials
|
|
||||||
// providers to implement expiry functionality.
|
|
||||||
//
|
|
||||||
// The best method to use this struct is as an anonymous field within the
|
|
||||||
// provider's struct.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// type EC2RoleProvider struct {
|
|
||||||
// Expiry
|
|
||||||
// ...
|
|
||||||
// }
|
|
||||||
type Expiry struct {
|
|
||||||
// The date/time when to expire on
|
|
||||||
expiration time.Time
|
|
||||||
|
|
||||||
// If set will be used by IsExpired to determine the current time.
|
|
||||||
// Defaults to time.Now if CurrentTime is not set. Available for testing
|
|
||||||
// to be able to mock out the current time.
|
|
||||||
CurrentTime func() time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetExpiration sets the expiration IsExpired will check when called.
|
|
||||||
//
|
|
||||||
// If window is greater than 0 the expiration time will be reduced by the
|
|
||||||
// window value.
|
|
||||||
//
|
|
||||||
// Using a window is helpful to trigger credentials to expire sooner than
|
|
||||||
// the expiration time given to ensure no requests are made with expired
|
|
||||||
// tokens.
|
|
||||||
func (e *Expiry) SetExpiration(expiration time.Time, window time.Duration) {
|
|
||||||
// Passed in expirations should have the monotonic clock values stripped.
|
|
||||||
// This ensures time comparisons will be based on wall-time.
|
|
||||||
e.expiration = expiration.Round(0)
|
|
||||||
if window > 0 {
|
|
||||||
e.expiration = e.expiration.Add(-window)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns if the credentials are expired.
|
|
||||||
func (e *Expiry) IsExpired() bool {
|
|
||||||
curTime := e.CurrentTime
|
|
||||||
if curTime == nil {
|
|
||||||
curTime = time.Now
|
|
||||||
}
|
|
||||||
return e.expiration.Before(curTime())
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExpiresAt returns the expiration time of the credential
|
|
||||||
func (e *Expiry) ExpiresAt() time.Time {
|
|
||||||
return e.expiration
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Credentials provides concurrency safe retrieval of AWS credentials Value.
|
|
||||||
// Credentials will cache the credentials value until they expire. Once the value
|
|
||||||
// expires the next Get will attempt to retrieve valid credentials.
|
|
||||||
//
|
|
||||||
// Credentials is safe to use across multiple goroutines and will manage the
|
|
||||||
// synchronous state so the Providers do not need to implement their own
|
|
||||||
// synchronization.
|
|
||||||
//
|
|
||||||
// The first Credentials.Get() will always call Provider.Retrieve() to get the
|
|
||||||
// first instance of the credentials Value. All calls to Get() after that
|
|
||||||
// will return the cached credentials Value until IsExpired() returns true.
|
|
||||||
type Credentials struct {
|
|
||||||
sf singleflight.Group
|
|
||||||
|
|
||||||
m sync.RWMutex
|
|
||||||
creds Value
|
|
||||||
provider Provider
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentials returns a pointer to a new Credentials with the provider set.
|
|
||||||
func NewCredentials(provider Provider) *Credentials {
|
|
||||||
c := &Credentials{
|
|
||||||
provider: provider,
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetWithContext returns the credentials value, or error if the credentials
|
|
||||||
// Value failed to be retrieved. Will return early if the passed in context is
|
|
||||||
// canceled.
|
|
||||||
//
|
|
||||||
// Will return the cached credentials Value if it has not expired. If the
|
|
||||||
// credentials Value has expired the Provider's Retrieve() will be called
|
|
||||||
// to refresh the credentials.
|
|
||||||
//
|
|
||||||
// If Credentials.Expire() was called the credentials Value will be force
|
|
||||||
// expired, and the next call to Get() will cause them to be refreshed.
|
|
||||||
//
|
|
||||||
// Passed in Context is equivalent to aws.Context, and context.Context.
|
|
||||||
func (c *Credentials) GetWithContext(ctx Context) (Value, error) {
|
|
||||||
// Check if credentials are cached, and not expired.
|
|
||||||
select {
|
|
||||||
case curCreds, ok := <-c.asyncIsExpired():
|
|
||||||
// ok will only be true, of the credentials were not expired. ok will
|
|
||||||
// be false and have no value if the credentials are expired.
|
|
||||||
if ok {
|
|
||||||
return curCreds, nil
|
|
||||||
}
|
|
||||||
case <-ctx.Done():
|
|
||||||
return Value{}, awserr.New("RequestCanceled",
|
|
||||||
"request context canceled", ctx.Err())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cannot pass context down to the actual retrieve, because the first
|
|
||||||
// context would cancel the whole group when there is not direct
|
|
||||||
// association of items in the group.
|
|
||||||
resCh := c.sf.DoChan("", func() (interface{}, error) {
|
|
||||||
return c.singleRetrieve(&suppressedContext{ctx})
|
|
||||||
})
|
|
||||||
select {
|
|
||||||
case res := <-resCh:
|
|
||||||
return res.Val.(Value), res.Err
|
|
||||||
case <-ctx.Done():
|
|
||||||
return Value{}, awserr.New("RequestCanceled",
|
|
||||||
"request context canceled", ctx.Err())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Credentials) singleRetrieve(ctx Context) (interface{}, error) {
|
|
||||||
c.m.Lock()
|
|
||||||
defer c.m.Unlock()
|
|
||||||
|
|
||||||
if curCreds := c.creds; !c.isExpiredLocked(curCreds) {
|
|
||||||
return curCreds, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var creds Value
|
|
||||||
var err error
|
|
||||||
if p, ok := c.provider.(ProviderWithContext); ok {
|
|
||||||
creds, err = p.RetrieveWithContext(ctx)
|
|
||||||
} else {
|
|
||||||
creds, err = c.provider.Retrieve()
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
c.creds = creds
|
|
||||||
}
|
|
||||||
|
|
||||||
return creds, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the credentials value, or error if the credentials Value failed
|
|
||||||
// to be retrieved.
|
|
||||||
//
|
|
||||||
// Will return the cached credentials Value if it has not expired. If the
|
|
||||||
// credentials Value has expired the Provider's Retrieve() will be called
|
|
||||||
// to refresh the credentials.
|
|
||||||
//
|
|
||||||
// If Credentials.Expire() was called the credentials Value will be force
|
|
||||||
// expired, and the next call to Get() will cause them to be refreshed.
|
|
||||||
func (c *Credentials) Get() (Value, error) {
|
|
||||||
return c.GetWithContext(backgroundContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expire expires the credentials and forces them to be retrieved on the
|
|
||||||
// next call to Get().
|
|
||||||
//
|
|
||||||
// This will override the Provider's expired state, and force Credentials
|
|
||||||
// to call the Provider's Retrieve().
|
|
||||||
func (c *Credentials) Expire() {
|
|
||||||
c.m.Lock()
|
|
||||||
defer c.m.Unlock()
|
|
||||||
|
|
||||||
c.creds = Value{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns if the credentials are no longer valid, and need
|
|
||||||
// to be retrieved.
|
|
||||||
//
|
|
||||||
// If the Credentials were forced to be expired with Expire() this will
|
|
||||||
// reflect that override.
|
|
||||||
func (c *Credentials) IsExpired() bool {
|
|
||||||
c.m.RLock()
|
|
||||||
defer c.m.RUnlock()
|
|
||||||
|
|
||||||
return c.isExpiredLocked(c.creds)
|
|
||||||
}
|
|
||||||
|
|
||||||
// asyncIsExpired returns a channel of credentials Value. If the channel is
|
|
||||||
// closed the credentials are expired and credentials value are not empty.
|
|
||||||
func (c *Credentials) asyncIsExpired() <-chan Value {
|
|
||||||
ch := make(chan Value, 1)
|
|
||||||
go func() {
|
|
||||||
c.m.RLock()
|
|
||||||
defer c.m.RUnlock()
|
|
||||||
|
|
||||||
if curCreds := c.creds; !c.isExpiredLocked(curCreds) {
|
|
||||||
ch <- curCreds
|
|
||||||
}
|
|
||||||
|
|
||||||
close(ch)
|
|
||||||
}()
|
|
||||||
|
|
||||||
return ch
|
|
||||||
}
|
|
||||||
|
|
||||||
// isExpiredLocked helper method wrapping the definition of expired credentials.
|
|
||||||
func (c *Credentials) isExpiredLocked(creds interface{}) bool {
|
|
||||||
return creds == nil || creds.(Value) == Value{} || c.provider.IsExpired()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExpiresAt provides access to the functionality of the Expirer interface of
|
|
||||||
// the underlying Provider, if it supports that interface. Otherwise, it returns
|
|
||||||
// an error.
|
|
||||||
func (c *Credentials) ExpiresAt() (time.Time, error) {
|
|
||||||
c.m.RLock()
|
|
||||||
defer c.m.RUnlock()
|
|
||||||
|
|
||||||
expirer, ok := c.provider.(Expirer)
|
|
||||||
if !ok {
|
|
||||||
return time.Time{}, awserr.New("ProviderNotExpirer",
|
|
||||||
fmt.Sprintf("provider %s does not support ExpiresAt()",
|
|
||||||
c.creds.ProviderName),
|
|
||||||
nil)
|
|
||||||
}
|
|
||||||
if c.creds == (Value{}) {
|
|
||||||
// set expiration time to the distant past
|
|
||||||
return time.Time{}, nil
|
|
||||||
}
|
|
||||||
return expirer.ExpiresAt(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type suppressedContext struct {
|
|
||||||
Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *suppressedContext) Deadline() (deadline time.Time, ok bool) {
|
|
||||||
return time.Time{}, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *suppressedContext) Done() <-chan struct{} {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *suppressedContext) Err() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
188
vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
generated
vendored
188
vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
generated
vendored
@ -1,188 +0,0 @@
|
|||||||
package ec2rolecreds
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sdkuri"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ProviderName provides a name of EC2Role provider
|
|
||||||
const ProviderName = "EC2RoleProvider"
|
|
||||||
|
|
||||||
// A EC2RoleProvider retrieves credentials from the EC2 service, and keeps track if
|
|
||||||
// those credentials are expired.
|
|
||||||
//
|
|
||||||
// Example how to configure the EC2RoleProvider with custom http Client, Endpoint
|
|
||||||
// or ExpiryWindow
|
|
||||||
//
|
|
||||||
// p := &ec2rolecreds.EC2RoleProvider{
|
|
||||||
// // Pass in a custom timeout to be used when requesting
|
|
||||||
// // IAM EC2 Role credentials.
|
|
||||||
// Client: ec2metadata.New(sess, aws.Config{
|
|
||||||
// HTTPClient: &http.Client{Timeout: 10 * time.Second},
|
|
||||||
// }),
|
|
||||||
//
|
|
||||||
// // Do not use early expiry of credentials. If a non zero value is
|
|
||||||
// // specified the credentials will be expired early
|
|
||||||
// ExpiryWindow: 0,
|
|
||||||
// }
|
|
||||||
type EC2RoleProvider struct {
|
|
||||||
credentials.Expiry
|
|
||||||
|
|
||||||
// Required EC2Metadata client to use when connecting to EC2 metadata service.
|
|
||||||
Client *ec2metadata.EC2Metadata
|
|
||||||
|
|
||||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
|
||||||
// the credentials actually expiring. This is beneficial so race conditions
|
|
||||||
// with expiring credentials do not cause request to fail unexpectedly
|
|
||||||
// due to ExpiredTokenException exceptions.
|
|
||||||
//
|
|
||||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
|
||||||
// 10 seconds before the credentials are actually expired.
|
|
||||||
//
|
|
||||||
// If ExpiryWindow is 0 or less it will be ignored.
|
|
||||||
ExpiryWindow time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentials returns a pointer to a new Credentials object wrapping
|
|
||||||
// the EC2RoleProvider. Takes a ConfigProvider to create a EC2Metadata client.
|
|
||||||
// The ConfigProvider is satisfied by the session.Session type.
|
|
||||||
func NewCredentials(c client.ConfigProvider, options ...func(*EC2RoleProvider)) *credentials.Credentials {
|
|
||||||
p := &EC2RoleProvider{
|
|
||||||
Client: ec2metadata.New(c),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.NewCredentials(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping
|
|
||||||
// the EC2RoleProvider. Takes a EC2Metadata client to use when connecting to EC2
|
|
||||||
// metadata service.
|
|
||||||
func NewCredentialsWithClient(client *ec2metadata.EC2Metadata, options ...func(*EC2RoleProvider)) *credentials.Credentials {
|
|
||||||
p := &EC2RoleProvider{
|
|
||||||
Client: client,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.NewCredentials(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve retrieves credentials from the EC2 service.
|
|
||||||
// Error will be returned if the request fails, or unable to extract
|
|
||||||
// the desired credentials.
|
|
||||||
func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) {
|
|
||||||
return m.RetrieveWithContext(aws.BackgroundContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetrieveWithContext retrieves credentials from the EC2 service.
|
|
||||||
// Error will be returned if the request fails, or unable to extract
|
|
||||||
// the desired credentials.
|
|
||||||
func (m *EC2RoleProvider) RetrieveWithContext(ctx credentials.Context) (credentials.Value, error) {
|
|
||||||
credsList, err := requestCredList(ctx, m.Client)
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(credsList) == 0 {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, awserr.New("EmptyEC2RoleList", "empty EC2 Role list", nil)
|
|
||||||
}
|
|
||||||
credsName := credsList[0]
|
|
||||||
|
|
||||||
roleCreds, err := requestCred(ctx, m.Client, credsName)
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
m.SetExpiration(roleCreds.Expiration, m.ExpiryWindow)
|
|
||||||
|
|
||||||
return credentials.Value{
|
|
||||||
AccessKeyID: roleCreds.AccessKeyID,
|
|
||||||
SecretAccessKey: roleCreds.SecretAccessKey,
|
|
||||||
SessionToken: roleCreds.Token,
|
|
||||||
ProviderName: ProviderName,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// A ec2RoleCredRespBody provides the shape for unmarshaling credential
|
|
||||||
// request responses.
|
|
||||||
type ec2RoleCredRespBody struct {
|
|
||||||
// Success State
|
|
||||||
Expiration time.Time
|
|
||||||
AccessKeyID string
|
|
||||||
SecretAccessKey string
|
|
||||||
Token string
|
|
||||||
|
|
||||||
// Error state
|
|
||||||
Code string
|
|
||||||
Message string
|
|
||||||
}
|
|
||||||
|
|
||||||
const iamSecurityCredsPath = "iam/security-credentials/"
|
|
||||||
|
|
||||||
// requestCredList requests a list of credentials from the EC2 service.
|
|
||||||
// If there are no credentials, or there is an error making or receiving the request
|
|
||||||
func requestCredList(ctx aws.Context, client *ec2metadata.EC2Metadata) ([]string, error) {
|
|
||||||
resp, err := client.GetMetadataWithContext(ctx, iamSecurityCredsPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, awserr.New("EC2RoleRequestError", "no EC2 instance role found", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
credsList := []string{}
|
|
||||||
s := bufio.NewScanner(strings.NewReader(resp))
|
|
||||||
for s.Scan() {
|
|
||||||
credsList = append(credsList, s.Text())
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.Err(); err != nil {
|
|
||||||
return nil, awserr.New(request.ErrCodeSerialization,
|
|
||||||
"failed to read EC2 instance role from metadata service", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credsList, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// requestCred requests the credentials for a specific credentials from the EC2 service.
|
|
||||||
//
|
|
||||||
// If the credentials cannot be found, or there is an error reading the response
|
|
||||||
// and error will be returned.
|
|
||||||
func requestCred(ctx aws.Context, client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCredRespBody, error) {
|
|
||||||
resp, err := client.GetMetadataWithContext(ctx, sdkuri.PathJoin(iamSecurityCredsPath, credsName))
|
|
||||||
if err != nil {
|
|
||||||
return ec2RoleCredRespBody{},
|
|
||||||
awserr.New("EC2RoleRequestError",
|
|
||||||
fmt.Sprintf("failed to get %s EC2 instance role credentials", credsName),
|
|
||||||
err)
|
|
||||||
}
|
|
||||||
|
|
||||||
respCreds := ec2RoleCredRespBody{}
|
|
||||||
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil {
|
|
||||||
return ec2RoleCredRespBody{},
|
|
||||||
awserr.New(request.ErrCodeSerialization,
|
|
||||||
fmt.Sprintf("failed to decode %s EC2 instance role credentials", credsName),
|
|
||||||
err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if respCreds.Code != "Success" {
|
|
||||||
// If an error code was returned something failed requesting the role.
|
|
||||||
return ec2RoleCredRespBody{}, awserr.New(respCreds.Code, respCreds.Message, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
return respCreds, nil
|
|
||||||
}
|
|
||||||
255
vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go
generated
vendored
255
vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go
generated
vendored
@ -1,255 +0,0 @@
|
|||||||
// Package endpointcreds provides support for retrieving credentials from an
|
|
||||||
// arbitrary HTTP endpoint.
|
|
||||||
//
|
|
||||||
// The credentials endpoint Provider can receive both static and refreshable
|
|
||||||
// credentials that will expire. Credentials are static when an "Expiration"
|
|
||||||
// value is not provided in the endpoint's response.
|
|
||||||
//
|
|
||||||
// Static credentials will never expire once they have been retrieved. The format
|
|
||||||
// of the static credentials response:
|
|
||||||
// {
|
|
||||||
// "AccessKeyId" : "MUA...",
|
|
||||||
// "SecretAccessKey" : "/7PC5om....",
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Refreshable credentials will expire within the "ExpiryWindow" of the Expiration
|
|
||||||
// value in the response. The format of the refreshable credentials response:
|
|
||||||
// {
|
|
||||||
// "AccessKeyId" : "MUA...",
|
|
||||||
// "SecretAccessKey" : "/7PC5om....",
|
|
||||||
// "Token" : "AQoDY....=",
|
|
||||||
// "Expiration" : "2016-02-25T06:03:31Z"
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Errors should be returned in the following format and only returned with 400
|
|
||||||
// or 500 HTTP status codes.
|
|
||||||
// {
|
|
||||||
// "code": "ErrorCode",
|
|
||||||
// "message": "Helpful error message."
|
|
||||||
// }
|
|
||||||
package endpointcreds
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ProviderName is the name of the credentials provider.
|
|
||||||
const ProviderName = `CredentialsEndpointProvider`
|
|
||||||
|
|
||||||
// Provider satisfies the credentials.Provider interface, and is a client to
|
|
||||||
// retrieve credentials from an arbitrary endpoint.
|
|
||||||
type Provider struct {
|
|
||||||
staticCreds bool
|
|
||||||
credentials.Expiry
|
|
||||||
|
|
||||||
// Requires a AWS Client to make HTTP requests to the endpoint with.
|
|
||||||
// the Endpoint the request will be made to is provided by the aws.Config's
|
|
||||||
// Endpoint value.
|
|
||||||
Client *client.Client
|
|
||||||
|
|
||||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
|
||||||
// the credentials actually expiring. This is beneficial so race conditions
|
|
||||||
// with expiring credentials do not cause request to fail unexpectedly
|
|
||||||
// due to ExpiredTokenException exceptions.
|
|
||||||
//
|
|
||||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
|
||||||
// 10 seconds before the credentials are actually expired.
|
|
||||||
//
|
|
||||||
// If ExpiryWindow is 0 or less it will be ignored.
|
|
||||||
ExpiryWindow time.Duration
|
|
||||||
|
|
||||||
// Optional authorization token value if set will be used as the value of
|
|
||||||
// the Authorization header of the endpoint credential request.
|
|
||||||
//
|
|
||||||
// When constructed from environment, the provider will use the value of
|
|
||||||
// AWS_CONTAINER_AUTHORIZATION_TOKEN environment variable as the token
|
|
||||||
//
|
|
||||||
// Will be overridden if AuthorizationTokenProvider is configured
|
|
||||||
AuthorizationToken string
|
|
||||||
|
|
||||||
// Optional auth provider func to dynamically load the auth token from a file
|
|
||||||
// everytime a credential is retrieved
|
|
||||||
//
|
|
||||||
// When constructed from environment, the provider will read and use the content
|
|
||||||
// of the file pointed to by AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE environment variable
|
|
||||||
// as the auth token everytime credentials are retrieved
|
|
||||||
//
|
|
||||||
// Will override AuthorizationToken if configured
|
|
||||||
AuthorizationTokenProvider AuthTokenProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuthTokenProvider defines an interface to dynamically load a value to be passed
|
|
||||||
// for the Authorization header of a credentials request.
|
|
||||||
type AuthTokenProvider interface {
|
|
||||||
GetToken() (string, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenProviderFunc is a func type implementing AuthTokenProvider interface
|
|
||||||
// and enables customizing token provider behavior
|
|
||||||
type TokenProviderFunc func() (string, error)
|
|
||||||
|
|
||||||
// GetToken func retrieves auth token according to TokenProviderFunc implementation
|
|
||||||
func (p TokenProviderFunc) GetToken() (string, error) {
|
|
||||||
return p()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewProviderClient returns a credentials Provider for retrieving AWS credentials
|
|
||||||
// from arbitrary endpoint.
|
|
||||||
func NewProviderClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) credentials.Provider {
|
|
||||||
p := &Provider{
|
|
||||||
Client: client.New(
|
|
||||||
cfg,
|
|
||||||
metadata.ClientInfo{
|
|
||||||
ServiceName: "CredentialsEndpoint",
|
|
||||||
Endpoint: endpoint,
|
|
||||||
},
|
|
||||||
handlers,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
p.Client.Handlers.Unmarshal.PushBack(unmarshalHandler)
|
|
||||||
p.Client.Handlers.UnmarshalError.PushBack(unmarshalError)
|
|
||||||
p.Client.Handlers.Validate.Clear()
|
|
||||||
p.Client.Handlers.Validate.PushBack(validateEndpointHandler)
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentialsClient returns a pointer to a new Credentials object
|
|
||||||
// wrapping the endpoint credentials Provider.
|
|
||||||
func NewCredentialsClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) *credentials.Credentials {
|
|
||||||
return credentials.NewCredentials(NewProviderClient(cfg, handlers, endpoint, options...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns true if the credentials retrieved are expired, or not yet
|
|
||||||
// retrieved.
|
|
||||||
func (p *Provider) IsExpired() bool {
|
|
||||||
if p.staticCreds {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return p.Expiry.IsExpired()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve will attempt to request the credentials from the endpoint the Provider
|
|
||||||
// was configured for. And error will be returned if the retrieval fails.
|
|
||||||
func (p *Provider) Retrieve() (credentials.Value, error) {
|
|
||||||
return p.RetrieveWithContext(aws.BackgroundContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetrieveWithContext will attempt to request the credentials from the endpoint the Provider
|
|
||||||
// was configured for. And error will be returned if the retrieval fails.
|
|
||||||
func (p *Provider) RetrieveWithContext(ctx credentials.Context) (credentials.Value, error) {
|
|
||||||
resp, err := p.getCredentials(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{ProviderName: ProviderName},
|
|
||||||
awserr.New("CredentialsEndpointError", "failed to load credentials", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.Expiration != nil {
|
|
||||||
p.SetExpiration(*resp.Expiration, p.ExpiryWindow)
|
|
||||||
} else {
|
|
||||||
p.staticCreds = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.Value{
|
|
||||||
AccessKeyID: resp.AccessKeyID,
|
|
||||||
SecretAccessKey: resp.SecretAccessKey,
|
|
||||||
SessionToken: resp.Token,
|
|
||||||
ProviderName: ProviderName,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type getCredentialsOutput struct {
|
|
||||||
Expiration *time.Time
|
|
||||||
AccessKeyID string
|
|
||||||
SecretAccessKey string
|
|
||||||
Token string
|
|
||||||
}
|
|
||||||
|
|
||||||
type errorOutput struct {
|
|
||||||
Code string `json:"code"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) getCredentials(ctx aws.Context) (*getCredentialsOutput, error) {
|
|
||||||
op := &request.Operation{
|
|
||||||
Name: "GetCredentials",
|
|
||||||
HTTPMethod: "GET",
|
|
||||||
}
|
|
||||||
|
|
||||||
out := &getCredentialsOutput{}
|
|
||||||
req := p.Client.NewRequest(op, nil, out)
|
|
||||||
req.SetContext(ctx)
|
|
||||||
req.HTTPRequest.Header.Set("Accept", "application/json")
|
|
||||||
|
|
||||||
authToken := p.AuthorizationToken
|
|
||||||
var err error
|
|
||||||
if p.AuthorizationTokenProvider != nil {
|
|
||||||
authToken, err = p.AuthorizationTokenProvider.GetToken()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("get authorization token: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if strings.ContainsAny(authToken, "\r\n") {
|
|
||||||
return nil, fmt.Errorf("authorization token contains invalid newline sequence")
|
|
||||||
}
|
|
||||||
if len(authToken) != 0 {
|
|
||||||
req.HTTPRequest.Header.Set("Authorization", authToken)
|
|
||||||
}
|
|
||||||
|
|
||||||
return out, req.Send()
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateEndpointHandler(r *request.Request) {
|
|
||||||
if len(r.ClientInfo.Endpoint) == 0 {
|
|
||||||
r.Error = aws.ErrMissingEndpoint
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalHandler(r *request.Request) {
|
|
||||||
defer r.HTTPResponse.Body.Close()
|
|
||||||
|
|
||||||
out := r.Data.(*getCredentialsOutput)
|
|
||||||
if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil {
|
|
||||||
r.Error = awserr.New(request.ErrCodeSerialization,
|
|
||||||
"failed to decode endpoint credentials",
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalError(r *request.Request) {
|
|
||||||
defer r.HTTPResponse.Body.Close()
|
|
||||||
|
|
||||||
var errOut errorOutput
|
|
||||||
err := jsonutil.UnmarshalJSONError(&errOut, r.HTTPResponse.Body)
|
|
||||||
if err != nil {
|
|
||||||
r.Error = awserr.NewRequestFailure(
|
|
||||||
awserr.New(request.ErrCodeSerialization,
|
|
||||||
"failed to decode error message", err),
|
|
||||||
r.HTTPResponse.StatusCode,
|
|
||||||
r.RequestID,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response body format is not consistent between metadata endpoints.
|
|
||||||
// Grab the error message as a string and include that as the source error
|
|
||||||
r.Error = awserr.New(errOut.Code, errOut.Message, nil)
|
|
||||||
}
|
|
||||||
74
vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go
generated
vendored
74
vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go
generated
vendored
@ -1,74 +0,0 @@
|
|||||||
package credentials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// EnvProviderName provides a name of Env provider
|
|
||||||
const EnvProviderName = "EnvProvider"
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be
|
|
||||||
// found in the process's environment.
|
|
||||||
ErrAccessKeyIDNotFound = awserr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil)
|
|
||||||
|
|
||||||
// ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key
|
|
||||||
// can't be found in the process's environment.
|
|
||||||
ErrSecretAccessKeyNotFound = awserr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
// A EnvProvider retrieves credentials from the environment variables of the
|
|
||||||
// running process. Environment credentials never expire.
|
|
||||||
//
|
|
||||||
// Environment variables used:
|
|
||||||
//
|
|
||||||
// * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY
|
|
||||||
//
|
|
||||||
// * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY
|
|
||||||
type EnvProvider struct {
|
|
||||||
retrieved bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEnvCredentials returns a pointer to a new Credentials object
|
|
||||||
// wrapping the environment variable provider.
|
|
||||||
func NewEnvCredentials() *Credentials {
|
|
||||||
return NewCredentials(&EnvProvider{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve retrieves the keys from the environment.
|
|
||||||
func (e *EnvProvider) Retrieve() (Value, error) {
|
|
||||||
e.retrieved = false
|
|
||||||
|
|
||||||
id := os.Getenv("AWS_ACCESS_KEY_ID")
|
|
||||||
if id == "" {
|
|
||||||
id = os.Getenv("AWS_ACCESS_KEY")
|
|
||||||
}
|
|
||||||
|
|
||||||
secret := os.Getenv("AWS_SECRET_ACCESS_KEY")
|
|
||||||
if secret == "" {
|
|
||||||
secret = os.Getenv("AWS_SECRET_KEY")
|
|
||||||
}
|
|
||||||
|
|
||||||
if id == "" {
|
|
||||||
return Value{ProviderName: EnvProviderName}, ErrAccessKeyIDNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
if secret == "" {
|
|
||||||
return Value{ProviderName: EnvProviderName}, ErrSecretAccessKeyNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
e.retrieved = true
|
|
||||||
return Value{
|
|
||||||
AccessKeyID: id,
|
|
||||||
SecretAccessKey: secret,
|
|
||||||
SessionToken: os.Getenv("AWS_SESSION_TOKEN"),
|
|
||||||
ProviderName: EnvProviderName,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns if the credentials have been retrieved.
|
|
||||||
func (e *EnvProvider) IsExpired() bool {
|
|
||||||
return !e.retrieved
|
|
||||||
}
|
|
||||||
12
vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini
generated
vendored
12
vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
[default]
|
|
||||||
aws_access_key_id = accessKey
|
|
||||||
aws_secret_access_key = secret
|
|
||||||
aws_session_token = token
|
|
||||||
|
|
||||||
[no_token]
|
|
||||||
aws_access_key_id = accessKey
|
|
||||||
aws_secret_access_key = secret
|
|
||||||
|
|
||||||
[with_colon]
|
|
||||||
aws_access_key_id: accessKey
|
|
||||||
aws_secret_access_key: secret
|
|
||||||
438
vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go
generated
vendored
438
vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go
generated
vendored
@ -1,438 +0,0 @@
|
|||||||
/*
|
|
||||||
Package processcreds is a credential Provider to retrieve `credential_process`
|
|
||||||
credentials.
|
|
||||||
|
|
||||||
WARNING: The following describes a method of sourcing credentials from an external
|
|
||||||
process. This can potentially be dangerous, so proceed with caution. Other
|
|
||||||
credential providers should be preferred if at all possible. If using this
|
|
||||||
option, you should make sure that the config file is as locked down as possible
|
|
||||||
using security best practices for your operating system.
|
|
||||||
|
|
||||||
You can use credentials from a `credential_process` in a variety of ways.
|
|
||||||
|
|
||||||
One way is to setup your shared config file, located in the default
|
|
||||||
location, with the `credential_process` key and the command you want to be
|
|
||||||
called. You also need to set the AWS_SDK_LOAD_CONFIG environment variable
|
|
||||||
(e.g., `export AWS_SDK_LOAD_CONFIG=1`) to use the shared config file.
|
|
||||||
|
|
||||||
[default]
|
|
||||||
credential_process = /command/to/call
|
|
||||||
|
|
||||||
Creating a new session will use the credential process to retrieve credentials.
|
|
||||||
NOTE: If there are credentials in the profile you are using, the credential
|
|
||||||
process will not be used.
|
|
||||||
|
|
||||||
// Initialize a session to load credentials.
|
|
||||||
sess, _ := session.NewSession(&aws.Config{
|
|
||||||
Region: aws.String("us-east-1")},
|
|
||||||
)
|
|
||||||
|
|
||||||
// Create S3 service client to use the credentials.
|
|
||||||
svc := s3.New(sess)
|
|
||||||
|
|
||||||
Another way to use the `credential_process` method is by using
|
|
||||||
`credentials.NewCredentials()` and providing a command to be executed to
|
|
||||||
retrieve credentials:
|
|
||||||
|
|
||||||
// Create credentials using the ProcessProvider.
|
|
||||||
creds := processcreds.NewCredentials("/path/to/command")
|
|
||||||
|
|
||||||
// Create service client value configured for credentials.
|
|
||||||
svc := s3.New(sess, &aws.Config{Credentials: creds})
|
|
||||||
|
|
||||||
You can set a non-default timeout for the `credential_process` with another
|
|
||||||
constructor, `credentials.NewCredentialsTimeout()`, providing the timeout. To
|
|
||||||
set a one minute timeout:
|
|
||||||
|
|
||||||
// Create credentials using the ProcessProvider.
|
|
||||||
creds := processcreds.NewCredentialsTimeout(
|
|
||||||
"/path/to/command",
|
|
||||||
time.Duration(500) * time.Millisecond)
|
|
||||||
|
|
||||||
If you need more control, you can set any configurable options in the
|
|
||||||
credentials using one or more option functions. For example, you can set a two
|
|
||||||
minute timeout, a credential duration of 60 minutes, and a maximum stdout
|
|
||||||
buffer size of 2k.
|
|
||||||
|
|
||||||
creds := processcreds.NewCredentials(
|
|
||||||
"/path/to/command",
|
|
||||||
func(opt *ProcessProvider) {
|
|
||||||
opt.Timeout = time.Duration(2) * time.Minute
|
|
||||||
opt.Duration = time.Duration(60) * time.Minute
|
|
||||||
opt.MaxBufSize = 2048
|
|
||||||
})
|
|
||||||
|
|
||||||
You can also use your own `exec.Cmd`:
|
|
||||||
|
|
||||||
// Create an exec.Cmd
|
|
||||||
myCommand := exec.Command("/path/to/command")
|
|
||||||
|
|
||||||
// Create credentials using your exec.Cmd and custom timeout
|
|
||||||
creds := processcreds.NewCredentialsCommand(
|
|
||||||
myCommand,
|
|
||||||
func(opt *processcreds.ProcessProvider) {
|
|
||||||
opt.Timeout = time.Duration(1) * time.Second
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
package processcreds
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sdkio"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ProviderName is the name this credentials provider will label any
|
|
||||||
// returned credentials Value with.
|
|
||||||
ProviderName = `ProcessProvider`
|
|
||||||
|
|
||||||
// ErrCodeProcessProviderParse error parsing process output
|
|
||||||
ErrCodeProcessProviderParse = "ProcessProviderParseError"
|
|
||||||
|
|
||||||
// ErrCodeProcessProviderVersion version error in output
|
|
||||||
ErrCodeProcessProviderVersion = "ProcessProviderVersionError"
|
|
||||||
|
|
||||||
// ErrCodeProcessProviderRequired required attribute missing in output
|
|
||||||
ErrCodeProcessProviderRequired = "ProcessProviderRequiredError"
|
|
||||||
|
|
||||||
// ErrCodeProcessProviderExecution execution of command failed
|
|
||||||
ErrCodeProcessProviderExecution = "ProcessProviderExecutionError"
|
|
||||||
|
|
||||||
// errMsgProcessProviderTimeout process took longer than allowed
|
|
||||||
errMsgProcessProviderTimeout = "credential process timed out"
|
|
||||||
|
|
||||||
// errMsgProcessProviderProcess process error
|
|
||||||
errMsgProcessProviderProcess = "error in credential_process"
|
|
||||||
|
|
||||||
// errMsgProcessProviderParse problem parsing output
|
|
||||||
errMsgProcessProviderParse = "parse failed of credential_process output"
|
|
||||||
|
|
||||||
// errMsgProcessProviderVersion version error in output
|
|
||||||
errMsgProcessProviderVersion = "wrong version in process output (not 1)"
|
|
||||||
|
|
||||||
// errMsgProcessProviderMissKey missing access key id in output
|
|
||||||
errMsgProcessProviderMissKey = "missing AccessKeyId in process output"
|
|
||||||
|
|
||||||
// errMsgProcessProviderMissSecret missing secret acess key in output
|
|
||||||
errMsgProcessProviderMissSecret = "missing SecretAccessKey in process output"
|
|
||||||
|
|
||||||
// errMsgProcessProviderPrepareCmd prepare of command failed
|
|
||||||
errMsgProcessProviderPrepareCmd = "failed to prepare command"
|
|
||||||
|
|
||||||
// errMsgProcessProviderEmptyCmd command must not be empty
|
|
||||||
errMsgProcessProviderEmptyCmd = "command must not be empty"
|
|
||||||
|
|
||||||
// errMsgProcessProviderPipe failed to initialize pipe
|
|
||||||
errMsgProcessProviderPipe = "failed to initialize pipe"
|
|
||||||
|
|
||||||
// DefaultDuration is the default amount of time in minutes that the
|
|
||||||
// credentials will be valid for.
|
|
||||||
DefaultDuration = time.Duration(15) * time.Minute
|
|
||||||
|
|
||||||
// DefaultBufSize limits buffer size from growing to an enormous
|
|
||||||
// amount due to a faulty process.
|
|
||||||
DefaultBufSize = int(8 * sdkio.KibiByte)
|
|
||||||
|
|
||||||
// DefaultTimeout default limit on time a process can run.
|
|
||||||
DefaultTimeout = time.Duration(1) * time.Minute
|
|
||||||
)
|
|
||||||
|
|
||||||
// ProcessProvider satisfies the credentials.Provider interface, and is a
|
|
||||||
// client to retrieve credentials from a process.
|
|
||||||
type ProcessProvider struct {
|
|
||||||
staticCreds bool
|
|
||||||
credentials.Expiry
|
|
||||||
originalCommand []string
|
|
||||||
|
|
||||||
// Expiry duration of the credentials. Defaults to 15 minutes if not set.
|
|
||||||
Duration time.Duration
|
|
||||||
|
|
||||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
|
||||||
// the credentials actually expiring. This is beneficial so race conditions
|
|
||||||
// with expiring credentials do not cause request to fail unexpectedly
|
|
||||||
// due to ExpiredTokenException exceptions.
|
|
||||||
//
|
|
||||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
|
||||||
// 10 seconds before the credentials are actually expired.
|
|
||||||
//
|
|
||||||
// If ExpiryWindow is 0 or less it will be ignored.
|
|
||||||
ExpiryWindow time.Duration
|
|
||||||
|
|
||||||
// A string representing an os command that should return a JSON with
|
|
||||||
// credential information.
|
|
||||||
command *exec.Cmd
|
|
||||||
|
|
||||||
// MaxBufSize limits memory usage from growing to an enormous
|
|
||||||
// amount due to a faulty process.
|
|
||||||
MaxBufSize int
|
|
||||||
|
|
||||||
// Timeout limits the time a process can run.
|
|
||||||
Timeout time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentials returns a pointer to a new Credentials object wrapping the
|
|
||||||
// ProcessProvider. The credentials will expire every 15 minutes by default.
|
|
||||||
func NewCredentials(command string, options ...func(*ProcessProvider)) *credentials.Credentials {
|
|
||||||
p := &ProcessProvider{
|
|
||||||
command: exec.Command(command),
|
|
||||||
Duration: DefaultDuration,
|
|
||||||
Timeout: DefaultTimeout,
|
|
||||||
MaxBufSize: DefaultBufSize,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.NewCredentials(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentialsTimeout returns a pointer to a new Credentials object with
|
|
||||||
// the specified command and timeout, and default duration and max buffer size.
|
|
||||||
func NewCredentialsTimeout(command string, timeout time.Duration) *credentials.Credentials {
|
|
||||||
p := NewCredentials(command, func(opt *ProcessProvider) {
|
|
||||||
opt.Timeout = timeout
|
|
||||||
})
|
|
||||||
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentialsCommand returns a pointer to a new Credentials object with
|
|
||||||
// the specified command, and default timeout, duration and max buffer size.
|
|
||||||
func NewCredentialsCommand(command *exec.Cmd, options ...func(*ProcessProvider)) *credentials.Credentials {
|
|
||||||
p := &ProcessProvider{
|
|
||||||
command: command,
|
|
||||||
Duration: DefaultDuration,
|
|
||||||
Timeout: DefaultTimeout,
|
|
||||||
MaxBufSize: DefaultBufSize,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.NewCredentials(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A CredentialProcessResponse is the AWS credentials format that must be
|
|
||||||
// returned when executing an external credential_process.
|
|
||||||
type CredentialProcessResponse struct {
|
|
||||||
// As of this writing, the Version key must be set to 1. This might
|
|
||||||
// increment over time as the structure evolves.
|
|
||||||
Version int
|
|
||||||
|
|
||||||
// The access key ID that identifies the temporary security credentials.
|
|
||||||
AccessKeyID string `json:"AccessKeyId"`
|
|
||||||
|
|
||||||
// The secret access key that can be used to sign requests.
|
|
||||||
SecretAccessKey string
|
|
||||||
|
|
||||||
// The token that users must pass to the service API to use the temporary credentials.
|
|
||||||
SessionToken string
|
|
||||||
|
|
||||||
// The date on which the current credentials expire.
|
|
||||||
Expiration *time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve executes the 'credential_process' and returns the credentials.
|
|
||||||
func (p *ProcessProvider) Retrieve() (credentials.Value, error) {
|
|
||||||
out, err := p.executeCredentialProcess()
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serialize and validate response
|
|
||||||
resp := &CredentialProcessResponse{}
|
|
||||||
if err = json.Unmarshal(out, resp); err != nil {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, awserr.New(
|
|
||||||
ErrCodeProcessProviderParse,
|
|
||||||
fmt.Sprintf("%s: %s", errMsgProcessProviderParse, string(out)),
|
|
||||||
err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.Version != 1 {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, awserr.New(
|
|
||||||
ErrCodeProcessProviderVersion,
|
|
||||||
errMsgProcessProviderVersion,
|
|
||||||
nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(resp.AccessKeyID) == 0 {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, awserr.New(
|
|
||||||
ErrCodeProcessProviderRequired,
|
|
||||||
errMsgProcessProviderMissKey,
|
|
||||||
nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(resp.SecretAccessKey) == 0 {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, awserr.New(
|
|
||||||
ErrCodeProcessProviderRequired,
|
|
||||||
errMsgProcessProviderMissSecret,
|
|
||||||
nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle expiration
|
|
||||||
p.staticCreds = resp.Expiration == nil
|
|
||||||
if resp.Expiration != nil {
|
|
||||||
p.SetExpiration(*resp.Expiration, p.ExpiryWindow)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.Value{
|
|
||||||
ProviderName: ProviderName,
|
|
||||||
AccessKeyID: resp.AccessKeyID,
|
|
||||||
SecretAccessKey: resp.SecretAccessKey,
|
|
||||||
SessionToken: resp.SessionToken,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns true if the credentials retrieved are expired, or not yet
|
|
||||||
// retrieved.
|
|
||||||
func (p *ProcessProvider) IsExpired() bool {
|
|
||||||
if p.staticCreds {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return p.Expiry.IsExpired()
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepareCommand prepares the command to be executed.
|
|
||||||
func (p *ProcessProvider) prepareCommand() error {
|
|
||||||
|
|
||||||
var cmdArgs []string
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
cmdArgs = []string{"cmd.exe", "/C"}
|
|
||||||
} else {
|
|
||||||
cmdArgs = []string{"sh", "-c"}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(p.originalCommand) == 0 {
|
|
||||||
p.originalCommand = make([]string, len(p.command.Args))
|
|
||||||
copy(p.originalCommand, p.command.Args)
|
|
||||||
|
|
||||||
// check for empty command because it succeeds
|
|
||||||
if len(strings.TrimSpace(p.originalCommand[0])) < 1 {
|
|
||||||
return awserr.New(
|
|
||||||
ErrCodeProcessProviderExecution,
|
|
||||||
fmt.Sprintf(
|
|
||||||
"%s: %s",
|
|
||||||
errMsgProcessProviderPrepareCmd,
|
|
||||||
errMsgProcessProviderEmptyCmd),
|
|
||||||
nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cmdArgs = append(cmdArgs, p.originalCommand...)
|
|
||||||
p.command = exec.Command(cmdArgs[0], cmdArgs[1:]...)
|
|
||||||
p.command.Env = os.Environ()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// executeCredentialProcess starts the credential process on the OS and
|
|
||||||
// returns the results or an error.
|
|
||||||
func (p *ProcessProvider) executeCredentialProcess() ([]byte, error) {
|
|
||||||
|
|
||||||
if err := p.prepareCommand(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup the pipes
|
|
||||||
outReadPipe, outWritePipe, err := os.Pipe()
|
|
||||||
if err != nil {
|
|
||||||
return nil, awserr.New(
|
|
||||||
ErrCodeProcessProviderExecution,
|
|
||||||
errMsgProcessProviderPipe,
|
|
||||||
err)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.command.Stderr = os.Stderr // display stderr on console for MFA
|
|
||||||
p.command.Stdout = outWritePipe // get creds json on process's stdout
|
|
||||||
p.command.Stdin = os.Stdin // enable stdin for MFA
|
|
||||||
|
|
||||||
output := bytes.NewBuffer(make([]byte, 0, p.MaxBufSize))
|
|
||||||
|
|
||||||
stdoutCh := make(chan error, 1)
|
|
||||||
go readInput(
|
|
||||||
io.LimitReader(outReadPipe, int64(p.MaxBufSize)),
|
|
||||||
output,
|
|
||||||
stdoutCh)
|
|
||||||
|
|
||||||
execCh := make(chan error, 1)
|
|
||||||
go executeCommand(*p.command, execCh)
|
|
||||||
|
|
||||||
finished := false
|
|
||||||
var errors []error
|
|
||||||
for !finished {
|
|
||||||
select {
|
|
||||||
case readError := <-stdoutCh:
|
|
||||||
errors = appendError(errors, readError)
|
|
||||||
finished = true
|
|
||||||
case execError := <-execCh:
|
|
||||||
err := outWritePipe.Close()
|
|
||||||
errors = appendError(errors, err)
|
|
||||||
errors = appendError(errors, execError)
|
|
||||||
if errors != nil {
|
|
||||||
return output.Bytes(), awserr.NewBatchError(
|
|
||||||
ErrCodeProcessProviderExecution,
|
|
||||||
errMsgProcessProviderProcess,
|
|
||||||
errors)
|
|
||||||
}
|
|
||||||
case <-time.After(p.Timeout):
|
|
||||||
finished = true
|
|
||||||
return output.Bytes(), awserr.NewBatchError(
|
|
||||||
ErrCodeProcessProviderExecution,
|
|
||||||
errMsgProcessProviderTimeout,
|
|
||||||
errors) // errors can be nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out := output.Bytes()
|
|
||||||
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
// windows adds slashes to quotes
|
|
||||||
out = []byte(strings.Replace(string(out), `\"`, `"`, -1))
|
|
||||||
}
|
|
||||||
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// appendError conveniently checks for nil before appending slice
|
|
||||||
func appendError(errors []error, err error) []error {
|
|
||||||
if err != nil {
|
|
||||||
return append(errors, err)
|
|
||||||
}
|
|
||||||
return errors
|
|
||||||
}
|
|
||||||
|
|
||||||
func executeCommand(cmd exec.Cmd, exec chan error) {
|
|
||||||
// Start the command
|
|
||||||
err := cmd.Start()
|
|
||||||
if err == nil {
|
|
||||||
err = cmd.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
exec <- err
|
|
||||||
}
|
|
||||||
|
|
||||||
func readInput(r io.Reader, w io.Writer, read chan error) {
|
|
||||||
tee := io.TeeReader(r, w)
|
|
||||||
|
|
||||||
_, err := ioutil.ReadAll(tee)
|
|
||||||
|
|
||||||
if err == io.EOF {
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
read <- err // will only arrive here when write end of pipe is closed
|
|
||||||
}
|
|
||||||
151
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
151
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
@ -1,151 +0,0 @@
|
|||||||
package credentials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/ini"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SharedCredsProviderName provides a name of SharedCreds provider
|
|
||||||
const SharedCredsProviderName = "SharedCredentialsProvider"
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found.
|
|
||||||
ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
// A SharedCredentialsProvider retrieves access key pair (access key ID,
|
|
||||||
// secret access key, and session token if present) credentials from the current
|
|
||||||
// user's home directory, and keeps track if those credentials are expired.
|
|
||||||
//
|
|
||||||
// Profile ini file example: $HOME/.aws/credentials
|
|
||||||
type SharedCredentialsProvider struct {
|
|
||||||
// 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"
|
|
||||||
Filename string
|
|
||||||
|
|
||||||
// AWS Profile to extract credentials from the shared credentials file. If empty
|
|
||||||
// will default to environment variable "AWS_PROFILE" or "default" if
|
|
||||||
// environment variable is also not set.
|
|
||||||
Profile string
|
|
||||||
|
|
||||||
// retrieved states if the credentials have been successfully retrieved.
|
|
||||||
retrieved bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSharedCredentials returns a pointer to a new Credentials object
|
|
||||||
// wrapping the Profile file provider.
|
|
||||||
func NewSharedCredentials(filename, profile string) *Credentials {
|
|
||||||
return NewCredentials(&SharedCredentialsProvider{
|
|
||||||
Filename: filename,
|
|
||||||
Profile: profile,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve reads and extracts the shared credentials from the current
|
|
||||||
// users home directory.
|
|
||||||
func (p *SharedCredentialsProvider) Retrieve() (Value, error) {
|
|
||||||
p.retrieved = false
|
|
||||||
|
|
||||||
filename, err := p.filename()
|
|
||||||
if err != nil {
|
|
||||||
return Value{ProviderName: SharedCredsProviderName}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
creds, err := loadProfile(filename, p.profile())
|
|
||||||
if err != nil {
|
|
||||||
return Value{ProviderName: SharedCredsProviderName}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
p.retrieved = true
|
|
||||||
return creds, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns if the shared credentials have expired.
|
|
||||||
func (p *SharedCredentialsProvider) IsExpired() bool {
|
|
||||||
return !p.retrieved
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadProfiles loads from the file pointed to by shared credentials filename for profile.
|
|
||||||
// The credentials retrieved from the profile will be returned or error. Error will be
|
|
||||||
// returned if it fails to read from the file, or the data is invalid.
|
|
||||||
func loadProfile(filename, profile string) (Value, error) {
|
|
||||||
config, err := ini.OpenFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
iniProfile, ok := config.GetSection(profile)
|
|
||||||
if !ok {
|
|
||||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
id := iniProfile.String("aws_access_key_id")
|
|
||||||
if len(id) == 0 {
|
|
||||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsAccessKey",
|
|
||||||
fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename),
|
|
||||||
nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
secret := iniProfile.String("aws_secret_access_key")
|
|
||||||
if len(secret) == 0 {
|
|
||||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsSecret",
|
|
||||||
fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename),
|
|
||||||
nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default to empty string if not found
|
|
||||||
token := iniProfile.String("aws_session_token")
|
|
||||||
|
|
||||||
return Value{
|
|
||||||
AccessKeyID: id,
|
|
||||||
SecretAccessKey: secret,
|
|
||||||
SessionToken: token,
|
|
||||||
ProviderName: SharedCredsProviderName,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// filename returns the filename to use to read AWS shared credentials.
|
|
||||||
//
|
|
||||||
// Will return an error if the user's home directory path cannot be found.
|
|
||||||
func (p *SharedCredentialsProvider) filename() (string, error) {
|
|
||||||
if len(p.Filename) != 0 {
|
|
||||||
return p.Filename, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(p.Filename) != 0 {
|
|
||||||
return p.Filename, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if home := shareddefaults.UserHomeDir(); len(home) == 0 {
|
|
||||||
// Backwards compatibility of home directly not found error being returned.
|
|
||||||
// This error is too verbose, failure when opening the file would of been
|
|
||||||
// a better error to return.
|
|
||||||
return "", ErrSharedCredentialsHomeNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
p.Filename = shareddefaults.SharedCredentialsFilename()
|
|
||||||
|
|
||||||
return p.Filename, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// profile returns the AWS shared credentials profile. If empty will read
|
|
||||||
// environment variable "AWS_PROFILE". If that is not set profile will
|
|
||||||
// return "default".
|
|
||||||
func (p *SharedCredentialsProvider) profile() string {
|
|
||||||
if p.Profile == "" {
|
|
||||||
p.Profile = os.Getenv("AWS_PROFILE")
|
|
||||||
}
|
|
||||||
if p.Profile == "" {
|
|
||||||
p.Profile = "default"
|
|
||||||
}
|
|
||||||
|
|
||||||
return p.Profile
|
|
||||||
}
|
|
||||||
60
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/doc.go
generated
vendored
60
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/doc.go
generated
vendored
@ -1,60 +0,0 @@
|
|||||||
// Package ssocreds provides a credential provider for retrieving temporary AWS credentials using an SSO access token.
|
|
||||||
//
|
|
||||||
// IMPORTANT: The provider in this package does not initiate or perform the AWS SSO login flow. The SDK provider
|
|
||||||
// expects that you have already performed the SSO login flow using AWS CLI using the "aws sso login" command, or by
|
|
||||||
// some other mechanism. The provider must find a valid non-expired access token for the AWS SSO user portal URL in
|
|
||||||
// ~/.aws/sso/cache. If a cached token is not found, it is expired, or the file is malformed an error will be returned.
|
|
||||||
//
|
|
||||||
// Loading AWS SSO credentials with the AWS shared configuration file
|
|
||||||
//
|
|
||||||
// You can use configure AWS SSO credentials from the AWS shared configuration file by
|
|
||||||
// providing the specifying the required keys in the profile:
|
|
||||||
//
|
|
||||||
// sso_account_id
|
|
||||||
// sso_region
|
|
||||||
// sso_role_name
|
|
||||||
// sso_start_url
|
|
||||||
//
|
|
||||||
// For example, the following defines a profile "devsso" and specifies the AWS SSO parameters that defines the target
|
|
||||||
// account, role, sign-on portal, and the region where the user portal is located. Note: all SSO arguments must be
|
|
||||||
// provided, or an error will be returned.
|
|
||||||
//
|
|
||||||
// [profile devsso]
|
|
||||||
// sso_start_url = https://my-sso-portal.awsapps.com/start
|
|
||||||
// sso_role_name = SSOReadOnlyRole
|
|
||||||
// sso_region = us-east-1
|
|
||||||
// sso_account_id = 123456789012
|
|
||||||
//
|
|
||||||
// Using the config module, you can load the AWS SDK shared configuration, and specify that this profile be used to
|
|
||||||
// retrieve credentials. For example:
|
|
||||||
//
|
|
||||||
// sess, err := session.NewSessionWithOptions(session.Options{
|
|
||||||
// SharedConfigState: session.SharedConfigEnable,
|
|
||||||
// Profile: "devsso",
|
|
||||||
// })
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Programmatically loading AWS SSO credentials directly
|
|
||||||
//
|
|
||||||
// You can programmatically construct the AWS SSO Provider in your application, and provide the necessary information
|
|
||||||
// to load and retrieve temporary credentials using an access token from ~/.aws/sso/cache.
|
|
||||||
//
|
|
||||||
// svc := sso.New(sess, &aws.Config{
|
|
||||||
// Region: aws.String("us-west-2"), // Client Region must correspond to the AWS SSO user portal region
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// provider := ssocreds.NewCredentialsWithClient(svc, "123456789012", "SSOReadOnlyRole", "https://my-sso-portal.awsapps.com/start")
|
|
||||||
//
|
|
||||||
// credentials, err := provider.Get()
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Additional Resources
|
|
||||||
//
|
|
||||||
// Configuring the AWS CLI to use AWS Single Sign-On: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
|
|
||||||
//
|
|
||||||
// AWS Single Sign-On User Guide: https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html
|
|
||||||
package ssocreds
|
|
||||||
10
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/os.go
generated
vendored
10
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/os.go
generated
vendored
@ -1,10 +0,0 @@
|
|||||||
//go:build !windows
|
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package ssocreds
|
|
||||||
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
func getHomeDirectory() string {
|
|
||||||
return os.Getenv("HOME")
|
|
||||||
}
|
|
||||||
7
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/os_windows.go
generated
vendored
7
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/os_windows.go
generated
vendored
@ -1,7 +0,0 @@
|
|||||||
package ssocreds
|
|
||||||
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
func getHomeDirectory() string {
|
|
||||||
return os.Getenv("USERPROFILE")
|
|
||||||
}
|
|
||||||
187
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/provider.go
generated
vendored
187
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/provider.go
generated
vendored
@ -1,187 +0,0 @@
|
|||||||
package ssocreds
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/sha1"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/auth/bearer"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/service/sso"
|
|
||||||
"github.com/aws/aws-sdk-go/service/sso/ssoiface"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrCodeSSOProviderInvalidToken is the code type that is returned if loaded token has expired or is otherwise invalid.
|
|
||||||
// To refresh the SSO session run aws sso login with the corresponding profile.
|
|
||||||
const ErrCodeSSOProviderInvalidToken = "SSOProviderInvalidToken"
|
|
||||||
|
|
||||||
const invalidTokenMessage = "the SSO session has expired or is invalid"
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
nowTime = time.Now
|
|
||||||
defaultCacheLocation = defaultCacheLocationImpl
|
|
||||||
}
|
|
||||||
|
|
||||||
var nowTime func() time.Time
|
|
||||||
|
|
||||||
// ProviderName is the name of the provider used to specify the source of credentials.
|
|
||||||
const ProviderName = "SSOProvider"
|
|
||||||
|
|
||||||
var defaultCacheLocation func() string
|
|
||||||
|
|
||||||
func defaultCacheLocationImpl() string {
|
|
||||||
return filepath.Join(getHomeDirectory(), ".aws", "sso", "cache")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provider is an AWS credential provider that retrieves temporary AWS credentials by exchanging an SSO login token.
|
|
||||||
type Provider struct {
|
|
||||||
credentials.Expiry
|
|
||||||
|
|
||||||
// The Client which is configured for the AWS Region where the AWS SSO user portal is located.
|
|
||||||
Client ssoiface.SSOAPI
|
|
||||||
|
|
||||||
// The AWS account that is assigned to the user.
|
|
||||||
AccountID string
|
|
||||||
|
|
||||||
// The role name that is assigned to the user.
|
|
||||||
RoleName string
|
|
||||||
|
|
||||||
// The URL that points to the organization's AWS Single Sign-On (AWS SSO) user portal.
|
|
||||||
StartURL string
|
|
||||||
|
|
||||||
// The filepath the cached token will be retrieved from. If unset Provider will
|
|
||||||
// use the startURL to determine the filepath at.
|
|
||||||
//
|
|
||||||
// ~/.aws/sso/cache/<sha1-hex-encoded-startURL>.json
|
|
||||||
//
|
|
||||||
// If custom cached token filepath is used, the Provider's startUrl
|
|
||||||
// parameter will be ignored.
|
|
||||||
CachedTokenFilepath string
|
|
||||||
|
|
||||||
// Used by the SSOCredentialProvider if a token configuration
|
|
||||||
// profile is used in the shared config
|
|
||||||
TokenProvider bearer.TokenProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentials returns a new AWS Single Sign-On (AWS SSO) credential provider. The ConfigProvider is expected to be configured
|
|
||||||
// for the AWS Region where the AWS SSO user portal is located.
|
|
||||||
func NewCredentials(configProvider client.ConfigProvider, accountID, roleName, startURL string, optFns ...func(provider *Provider)) *credentials.Credentials {
|
|
||||||
return NewCredentialsWithClient(sso.New(configProvider), accountID, roleName, startURL, optFns...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentialsWithClient returns a new AWS Single Sign-On (AWS SSO) credential provider. The provided client is expected to be configured
|
|
||||||
// for the AWS Region where the AWS SSO user portal is located.
|
|
||||||
func NewCredentialsWithClient(client ssoiface.SSOAPI, accountID, roleName, startURL string, optFns ...func(provider *Provider)) *credentials.Credentials {
|
|
||||||
p := &Provider{
|
|
||||||
Client: client,
|
|
||||||
AccountID: accountID,
|
|
||||||
RoleName: roleName,
|
|
||||||
StartURL: startURL,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, fn := range optFns {
|
|
||||||
fn(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.NewCredentials(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve retrieves temporary AWS credentials from the configured Amazon Single Sign-On (AWS SSO) user portal
|
|
||||||
// by exchanging the accessToken present in ~/.aws/sso/cache.
|
|
||||||
func (p *Provider) Retrieve() (credentials.Value, error) {
|
|
||||||
return p.RetrieveWithContext(aws.BackgroundContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetrieveWithContext retrieves temporary AWS credentials from the configured Amazon Single Sign-On (AWS SSO) user portal
|
|
||||||
// by exchanging the accessToken present in ~/.aws/sso/cache.
|
|
||||||
func (p *Provider) RetrieveWithContext(ctx credentials.Context) (credentials.Value, error) {
|
|
||||||
var accessToken *string
|
|
||||||
if p.TokenProvider != nil {
|
|
||||||
token, err := p.TokenProvider.RetrieveBearerToken(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{}, err
|
|
||||||
}
|
|
||||||
accessToken = &token.Value
|
|
||||||
} else {
|
|
||||||
if p.CachedTokenFilepath == "" {
|
|
||||||
cachedTokenFilePath, err := getCachedFilePath(p.StartURL)
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{}, err
|
|
||||||
}
|
|
||||||
p.CachedTokenFilepath = cachedTokenFilePath
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenFile, err := loadTokenFile(p.CachedTokenFilepath)
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{}, err
|
|
||||||
}
|
|
||||||
accessToken = &tokenFile.AccessToken
|
|
||||||
}
|
|
||||||
|
|
||||||
output, err := p.Client.GetRoleCredentialsWithContext(ctx, &sso.GetRoleCredentialsInput{
|
|
||||||
AccessToken: accessToken,
|
|
||||||
AccountId: &p.AccountID,
|
|
||||||
RoleName: &p.RoleName,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
expireTime := time.Unix(0, aws.Int64Value(output.RoleCredentials.Expiration)*int64(time.Millisecond)).UTC()
|
|
||||||
p.SetExpiration(expireTime, 0)
|
|
||||||
|
|
||||||
return credentials.Value{
|
|
||||||
AccessKeyID: aws.StringValue(output.RoleCredentials.AccessKeyId),
|
|
||||||
SecretAccessKey: aws.StringValue(output.RoleCredentials.SecretAccessKey),
|
|
||||||
SessionToken: aws.StringValue(output.RoleCredentials.SessionToken),
|
|
||||||
ProviderName: ProviderName,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCachedFilePath(startUrl string) (string, error) {
|
|
||||||
hash := sha1.New()
|
|
||||||
_, err := hash.Write([]byte(startUrl))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return filepath.Join(defaultCacheLocation(), strings.ToLower(hex.EncodeToString(hash.Sum(nil)))+".json"), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type token struct {
|
|
||||||
AccessToken string `json:"accessToken"`
|
|
||||||
ExpiresAt rfc3339 `json:"expiresAt"`
|
|
||||||
Region string `json:"region,omitempty"`
|
|
||||||
StartURL string `json:"startUrl,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t token) Expired() bool {
|
|
||||||
return nowTime().Round(0).After(time.Time(t.ExpiresAt))
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadTokenFile(cachedTokenPath string) (t token, err error) {
|
|
||||||
fileBytes, err := ioutil.ReadFile(cachedTokenPath)
|
|
||||||
if err != nil {
|
|
||||||
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := json.Unmarshal(fileBytes, &t); err != nil {
|
|
||||||
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(t.AccessToken) == 0 {
|
|
||||||
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
if t.Expired() {
|
|
||||||
return token{}, awserr.New(ErrCodeSSOProviderInvalidToken, invalidTokenMessage, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
return t, nil
|
|
||||||
}
|
|
||||||
237
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/sso_cached_token.go
generated
vendored
237
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/sso_cached_token.go
generated
vendored
@ -1,237 +0,0 @@
|
|||||||
package ssocreds
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/sha1"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var resolvedOsUserHomeDir = shareddefaults.UserHomeDir
|
|
||||||
|
|
||||||
// StandardCachedTokenFilepath returns the filepath for the cached SSO token file, or
|
|
||||||
// error if unable get derive the path. Key that will be used to compute a SHA1
|
|
||||||
// value that is hex encoded.
|
|
||||||
//
|
|
||||||
// Derives the filepath using the Key as:
|
|
||||||
//
|
|
||||||
// ~/.aws/sso/cache/<sha1-hex-encoded-key>.json
|
|
||||||
func StandardCachedTokenFilepath(key string) (string, error) {
|
|
||||||
homeDir := resolvedOsUserHomeDir()
|
|
||||||
if len(homeDir) == 0 {
|
|
||||||
return "", fmt.Errorf("unable to get USER's home directory for cached token")
|
|
||||||
}
|
|
||||||
hash := sha1.New()
|
|
||||||
if _, err := hash.Write([]byte(key)); err != nil {
|
|
||||||
return "", fmt.Errorf("unable to compute cached token filepath key SHA1 hash, %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cacheFilename := strings.ToLower(hex.EncodeToString(hash.Sum(nil))) + ".json"
|
|
||||||
|
|
||||||
return filepath.Join(homeDir, ".aws", "sso", "cache", cacheFilename), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type tokenKnownFields struct {
|
|
||||||
AccessToken string `json:"accessToken,omitempty"`
|
|
||||||
ExpiresAt *rfc3339 `json:"expiresAt,omitempty"`
|
|
||||||
|
|
||||||
RefreshToken string `json:"refreshToken,omitempty"`
|
|
||||||
ClientID string `json:"clientId,omitempty"`
|
|
||||||
ClientSecret string `json:"clientSecret,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type cachedToken struct {
|
|
||||||
tokenKnownFields
|
|
||||||
UnknownFields map[string]interface{} `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON provides custom marshalling because the standard library Go marshaller ignores unknown/unspecified fields
|
|
||||||
// when marshalling from a struct: https://pkg.go.dev/encoding/json#Marshal
|
|
||||||
// This function adds some extra validation to the known fields and captures unknown fields.
|
|
||||||
func (t cachedToken) MarshalJSON() ([]byte, error) {
|
|
||||||
fields := map[string]interface{}{}
|
|
||||||
|
|
||||||
setTokenFieldString(fields, "accessToken", t.AccessToken)
|
|
||||||
setTokenFieldRFC3339(fields, "expiresAt", t.ExpiresAt)
|
|
||||||
|
|
||||||
setTokenFieldString(fields, "refreshToken", t.RefreshToken)
|
|
||||||
setTokenFieldString(fields, "clientId", t.ClientID)
|
|
||||||
setTokenFieldString(fields, "clientSecret", t.ClientSecret)
|
|
||||||
|
|
||||||
for k, v := range t.UnknownFields {
|
|
||||||
if _, ok := fields[k]; ok {
|
|
||||||
return nil, fmt.Errorf("unknown token field %v, duplicates known field", k)
|
|
||||||
}
|
|
||||||
fields[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
return json.Marshal(fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setTokenFieldString(fields map[string]interface{}, key, value string) {
|
|
||||||
if value == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fields[key] = value
|
|
||||||
}
|
|
||||||
func setTokenFieldRFC3339(fields map[string]interface{}, key string, value *rfc3339) {
|
|
||||||
if value == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fields[key] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON provides custom unmarshalling because the standard library Go unmarshaller ignores unknown/unspecified
|
|
||||||
// fields when unmarshalling from a struct: https://pkg.go.dev/encoding/json#Unmarshal
|
|
||||||
// This function adds some extra validation to the known fields and captures unknown fields.
|
|
||||||
func (t *cachedToken) UnmarshalJSON(b []byte) error {
|
|
||||||
var fields map[string]interface{}
|
|
||||||
if err := json.Unmarshal(b, &fields); err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
t.UnknownFields = map[string]interface{}{}
|
|
||||||
|
|
||||||
for k, v := range fields {
|
|
||||||
var err error
|
|
||||||
switch k {
|
|
||||||
case "accessToken":
|
|
||||||
err = getTokenFieldString(v, &t.AccessToken)
|
|
||||||
case "expiresAt":
|
|
||||||
err = getTokenFieldRFC3339(v, &t.ExpiresAt)
|
|
||||||
case "refreshToken":
|
|
||||||
err = getTokenFieldString(v, &t.RefreshToken)
|
|
||||||
case "clientId":
|
|
||||||
err = getTokenFieldString(v, &t.ClientID)
|
|
||||||
case "clientSecret":
|
|
||||||
err = getTokenFieldString(v, &t.ClientSecret)
|
|
||||||
default:
|
|
||||||
t.UnknownFields[k] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("field %q, %v", k, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTokenFieldString(v interface{}, value *string) error {
|
|
||||||
var ok bool
|
|
||||||
*value, ok = v.(string)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("expect value to be string, got %T", v)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getTokenFieldRFC3339(v interface{}, value **rfc3339) error {
|
|
||||||
var stringValue string
|
|
||||||
if err := getTokenFieldString(v, &stringValue); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
timeValue, err := parseRFC3339(stringValue)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*value = &timeValue
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadCachedToken(filename string) (cachedToken, error) {
|
|
||||||
fileBytes, err := ioutil.ReadFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
return cachedToken{}, fmt.Errorf("failed to read cached SSO token file, %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var t cachedToken
|
|
||||||
if err := json.Unmarshal(fileBytes, &t); err != nil {
|
|
||||||
return cachedToken{}, fmt.Errorf("failed to parse cached SSO token file, %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(t.AccessToken) == 0 || t.ExpiresAt == nil || time.Time(*t.ExpiresAt).IsZero() {
|
|
||||||
return cachedToken{}, fmt.Errorf(
|
|
||||||
"cached SSO token must contain accessToken and expiresAt fields")
|
|
||||||
}
|
|
||||||
|
|
||||||
return t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func storeCachedToken(filename string, t cachedToken, fileMode os.FileMode) (err error) {
|
|
||||||
tmpFilename := filename + ".tmp-" + strconv.FormatInt(nowTime().UnixNano(), 10)
|
|
||||||
if err := writeCacheFile(tmpFilename, fileMode, t); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.Rename(tmpFilename, filename); err != nil {
|
|
||||||
return fmt.Errorf("failed to replace old cached SSO token file, %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeCacheFile(filename string, fileMode os.FileMode, t cachedToken) (err error) {
|
|
||||||
var f *os.File
|
|
||||||
f, err = os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_RDWR, fileMode)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to create cached SSO token file %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
closeErr := f.Close()
|
|
||||||
if err == nil && closeErr != nil {
|
|
||||||
err = fmt.Errorf("failed to close cached SSO token file, %v", closeErr)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
encoder := json.NewEncoder(f)
|
|
||||||
|
|
||||||
if err = encoder.Encode(t); err != nil {
|
|
||||||
return fmt.Errorf("failed to serialize cached SSO token, %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type rfc3339 time.Time
|
|
||||||
|
|
||||||
// UnmarshalJSON decode rfc3339 from JSON format
|
|
||||||
func (r *rfc3339) UnmarshalJSON(bytes []byte) error {
|
|
||||||
var value string
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if err = json.Unmarshal(bytes, &value); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*r, err = parseRFC3339(value)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseRFC3339(v string) (rfc3339, error) {
|
|
||||||
parsed, err := time.Parse(time.RFC3339, v)
|
|
||||||
if err != nil {
|
|
||||||
return rfc3339{}, fmt.Errorf("expected RFC3339 timestamp: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return rfc3339(parsed), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON encode rfc3339 to JSON format time
|
|
||||||
func (r *rfc3339) MarshalJSON() ([]byte, error) {
|
|
||||||
value := time.Time(*r).Format(time.RFC3339)
|
|
||||||
|
|
||||||
// Use JSON unmarshal to unescape the quoted value making use of JSON's
|
|
||||||
// quoting rules.
|
|
||||||
return json.Marshal(value)
|
|
||||||
}
|
|
||||||
148
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/token_provider.go
generated
vendored
148
vendor/github.com/aws/aws-sdk-go/aws/credentials/ssocreds/token_provider.go
generated
vendored
@ -1,148 +0,0 @@
|
|||||||
package ssocreds
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/auth/bearer"
|
|
||||||
"github.com/aws/aws-sdk-go/service/ssooidc"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CreateTokenAPIClient provides the interface for the SSOTokenProvider's API
|
|
||||||
// client for calling CreateToken operation to refresh the SSO token.
|
|
||||||
type CreateTokenAPIClient interface {
|
|
||||||
CreateToken(input *ssooidc.CreateTokenInput) (*ssooidc.CreateTokenOutput, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SSOTokenProviderOptions provides the options for configuring the
|
|
||||||
// SSOTokenProvider.
|
|
||||||
type SSOTokenProviderOptions struct {
|
|
||||||
// Client that can be overridden
|
|
||||||
Client CreateTokenAPIClient
|
|
||||||
|
|
||||||
// The path the file containing the cached SSO token will be read from.
|
|
||||||
// Initialized the NewSSOTokenProvider's cachedTokenFilepath parameter.
|
|
||||||
CachedTokenFilepath string
|
|
||||||
}
|
|
||||||
|
|
||||||
// SSOTokenProvider provides a utility for refreshing SSO AccessTokens for
|
|
||||||
// Bearer Authentication. The SSOTokenProvider can only be used to refresh
|
|
||||||
// already cached SSO Tokens. This utility cannot perform the initial SSO
|
|
||||||
// create token.
|
|
||||||
//
|
|
||||||
// The initial SSO create token should be preformed with the AWS CLI before the
|
|
||||||
// Go application using the SSOTokenProvider will need to retrieve the SSO
|
|
||||||
// token. If the AWS CLI has not created the token cache file, this provider
|
|
||||||
// will return an error when attempting to retrieve the cached token.
|
|
||||||
//
|
|
||||||
// This provider will attempt to refresh the cached SSO token periodically if
|
|
||||||
// needed when RetrieveBearerToken is called.
|
|
||||||
//
|
|
||||||
// A utility such as the AWS CLI must be used to initially create the SSO
|
|
||||||
// session and cached token file.
|
|
||||||
// https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
|
|
||||||
type SSOTokenProvider struct {
|
|
||||||
options SSOTokenProviderOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSSOTokenProvider returns an initialized SSOTokenProvider that will
|
|
||||||
// periodically refresh the SSO token cached stored in the cachedTokenFilepath.
|
|
||||||
// The cachedTokenFilepath file's content will be rewritten by the token
|
|
||||||
// provider when the token is refreshed.
|
|
||||||
//
|
|
||||||
// The client must be configured for the AWS region the SSO token was created for.
|
|
||||||
func NewSSOTokenProvider(client CreateTokenAPIClient, cachedTokenFilepath string, optFns ...func(o *SSOTokenProviderOptions)) *SSOTokenProvider {
|
|
||||||
options := SSOTokenProviderOptions{
|
|
||||||
Client: client,
|
|
||||||
CachedTokenFilepath: cachedTokenFilepath,
|
|
||||||
}
|
|
||||||
for _, fn := range optFns {
|
|
||||||
fn(&options)
|
|
||||||
}
|
|
||||||
|
|
||||||
provider := &SSOTokenProvider{
|
|
||||||
options: options,
|
|
||||||
}
|
|
||||||
|
|
||||||
return provider
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetrieveBearerToken returns the SSO token stored in the cachedTokenFilepath
|
|
||||||
// the SSOTokenProvider was created with. If the token has expired
|
|
||||||
// RetrieveBearerToken will attempt to refresh it. If the token cannot be
|
|
||||||
// refreshed or is not present an error will be returned.
|
|
||||||
//
|
|
||||||
// A utility such as the AWS CLI must be used to initially create the SSO
|
|
||||||
// session and cached token file. https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html
|
|
||||||
func (p *SSOTokenProvider) RetrieveBearerToken(ctx aws.Context) (bearer.Token, error) {
|
|
||||||
cachedToken, err := loadCachedToken(p.options.CachedTokenFilepath)
|
|
||||||
if err != nil {
|
|
||||||
return bearer.Token{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if cachedToken.ExpiresAt != nil && nowTime().After(time.Time(*cachedToken.ExpiresAt)) {
|
|
||||||
cachedToken, err = p.refreshToken(cachedToken)
|
|
||||||
if err != nil {
|
|
||||||
return bearer.Token{}, fmt.Errorf("refresh cached SSO token failed, %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
expiresAt := toTime((*time.Time)(cachedToken.ExpiresAt))
|
|
||||||
return bearer.Token{
|
|
||||||
Value: cachedToken.AccessToken,
|
|
||||||
CanExpire: !expiresAt.IsZero(),
|
|
||||||
Expires: expiresAt,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *SSOTokenProvider) refreshToken(token cachedToken) (cachedToken, error) {
|
|
||||||
if token.ClientSecret == "" || token.ClientID == "" || token.RefreshToken == "" {
|
|
||||||
return cachedToken{}, fmt.Errorf("cached SSO token is expired, or not present, and cannot be refreshed")
|
|
||||||
}
|
|
||||||
|
|
||||||
createResult, err := p.options.Client.CreateToken(&ssooidc.CreateTokenInput{
|
|
||||||
ClientId: &token.ClientID,
|
|
||||||
ClientSecret: &token.ClientSecret,
|
|
||||||
RefreshToken: &token.RefreshToken,
|
|
||||||
GrantType: aws.String("refresh_token"),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return cachedToken{}, fmt.Errorf("unable to refresh SSO token, %v", err)
|
|
||||||
}
|
|
||||||
if createResult.ExpiresIn == nil {
|
|
||||||
return cachedToken{}, fmt.Errorf("missing required field ExpiresIn")
|
|
||||||
}
|
|
||||||
if createResult.AccessToken == nil {
|
|
||||||
return cachedToken{}, fmt.Errorf("missing required field AccessToken")
|
|
||||||
}
|
|
||||||
if createResult.RefreshToken == nil {
|
|
||||||
return cachedToken{}, fmt.Errorf("missing required field RefreshToken")
|
|
||||||
}
|
|
||||||
|
|
||||||
expiresAt := nowTime().Add(time.Duration(*createResult.ExpiresIn) * time.Second)
|
|
||||||
|
|
||||||
token.AccessToken = *createResult.AccessToken
|
|
||||||
token.ExpiresAt = (*rfc3339)(&expiresAt)
|
|
||||||
token.RefreshToken = *createResult.RefreshToken
|
|
||||||
|
|
||||||
fileInfo, err := os.Stat(p.options.CachedTokenFilepath)
|
|
||||||
if err != nil {
|
|
||||||
return cachedToken{}, fmt.Errorf("failed to stat cached SSO token file %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = storeCachedToken(p.options.CachedTokenFilepath, token, fileInfo.Mode()); err != nil {
|
|
||||||
return cachedToken{}, fmt.Errorf("unable to cache refreshed SSO token, %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return token, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func toTime(p *time.Time) (v time.Time) {
|
|
||||||
if p == nil {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
return *p
|
|
||||||
}
|
|
||||||
57
vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go
generated
vendored
57
vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go
generated
vendored
@ -1,57 +0,0 @@
|
|||||||
package credentials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StaticProviderName provides a name of Static provider
|
|
||||||
const StaticProviderName = "StaticProvider"
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrStaticCredentialsEmpty is emitted when static credentials are empty.
|
|
||||||
ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
// A StaticProvider is a set of credentials which are set programmatically,
|
|
||||||
// and will never expire.
|
|
||||||
type StaticProvider struct {
|
|
||||||
Value
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewStaticCredentials returns a pointer to a new Credentials object
|
|
||||||
// wrapping a static credentials value provider. Token is only required
|
|
||||||
// for temporary security credentials retrieved via STS, otherwise an empty
|
|
||||||
// string can be passed for this parameter.
|
|
||||||
func NewStaticCredentials(id, secret, token string) *Credentials {
|
|
||||||
return NewCredentials(&StaticProvider{Value: Value{
|
|
||||||
AccessKeyID: id,
|
|
||||||
SecretAccessKey: secret,
|
|
||||||
SessionToken: token,
|
|
||||||
}})
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewStaticCredentialsFromCreds returns a pointer to a new Credentials object
|
|
||||||
// wrapping the static credentials value provide. Same as NewStaticCredentials
|
|
||||||
// but takes the creds Value instead of individual fields
|
|
||||||
func NewStaticCredentialsFromCreds(creds Value) *Credentials {
|
|
||||||
return NewCredentials(&StaticProvider{Value: creds})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve returns the credentials or error if the credentials are invalid.
|
|
||||||
func (s *StaticProvider) Retrieve() (Value, error) {
|
|
||||||
if s.AccessKeyID == "" || s.SecretAccessKey == "" {
|
|
||||||
return Value{ProviderName: StaticProviderName}, ErrStaticCredentialsEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(s.Value.ProviderName) == 0 {
|
|
||||||
s.Value.ProviderName = StaticProviderName
|
|
||||||
}
|
|
||||||
return s.Value, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns if the credentials are expired.
|
|
||||||
//
|
|
||||||
// For StaticProvider, the credentials never expired.
|
|
||||||
func (s *StaticProvider) IsExpired() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
371
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
generated
vendored
371
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
generated
vendored
@ -1,371 +0,0 @@
|
|||||||
/*
|
|
||||||
Package stscreds are credential Providers to retrieve STS AWS credentials.
|
|
||||||
|
|
||||||
STS provides multiple ways to retrieve credentials which can be used when making
|
|
||||||
future AWS service API operation calls.
|
|
||||||
|
|
||||||
The SDK will ensure that per instance of credentials.Credentials all requests
|
|
||||||
to refresh the credentials will be synchronized. But, the SDK is unable to
|
|
||||||
ensure synchronous usage of the AssumeRoleProvider if the value is shared
|
|
||||||
between multiple Credentials, Sessions or service clients.
|
|
||||||
|
|
||||||
# Assume Role
|
|
||||||
|
|
||||||
To assume an IAM role using STS with the SDK you can create a new Credentials
|
|
||||||
with the SDKs's stscreds package.
|
|
||||||
|
|
||||||
// Initial credentials loaded from SDK's default credential chain. Such as
|
|
||||||
// the environment, shared credentials (~/.aws/credentials), or EC2 Instance
|
|
||||||
// Role. These credentials will be used to to make the STS Assume Role API.
|
|
||||||
sess := session.Must(session.NewSession())
|
|
||||||
|
|
||||||
// Create the credentials from AssumeRoleProvider to assume the role
|
|
||||||
// referenced by the "myRoleARN" ARN.
|
|
||||||
creds := stscreds.NewCredentials(sess, "myRoleArn")
|
|
||||||
|
|
||||||
// Create service client value configured for credentials
|
|
||||||
// from assumed role.
|
|
||||||
svc := s3.New(sess, &aws.Config{Credentials: creds})
|
|
||||||
|
|
||||||
# Assume Role with static MFA Token
|
|
||||||
|
|
||||||
To assume an IAM role with a MFA token you can either specify a MFA token code
|
|
||||||
directly or provide a function to prompt the user each time the credentials
|
|
||||||
need to refresh the role's credentials. Specifying the TokenCode should be used
|
|
||||||
for short lived operations that will not need to be refreshed, and when you do
|
|
||||||
not want to have direct control over the user provides their MFA token.
|
|
||||||
|
|
||||||
With TokenCode the AssumeRoleProvider will be not be able to refresh the role's
|
|
||||||
credentials.
|
|
||||||
|
|
||||||
// Create the credentials from AssumeRoleProvider to assume the role
|
|
||||||
// referenced by the "myRoleARN" ARN using the MFA token code provided.
|
|
||||||
creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) {
|
|
||||||
p.SerialNumber = aws.String("myTokenSerialNumber")
|
|
||||||
p.TokenCode = aws.String("00000000")
|
|
||||||
})
|
|
||||||
|
|
||||||
// Create service client value configured for credentials
|
|
||||||
// from assumed role.
|
|
||||||
svc := s3.New(sess, &aws.Config{Credentials: creds})
|
|
||||||
|
|
||||||
# Assume Role with MFA Token Provider
|
|
||||||
|
|
||||||
To assume an IAM role with MFA for longer running tasks where the credentials
|
|
||||||
may need to be refreshed setting the TokenProvider field of AssumeRoleProvider
|
|
||||||
will allow the credential provider to prompt for new MFA token code when the
|
|
||||||
role's credentials need to be refreshed.
|
|
||||||
|
|
||||||
The StdinTokenProvider function is available to prompt on stdin to retrieve
|
|
||||||
the MFA token code from the user. You can also implement custom prompts by
|
|
||||||
satisfing the TokenProvider function signature.
|
|
||||||
|
|
||||||
Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will
|
|
||||||
have undesirable results as the StdinTokenProvider will not be synchronized. A
|
|
||||||
single Credentials with an AssumeRoleProvider can be shared safely.
|
|
||||||
|
|
||||||
// Create the credentials from AssumeRoleProvider to assume the role
|
|
||||||
// referenced by the "myRoleARN" ARN. Prompting for MFA token from stdin.
|
|
||||||
creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) {
|
|
||||||
p.SerialNumber = aws.String("myTokenSerialNumber")
|
|
||||||
p.TokenProvider = stscreds.StdinTokenProvider
|
|
||||||
})
|
|
||||||
|
|
||||||
// Create service client value configured for credentials
|
|
||||||
// from assumed role.
|
|
||||||
svc := s3.New(sess, &aws.Config{Credentials: creds})
|
|
||||||
*/
|
|
||||||
package stscreds
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sdkrand"
|
|
||||||
"github.com/aws/aws-sdk-go/service/sts"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StdinTokenProvider will prompt on stderr and read from stdin for a string value.
|
|
||||||
// An error is returned if reading from stdin fails.
|
|
||||||
//
|
|
||||||
// Use this function to read MFA tokens from stdin. The function makes no attempt
|
|
||||||
// to make atomic prompts from stdin across multiple gorouties.
|
|
||||||
//
|
|
||||||
// Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will
|
|
||||||
// have undesirable results as the StdinTokenProvider will not be synchronized. A
|
|
||||||
// single Credentials with an AssumeRoleProvider can be shared safely
|
|
||||||
//
|
|
||||||
// Will wait forever until something is provided on the stdin.
|
|
||||||
func StdinTokenProvider() (string, error) {
|
|
||||||
var v string
|
|
||||||
fmt.Fprintf(os.Stderr, "Assume Role MFA token code: ")
|
|
||||||
_, err := fmt.Scanln(&v)
|
|
||||||
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProviderName provides a name of AssumeRole provider
|
|
||||||
const ProviderName = "AssumeRoleProvider"
|
|
||||||
|
|
||||||
// AssumeRoler represents the minimal subset of the STS client API used by this provider.
|
|
||||||
type AssumeRoler interface {
|
|
||||||
AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type assumeRolerWithContext interface {
|
|
||||||
AssumeRoleWithContext(aws.Context, *sts.AssumeRoleInput, ...request.Option) (*sts.AssumeRoleOutput, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultDuration is the default amount of time in minutes that the credentials
|
|
||||||
// will be valid for.
|
|
||||||
var DefaultDuration = time.Duration(15) * time.Minute
|
|
||||||
|
|
||||||
// AssumeRoleProvider retrieves temporary credentials from the STS service, and
|
|
||||||
// keeps track of their expiration time.
|
|
||||||
//
|
|
||||||
// This credential provider will be used by the SDKs default credential change
|
|
||||||
// when shared configuration is enabled, and the shared config or shared credentials
|
|
||||||
// file configure assume role. See Session docs for how to do this.
|
|
||||||
//
|
|
||||||
// AssumeRoleProvider does not provide any synchronization and it is not safe
|
|
||||||
// to share this value across multiple Credentials, Sessions, or service clients
|
|
||||||
// without also sharing the same Credentials instance.
|
|
||||||
type AssumeRoleProvider struct {
|
|
||||||
credentials.Expiry
|
|
||||||
|
|
||||||
// STS client to make assume role request with.
|
|
||||||
Client AssumeRoler
|
|
||||||
|
|
||||||
// Role to be assumed.
|
|
||||||
RoleARN string
|
|
||||||
|
|
||||||
// Session name, if you wish to reuse the credentials elsewhere.
|
|
||||||
RoleSessionName string
|
|
||||||
|
|
||||||
// Optional, you can pass tag key-value pairs to your session. These tags are called session tags.
|
|
||||||
Tags []*sts.Tag
|
|
||||||
|
|
||||||
// A list of keys for session tags that you want to set as transitive.
|
|
||||||
// If you set a tag key as transitive, the corresponding key and value passes to subsequent sessions in a role chain.
|
|
||||||
TransitiveTagKeys []*string
|
|
||||||
|
|
||||||
// Expiry duration of the STS credentials. Defaults to 15 minutes if not set.
|
|
||||||
Duration time.Duration
|
|
||||||
|
|
||||||
// Optional ExternalID to pass along, defaults to nil if not set.
|
|
||||||
ExternalID *string
|
|
||||||
|
|
||||||
// The policy plain text must be 2048 bytes or shorter. However, an internal
|
|
||||||
// conversion compresses it into a packed binary format with a separate limit.
|
|
||||||
// The PackedPolicySize response element indicates by percentage how close to
|
|
||||||
// the upper size limit the policy is, with 100% equaling the maximum allowed
|
|
||||||
// size.
|
|
||||||
Policy *string
|
|
||||||
|
|
||||||
// The ARNs of IAM managed policies you want to use as managed session policies.
|
|
||||||
// The policies must exist in the same account as the role.
|
|
||||||
//
|
|
||||||
// This parameter is optional. You can provide up to 10 managed policy ARNs.
|
|
||||||
// However, the plain text that you use for both inline and managed session
|
|
||||||
// policies can't exceed 2,048 characters.
|
|
||||||
//
|
|
||||||
// An AWS conversion compresses the passed session policies and session tags
|
|
||||||
// into a packed binary format that has a separate limit. Your request can fail
|
|
||||||
// for this limit even if your plain text meets the other requirements. The
|
|
||||||
// PackedPolicySize response element indicates by percentage how close the policies
|
|
||||||
// and tags for your request are to the upper size limit.
|
|
||||||
//
|
|
||||||
// Passing policies to this operation returns new temporary credentials. The
|
|
||||||
// resulting session's permissions are the intersection of the role's identity-based
|
|
||||||
// policy and the session policies. You can use the role's temporary credentials
|
|
||||||
// in subsequent AWS API calls to access resources in the account that owns
|
|
||||||
// the role. You cannot use session policies to grant more permissions than
|
|
||||||
// those allowed by the identity-based policy of the role that is being assumed.
|
|
||||||
// For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
|
|
||||||
// in the IAM User Guide.
|
|
||||||
PolicyArns []*sts.PolicyDescriptorType
|
|
||||||
|
|
||||||
// The identification number of the MFA device that is associated with the user
|
|
||||||
// who is making the AssumeRole call. Specify this value if the trust policy
|
|
||||||
// of the role being assumed includes a condition that requires MFA authentication.
|
|
||||||
// The value is either the serial number for a hardware device (such as GAHT12345678)
|
|
||||||
// or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
|
|
||||||
SerialNumber *string
|
|
||||||
|
|
||||||
// The SourceIdentity which is used to identity a persistent identity through the whole session.
|
|
||||||
// For more details see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html
|
|
||||||
SourceIdentity *string
|
|
||||||
|
|
||||||
// The value provided by the MFA device, if the trust policy of the role being
|
|
||||||
// assumed requires MFA (that is, if the policy includes a condition that tests
|
|
||||||
// for MFA). If the role being assumed requires MFA and if the TokenCode value
|
|
||||||
// is missing or expired, the AssumeRole call returns an "access denied" error.
|
|
||||||
//
|
|
||||||
// If SerialNumber is set and neither TokenCode nor TokenProvider are also
|
|
||||||
// set an error will be returned.
|
|
||||||
TokenCode *string
|
|
||||||
|
|
||||||
// Async method of providing MFA token code for assuming an IAM role with MFA.
|
|
||||||
// The value returned by the function will be used as the TokenCode in the Retrieve
|
|
||||||
// call. See StdinTokenProvider for a provider that prompts and reads from stdin.
|
|
||||||
//
|
|
||||||
// This token provider will be called when ever the assumed role's
|
|
||||||
// credentials need to be refreshed when SerialNumber is also set and
|
|
||||||
// TokenCode is not set.
|
|
||||||
//
|
|
||||||
// If both TokenCode and TokenProvider is set, TokenProvider will be used and
|
|
||||||
// TokenCode is ignored.
|
|
||||||
TokenProvider func() (string, error)
|
|
||||||
|
|
||||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
|
||||||
// the credentials actually expiring. This is beneficial so race conditions
|
|
||||||
// with expiring credentials do not cause request to fail unexpectedly
|
|
||||||
// due to ExpiredTokenException exceptions.
|
|
||||||
//
|
|
||||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
|
||||||
// 10 seconds before the credentials are actually expired.
|
|
||||||
//
|
|
||||||
// If ExpiryWindow is 0 or less it will be ignored.
|
|
||||||
ExpiryWindow time.Duration
|
|
||||||
|
|
||||||
// MaxJitterFrac reduces the effective Duration of each credential requested
|
|
||||||
// by a random percentage between 0 and MaxJitterFraction. MaxJitterFrac must
|
|
||||||
// have a value between 0 and 1. Any other value may lead to expected behavior.
|
|
||||||
// With a MaxJitterFrac value of 0, default) will no jitter will be used.
|
|
||||||
//
|
|
||||||
// For example, with a Duration of 30m and a MaxJitterFrac of 0.1, the
|
|
||||||
// AssumeRole call will be made with an arbitrary Duration between 27m and
|
|
||||||
// 30m.
|
|
||||||
//
|
|
||||||
// MaxJitterFrac should not be negative.
|
|
||||||
MaxJitterFrac float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentials returns a pointer to a new Credentials value wrapping the
|
|
||||||
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
|
|
||||||
// role will be named after a nanosecond timestamp of this operation. The
|
|
||||||
// Credentials value will attempt to refresh the credentials using the provider
|
|
||||||
// when Credentials.Get is called, if the cached credentials are expiring.
|
|
||||||
//
|
|
||||||
// Takes a Config provider to create the STS client. The ConfigProvider is
|
|
||||||
// satisfied by the session.Session type.
|
|
||||||
//
|
|
||||||
// It is safe to share the returned Credentials with multiple Sessions and
|
|
||||||
// service clients. All access to the credentials and refreshing them
|
|
||||||
// will be synchronized.
|
|
||||||
func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
|
|
||||||
p := &AssumeRoleProvider{
|
|
||||||
Client: sts.New(c),
|
|
||||||
RoleARN: roleARN,
|
|
||||||
Duration: DefaultDuration,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.NewCredentials(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentialsWithClient returns a pointer to a new Credentials value wrapping the
|
|
||||||
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
|
|
||||||
// role will be named after a nanosecond timestamp of this operation. The
|
|
||||||
// Credentials value will attempt to refresh the credentials using the provider
|
|
||||||
// when Credentials.Get is called, if the cached credentials are expiring.
|
|
||||||
//
|
|
||||||
// Takes an AssumeRoler which can be satisfied by the STS client.
|
|
||||||
//
|
|
||||||
// It is safe to share the returned Credentials with multiple Sessions and
|
|
||||||
// service clients. All access to the credentials and refreshing them
|
|
||||||
// will be synchronized.
|
|
||||||
func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
|
|
||||||
p := &AssumeRoleProvider{
|
|
||||||
Client: svc,
|
|
||||||
RoleARN: roleARN,
|
|
||||||
Duration: DefaultDuration,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.NewCredentials(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve generates a new set of temporary credentials using STS.
|
|
||||||
func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) {
|
|
||||||
return p.RetrieveWithContext(aws.BackgroundContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetrieveWithContext generates a new set of temporary credentials using STS.
|
|
||||||
func (p *AssumeRoleProvider) RetrieveWithContext(ctx credentials.Context) (credentials.Value, error) {
|
|
||||||
// Apply defaults where parameters are not set.
|
|
||||||
if p.RoleSessionName == "" {
|
|
||||||
// Try to work out a role name that will hopefully end up unique.
|
|
||||||
p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano())
|
|
||||||
}
|
|
||||||
if p.Duration == 0 {
|
|
||||||
// Expire as often as AWS permits.
|
|
||||||
p.Duration = DefaultDuration
|
|
||||||
}
|
|
||||||
jitter := time.Duration(sdkrand.SeededRand.Float64() * p.MaxJitterFrac * float64(p.Duration))
|
|
||||||
input := &sts.AssumeRoleInput{
|
|
||||||
DurationSeconds: aws.Int64(int64((p.Duration - jitter) / time.Second)),
|
|
||||||
RoleArn: aws.String(p.RoleARN),
|
|
||||||
RoleSessionName: aws.String(p.RoleSessionName),
|
|
||||||
ExternalId: p.ExternalID,
|
|
||||||
Tags: p.Tags,
|
|
||||||
PolicyArns: p.PolicyArns,
|
|
||||||
TransitiveTagKeys: p.TransitiveTagKeys,
|
|
||||||
SourceIdentity: p.SourceIdentity,
|
|
||||||
}
|
|
||||||
if p.Policy != nil {
|
|
||||||
input.Policy = p.Policy
|
|
||||||
}
|
|
||||||
if p.SerialNumber != nil {
|
|
||||||
if p.TokenCode != nil {
|
|
||||||
input.SerialNumber = p.SerialNumber
|
|
||||||
input.TokenCode = p.TokenCode
|
|
||||||
} else if p.TokenProvider != nil {
|
|
||||||
input.SerialNumber = p.SerialNumber
|
|
||||||
code, err := p.TokenProvider()
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, err
|
|
||||||
}
|
|
||||||
input.TokenCode = aws.String(code)
|
|
||||||
} else {
|
|
||||||
return credentials.Value{ProviderName: ProviderName},
|
|
||||||
awserr.New("AssumeRoleTokenNotAvailable",
|
|
||||||
"assume role with MFA enabled, but neither TokenCode nor TokenProvider are set", nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var roleOutput *sts.AssumeRoleOutput
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if c, ok := p.Client.(assumeRolerWithContext); ok {
|
|
||||||
roleOutput, err = c.AssumeRoleWithContext(ctx, input)
|
|
||||||
} else {
|
|
||||||
roleOutput, err = p.Client.AssumeRole(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// We will proactively generate new credentials before they expire.
|
|
||||||
p.SetExpiration(*roleOutput.Credentials.Expiration, p.ExpiryWindow)
|
|
||||||
|
|
||||||
return credentials.Value{
|
|
||||||
AccessKeyID: *roleOutput.Credentials.AccessKeyId,
|
|
||||||
SecretAccessKey: *roleOutput.Credentials.SecretAccessKey,
|
|
||||||
SessionToken: *roleOutput.Credentials.SessionToken,
|
|
||||||
ProviderName: ProviderName,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
182
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go
generated
vendored
182
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go
generated
vendored
@ -1,182 +0,0 @@
|
|||||||
package stscreds
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/service/sts"
|
|
||||||
"github.com/aws/aws-sdk-go/service/sts/stsiface"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ErrCodeWebIdentity will be used as an error code when constructing
|
|
||||||
// a new error to be returned during session creation or retrieval.
|
|
||||||
ErrCodeWebIdentity = "WebIdentityErr"
|
|
||||||
|
|
||||||
// WebIdentityProviderName is the web identity provider name
|
|
||||||
WebIdentityProviderName = "WebIdentityCredentials"
|
|
||||||
)
|
|
||||||
|
|
||||||
// now is used to return a time.Time object representing
|
|
||||||
// the current time. This can be used to easily test and
|
|
||||||
// compare test values.
|
|
||||||
var now = time.Now
|
|
||||||
|
|
||||||
// TokenFetcher should return WebIdentity token bytes or an error
|
|
||||||
type TokenFetcher interface {
|
|
||||||
FetchToken(credentials.Context) ([]byte, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchTokenPath is a path to a WebIdentity token file
|
|
||||||
type FetchTokenPath string
|
|
||||||
|
|
||||||
// FetchToken returns a token by reading from the filesystem
|
|
||||||
func (f FetchTokenPath) FetchToken(ctx credentials.Context) ([]byte, error) {
|
|
||||||
data, err := ioutil.ReadFile(string(f))
|
|
||||||
if err != nil {
|
|
||||||
errMsg := fmt.Sprintf("unable to read file at %s", f)
|
|
||||||
return nil, awserr.New(ErrCodeWebIdentity, errMsg, err)
|
|
||||||
}
|
|
||||||
return data, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WebIdentityRoleProvider is used to retrieve credentials using
|
|
||||||
// an OIDC token.
|
|
||||||
type WebIdentityRoleProvider struct {
|
|
||||||
credentials.Expiry
|
|
||||||
|
|
||||||
// The policy ARNs to use with the web identity assumed role.
|
|
||||||
PolicyArns []*sts.PolicyDescriptorType
|
|
||||||
|
|
||||||
// Duration the STS credentials will be valid for. Truncated to seconds.
|
|
||||||
// If unset, the assumed role will use AssumeRoleWithWebIdentity's default
|
|
||||||
// expiry duration. See
|
|
||||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/#STS.AssumeRoleWithWebIdentity
|
|
||||||
// for more information.
|
|
||||||
Duration time.Duration
|
|
||||||
|
|
||||||
// The amount of time the credentials will be refreshed before they expire.
|
|
||||||
// This is useful refresh credentials before they expire to reduce risk of
|
|
||||||
// using credentials as they expire. If unset, will default to no expiry
|
|
||||||
// window.
|
|
||||||
ExpiryWindow time.Duration
|
|
||||||
|
|
||||||
client stsiface.STSAPI
|
|
||||||
|
|
||||||
tokenFetcher TokenFetcher
|
|
||||||
roleARN string
|
|
||||||
roleSessionName string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWebIdentityCredentials will return a new set of credentials with a given
|
|
||||||
// configuration, role arn, and token file path.
|
|
||||||
//
|
|
||||||
// Deprecated: Use NewWebIdentityRoleProviderWithOptions for flexible
|
|
||||||
// functional options, and wrap with credentials.NewCredentials helper.
|
|
||||||
func NewWebIdentityCredentials(c client.ConfigProvider, roleARN, roleSessionName, path string) *credentials.Credentials {
|
|
||||||
svc := sts.New(c)
|
|
||||||
p := NewWebIdentityRoleProvider(svc, roleARN, roleSessionName, path)
|
|
||||||
return credentials.NewCredentials(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWebIdentityRoleProvider will return a new WebIdentityRoleProvider with the
|
|
||||||
// provided stsiface.STSAPI
|
|
||||||
//
|
|
||||||
// Deprecated: Use NewWebIdentityRoleProviderWithOptions for flexible
|
|
||||||
// functional options.
|
|
||||||
func NewWebIdentityRoleProvider(svc stsiface.STSAPI, roleARN, roleSessionName, path string) *WebIdentityRoleProvider {
|
|
||||||
return NewWebIdentityRoleProviderWithOptions(svc, roleARN, roleSessionName, FetchTokenPath(path))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWebIdentityRoleProviderWithToken will return a new WebIdentityRoleProvider with the
|
|
||||||
// provided stsiface.STSAPI and a TokenFetcher
|
|
||||||
//
|
|
||||||
// Deprecated: Use NewWebIdentityRoleProviderWithOptions for flexible
|
|
||||||
// functional options.
|
|
||||||
func NewWebIdentityRoleProviderWithToken(svc stsiface.STSAPI, roleARN, roleSessionName string, tokenFetcher TokenFetcher) *WebIdentityRoleProvider {
|
|
||||||
return NewWebIdentityRoleProviderWithOptions(svc, roleARN, roleSessionName, tokenFetcher)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWebIdentityRoleProviderWithOptions will return an initialize
|
|
||||||
// WebIdentityRoleProvider with the provided stsiface.STSAPI, role ARN, and a
|
|
||||||
// TokenFetcher. Additional options can be provided as functional options.
|
|
||||||
//
|
|
||||||
// TokenFetcher is the implementation that will retrieve the JWT token from to
|
|
||||||
// assume the role with. Use the provided FetchTokenPath implementation to
|
|
||||||
// retrieve the JWT token using a file system path.
|
|
||||||
func NewWebIdentityRoleProviderWithOptions(svc stsiface.STSAPI, roleARN, roleSessionName string, tokenFetcher TokenFetcher, optFns ...func(*WebIdentityRoleProvider)) *WebIdentityRoleProvider {
|
|
||||||
p := WebIdentityRoleProvider{
|
|
||||||
client: svc,
|
|
||||||
tokenFetcher: tokenFetcher,
|
|
||||||
roleARN: roleARN,
|
|
||||||
roleSessionName: roleSessionName,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, fn := range optFns {
|
|
||||||
fn(&p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &p
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve will attempt to assume a role from a token which is located at
|
|
||||||
// 'WebIdentityTokenFilePath' specified destination and if that is empty an
|
|
||||||
// error will be returned.
|
|
||||||
func (p *WebIdentityRoleProvider) Retrieve() (credentials.Value, error) {
|
|
||||||
return p.RetrieveWithContext(aws.BackgroundContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetrieveWithContext will attempt to assume a role from a token which is
|
|
||||||
// located at 'WebIdentityTokenFilePath' specified destination and if that is
|
|
||||||
// empty an error will be returned.
|
|
||||||
func (p *WebIdentityRoleProvider) RetrieveWithContext(ctx credentials.Context) (credentials.Value, error) {
|
|
||||||
b, err := p.tokenFetcher.FetchToken(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{}, awserr.New(ErrCodeWebIdentity, "failed fetching WebIdentity token: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionName := p.roleSessionName
|
|
||||||
if len(sessionName) == 0 {
|
|
||||||
// session name is used to uniquely identify a session. This simply
|
|
||||||
// uses unix time in nanoseconds to uniquely identify sessions.
|
|
||||||
sessionName = strconv.FormatInt(now().UnixNano(), 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
var duration *int64
|
|
||||||
if p.Duration != 0 {
|
|
||||||
duration = aws.Int64(int64(p.Duration / time.Second))
|
|
||||||
}
|
|
||||||
|
|
||||||
req, resp := p.client.AssumeRoleWithWebIdentityRequest(&sts.AssumeRoleWithWebIdentityInput{
|
|
||||||
PolicyArns: p.PolicyArns,
|
|
||||||
RoleArn: &p.roleARN,
|
|
||||||
RoleSessionName: &sessionName,
|
|
||||||
WebIdentityToken: aws.String(string(b)),
|
|
||||||
DurationSeconds: duration,
|
|
||||||
})
|
|
||||||
|
|
||||||
req.SetContext(ctx)
|
|
||||||
|
|
||||||
// InvalidIdentityToken error is a temporary error that can occur
|
|
||||||
// when assuming an Role with a JWT web identity token.
|
|
||||||
req.RetryErrorCodes = append(req.RetryErrorCodes, sts.ErrCodeInvalidIdentityTokenException)
|
|
||||||
if err := req.Send(); err != nil {
|
|
||||||
return credentials.Value{}, awserr.New(ErrCodeWebIdentity, "failed to retrieve credentials", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.SetExpiration(aws.TimeValue(resp.Credentials.Expiration), p.ExpiryWindow)
|
|
||||||
|
|
||||||
value := credentials.Value{
|
|
||||||
AccessKeyID: aws.StringValue(resp.Credentials.AccessKeyId),
|
|
||||||
SecretAccessKey: aws.StringValue(resp.Credentials.SecretAccessKey),
|
|
||||||
SessionToken: aws.StringValue(resp.Credentials.SessionToken),
|
|
||||||
ProviderName: WebIdentityProviderName,
|
|
||||||
}
|
|
||||||
return value, nil
|
|
||||||
}
|
|
||||||
69
vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go
generated
vendored
69
vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go
generated
vendored
@ -1,69 +0,0 @@
|
|||||||
// Package csm provides the Client Side Monitoring (CSM) client which enables
|
|
||||||
// sending metrics via UDP connection to the CSM agent. This package provides
|
|
||||||
// control options, and configuration for the CSM client. The client can be
|
|
||||||
// controlled manually, or automatically via the SDK's Session configuration.
|
|
||||||
//
|
|
||||||
// Enabling CSM client via SDK's Session configuration
|
|
||||||
//
|
|
||||||
// The CSM client can be enabled automatically via SDK's Session configuration.
|
|
||||||
// The SDK's session configuration enables the CSM client if the AWS_CSM_PORT
|
|
||||||
// environment variable is set to a non-empty value.
|
|
||||||
//
|
|
||||||
// The configuration options for the CSM client via the SDK's session
|
|
||||||
// configuration are:
|
|
||||||
//
|
|
||||||
// * AWS_CSM_PORT=<port number>
|
|
||||||
// The port number the CSM agent will receive metrics on.
|
|
||||||
//
|
|
||||||
// * AWS_CSM_HOST=<hostname or ip>
|
|
||||||
// The hostname, or IP address the CSM agent will receive metrics on.
|
|
||||||
// Without port number.
|
|
||||||
//
|
|
||||||
// Manually enabling the CSM client
|
|
||||||
//
|
|
||||||
// The CSM client can be started, paused, and resumed manually. The Start
|
|
||||||
// function will enable the CSM client to publish metrics to the CSM agent. It
|
|
||||||
// is safe to call Start concurrently, but if Start is called additional times
|
|
||||||
// with different ClientID or address it will panic.
|
|
||||||
//
|
|
||||||
// r, err := csm.Start("clientID", ":31000")
|
|
||||||
// if err != nil {
|
|
||||||
// panic(fmt.Errorf("failed starting CSM: %v", err))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// When controlling the CSM client manually, you must also inject its request
|
|
||||||
// handlers into the SDK's Session configuration for the SDK's API clients to
|
|
||||||
// publish metrics.
|
|
||||||
//
|
|
||||||
// sess, err := session.NewSession(&aws.Config{})
|
|
||||||
// if err != nil {
|
|
||||||
// panic(fmt.Errorf("failed loading session: %v", err))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Add CSM client's metric publishing request handlers to the SDK's
|
|
||||||
// // Session Configuration.
|
|
||||||
// r.InjectHandlers(&sess.Handlers)
|
|
||||||
//
|
|
||||||
// Controlling CSM client
|
|
||||||
//
|
|
||||||
// Once the CSM client has been enabled the Get function will return a Reporter
|
|
||||||
// value that you can use to pause and resume the metrics published to the CSM
|
|
||||||
// agent. If Get function is called before the reporter is enabled with the
|
|
||||||
// Start function or via SDK's Session configuration nil will be returned.
|
|
||||||
//
|
|
||||||
// The Pause method can be called to stop the CSM client publishing metrics to
|
|
||||||
// the CSM agent. The Continue method will resume metric publishing.
|
|
||||||
//
|
|
||||||
// // Get the CSM client Reporter.
|
|
||||||
// r := csm.Get()
|
|
||||||
//
|
|
||||||
// // Will pause monitoring
|
|
||||||
// r.Pause()
|
|
||||||
// resp, err = client.GetObject(&s3.GetObjectInput{
|
|
||||||
// Bucket: aws.String("bucket"),
|
|
||||||
// Key: aws.String("key"),
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// // Resume monitoring
|
|
||||||
// r.Continue()
|
|
||||||
package csm
|
|
||||||
89
vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go
generated
vendored
89
vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go
generated
vendored
@ -1,89 +0,0 @@
|
|||||||
package csm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
lock sync.Mutex
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DefaultPort is used when no port is specified.
|
|
||||||
DefaultPort = "31000"
|
|
||||||
|
|
||||||
// DefaultHost is the host that will be used when none is specified.
|
|
||||||
DefaultHost = "127.0.0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AddressWithDefaults returns a CSM address built from the host and port
|
|
||||||
// values. If the host or port is not set, default values will be used
|
|
||||||
// instead. If host is "localhost" it will be replaced with "127.0.0.1".
|
|
||||||
func AddressWithDefaults(host, port string) string {
|
|
||||||
if len(host) == 0 || strings.EqualFold(host, "localhost") {
|
|
||||||
host = DefaultHost
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(port) == 0 {
|
|
||||||
port = DefaultPort
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only IP6 host can contain a colon
|
|
||||||
if strings.Contains(host, ":") {
|
|
||||||
return "[" + host + "]:" + port
|
|
||||||
}
|
|
||||||
|
|
||||||
return host + ":" + port
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start will start a long running go routine to capture
|
|
||||||
// client side metrics. Calling start multiple time will only
|
|
||||||
// start the metric listener once and will panic if a different
|
|
||||||
// client ID or port is passed in.
|
|
||||||
//
|
|
||||||
// r, err := csm.Start("clientID", "127.0.0.1:31000")
|
|
||||||
// if err != nil {
|
|
||||||
// panic(fmt.Errorf("expected no error, but received %v", err))
|
|
||||||
// }
|
|
||||||
// sess := session.NewSession()
|
|
||||||
// r.InjectHandlers(sess.Handlers)
|
|
||||||
//
|
|
||||||
// svc := s3.New(sess)
|
|
||||||
// out, err := svc.GetObject(&s3.GetObjectInput{
|
|
||||||
// Bucket: aws.String("bucket"),
|
|
||||||
// Key: aws.String("key"),
|
|
||||||
// })
|
|
||||||
func Start(clientID string, url string) (*Reporter, error) {
|
|
||||||
lock.Lock()
|
|
||||||
defer lock.Unlock()
|
|
||||||
|
|
||||||
if sender == nil {
|
|
||||||
sender = newReporter(clientID, url)
|
|
||||||
} else {
|
|
||||||
if sender.clientID != clientID {
|
|
||||||
panic(fmt.Errorf("inconsistent client IDs. %q was expected, but received %q", sender.clientID, clientID))
|
|
||||||
}
|
|
||||||
|
|
||||||
if sender.url != url {
|
|
||||||
panic(fmt.Errorf("inconsistent URLs. %q was expected, but received %q", sender.url, url))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := connect(url); err != nil {
|
|
||||||
sender = nil
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return sender, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get will return a reporter if one exists, if one does not exist, nil will
|
|
||||||
// be returned.
|
|
||||||
func Get() *Reporter {
|
|
||||||
lock.Lock()
|
|
||||||
defer lock.Unlock()
|
|
||||||
|
|
||||||
return sender
|
|
||||||
}
|
|
||||||
109
vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go
generated
vendored
109
vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go
generated
vendored
@ -1,109 +0,0 @@
|
|||||||
package csm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
)
|
|
||||||
|
|
||||||
type metricTime time.Time
|
|
||||||
|
|
||||||
func (t metricTime) MarshalJSON() ([]byte, error) {
|
|
||||||
ns := time.Duration(time.Time(t).UnixNano())
|
|
||||||
return []byte(strconv.FormatInt(int64(ns/time.Millisecond), 10)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type metric struct {
|
|
||||||
ClientID *string `json:"ClientId,omitempty"`
|
|
||||||
API *string `json:"Api,omitempty"`
|
|
||||||
Service *string `json:"Service,omitempty"`
|
|
||||||
Timestamp *metricTime `json:"Timestamp,omitempty"`
|
|
||||||
Type *string `json:"Type,omitempty"`
|
|
||||||
Version *int `json:"Version,omitempty"`
|
|
||||||
|
|
||||||
AttemptCount *int `json:"AttemptCount,omitempty"`
|
|
||||||
Latency *int `json:"Latency,omitempty"`
|
|
||||||
|
|
||||||
Fqdn *string `json:"Fqdn,omitempty"`
|
|
||||||
UserAgent *string `json:"UserAgent,omitempty"`
|
|
||||||
AttemptLatency *int `json:"AttemptLatency,omitempty"`
|
|
||||||
|
|
||||||
SessionToken *string `json:"SessionToken,omitempty"`
|
|
||||||
Region *string `json:"Region,omitempty"`
|
|
||||||
AccessKey *string `json:"AccessKey,omitempty"`
|
|
||||||
HTTPStatusCode *int `json:"HttpStatusCode,omitempty"`
|
|
||||||
XAmzID2 *string `json:"XAmzId2,omitempty"`
|
|
||||||
XAmzRequestID *string `json:"XAmznRequestId,omitempty"`
|
|
||||||
|
|
||||||
AWSException *string `json:"AwsException,omitempty"`
|
|
||||||
AWSExceptionMessage *string `json:"AwsExceptionMessage,omitempty"`
|
|
||||||
SDKException *string `json:"SdkException,omitempty"`
|
|
||||||
SDKExceptionMessage *string `json:"SdkExceptionMessage,omitempty"`
|
|
||||||
|
|
||||||
FinalHTTPStatusCode *int `json:"FinalHttpStatusCode,omitempty"`
|
|
||||||
FinalAWSException *string `json:"FinalAwsException,omitempty"`
|
|
||||||
FinalAWSExceptionMessage *string `json:"FinalAwsExceptionMessage,omitempty"`
|
|
||||||
FinalSDKException *string `json:"FinalSdkException,omitempty"`
|
|
||||||
FinalSDKExceptionMessage *string `json:"FinalSdkExceptionMessage,omitempty"`
|
|
||||||
|
|
||||||
DestinationIP *string `json:"DestinationIp,omitempty"`
|
|
||||||
ConnectionReused *int `json:"ConnectionReused,omitempty"`
|
|
||||||
|
|
||||||
AcquireConnectionLatency *int `json:"AcquireConnectionLatency,omitempty"`
|
|
||||||
ConnectLatency *int `json:"ConnectLatency,omitempty"`
|
|
||||||
RequestLatency *int `json:"RequestLatency,omitempty"`
|
|
||||||
DNSLatency *int `json:"DnsLatency,omitempty"`
|
|
||||||
TCPLatency *int `json:"TcpLatency,omitempty"`
|
|
||||||
SSLLatency *int `json:"SslLatency,omitempty"`
|
|
||||||
|
|
||||||
MaxRetriesExceeded *int `json:"MaxRetriesExceeded,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *metric) TruncateFields() {
|
|
||||||
m.ClientID = truncateString(m.ClientID, 255)
|
|
||||||
m.UserAgent = truncateString(m.UserAgent, 256)
|
|
||||||
|
|
||||||
m.AWSException = truncateString(m.AWSException, 128)
|
|
||||||
m.AWSExceptionMessage = truncateString(m.AWSExceptionMessage, 512)
|
|
||||||
|
|
||||||
m.SDKException = truncateString(m.SDKException, 128)
|
|
||||||
m.SDKExceptionMessage = truncateString(m.SDKExceptionMessage, 512)
|
|
||||||
|
|
||||||
m.FinalAWSException = truncateString(m.FinalAWSException, 128)
|
|
||||||
m.FinalAWSExceptionMessage = truncateString(m.FinalAWSExceptionMessage, 512)
|
|
||||||
|
|
||||||
m.FinalSDKException = truncateString(m.FinalSDKException, 128)
|
|
||||||
m.FinalSDKExceptionMessage = truncateString(m.FinalSDKExceptionMessage, 512)
|
|
||||||
}
|
|
||||||
|
|
||||||
func truncateString(v *string, l int) *string {
|
|
||||||
if v != nil && len(*v) > l {
|
|
||||||
nv := (*v)[:l]
|
|
||||||
return &nv
|
|
||||||
}
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *metric) SetException(e metricException) {
|
|
||||||
switch te := e.(type) {
|
|
||||||
case awsException:
|
|
||||||
m.AWSException = aws.String(te.exception)
|
|
||||||
m.AWSExceptionMessage = aws.String(te.message)
|
|
||||||
case sdkException:
|
|
||||||
m.SDKException = aws.String(te.exception)
|
|
||||||
m.SDKExceptionMessage = aws.String(te.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *metric) SetFinalException(e metricException) {
|
|
||||||
switch te := e.(type) {
|
|
||||||
case awsException:
|
|
||||||
m.FinalAWSException = aws.String(te.exception)
|
|
||||||
m.FinalAWSExceptionMessage = aws.String(te.message)
|
|
||||||
case sdkException:
|
|
||||||
m.FinalSDKException = aws.String(te.exception)
|
|
||||||
m.FinalSDKExceptionMessage = aws.String(te.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
55
vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go
generated
vendored
55
vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go
generated
vendored
@ -1,55 +0,0 @@
|
|||||||
package csm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync/atomic"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
runningEnum = iota
|
|
||||||
pausedEnum
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// MetricsChannelSize of metrics to hold in the channel
|
|
||||||
MetricsChannelSize = 100
|
|
||||||
)
|
|
||||||
|
|
||||||
type metricChan struct {
|
|
||||||
ch chan metric
|
|
||||||
paused *int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMetricChan(size int) metricChan {
|
|
||||||
return metricChan{
|
|
||||||
ch: make(chan metric, size),
|
|
||||||
paused: new(int64),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ch *metricChan) Pause() {
|
|
||||||
atomic.StoreInt64(ch.paused, pausedEnum)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ch *metricChan) Continue() {
|
|
||||||
atomic.StoreInt64(ch.paused, runningEnum)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ch *metricChan) IsPaused() bool {
|
|
||||||
v := atomic.LoadInt64(ch.paused)
|
|
||||||
return v == pausedEnum
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push will push metrics to the metric channel if the channel
|
|
||||||
// is not paused
|
|
||||||
func (ch *metricChan) Push(m metric) bool {
|
|
||||||
if ch.IsPaused() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case ch.ch <- m:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
26
vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go
generated
vendored
26
vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go
generated
vendored
@ -1,26 +0,0 @@
|
|||||||
package csm
|
|
||||||
|
|
||||||
type metricException interface {
|
|
||||||
Exception() string
|
|
||||||
Message() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type requestException struct {
|
|
||||||
exception string
|
|
||||||
message string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e requestException) Exception() string {
|
|
||||||
return e.exception
|
|
||||||
}
|
|
||||||
func (e requestException) Message() string {
|
|
||||||
return e.message
|
|
||||||
}
|
|
||||||
|
|
||||||
type awsException struct {
|
|
||||||
requestException
|
|
||||||
}
|
|
||||||
|
|
||||||
type sdkException struct {
|
|
||||||
requestException
|
|
||||||
}
|
|
||||||
264
vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go
generated
vendored
264
vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go
generated
vendored
@ -1,264 +0,0 @@
|
|||||||
package csm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reporter will gather metrics of API requests made and
|
|
||||||
// send those metrics to the CSM endpoint.
|
|
||||||
type Reporter struct {
|
|
||||||
clientID string
|
|
||||||
url string
|
|
||||||
conn net.Conn
|
|
||||||
metricsCh metricChan
|
|
||||||
done chan struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
sender *Reporter
|
|
||||||
)
|
|
||||||
|
|
||||||
func connect(url string) error {
|
|
||||||
const network = "udp"
|
|
||||||
if err := sender.connect(network, url); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if sender.done == nil {
|
|
||||||
sender.done = make(chan struct{})
|
|
||||||
go sender.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newReporter(clientID, url string) *Reporter {
|
|
||||||
return &Reporter{
|
|
||||||
clientID: clientID,
|
|
||||||
url: url,
|
|
||||||
metricsCh: newMetricChan(MetricsChannelSize),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rep *Reporter) sendAPICallAttemptMetric(r *request.Request) {
|
|
||||||
if rep == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now()
|
|
||||||
creds, _ := r.Config.Credentials.Get()
|
|
||||||
|
|
||||||
m := metric{
|
|
||||||
ClientID: aws.String(rep.clientID),
|
|
||||||
API: aws.String(r.Operation.Name),
|
|
||||||
Service: aws.String(r.ClientInfo.ServiceID),
|
|
||||||
Timestamp: (*metricTime)(&now),
|
|
||||||
UserAgent: aws.String(r.HTTPRequest.Header.Get("User-Agent")),
|
|
||||||
Region: r.Config.Region,
|
|
||||||
Type: aws.String("ApiCallAttempt"),
|
|
||||||
Version: aws.Int(1),
|
|
||||||
|
|
||||||
XAmzRequestID: aws.String(r.RequestID),
|
|
||||||
|
|
||||||
AttemptLatency: aws.Int(int(now.Sub(r.AttemptTime).Nanoseconds() / int64(time.Millisecond))),
|
|
||||||
AccessKey: aws.String(creds.AccessKeyID),
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
m.HTTPStatusCode = aws.Int(r.HTTPResponse.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Error != nil {
|
|
||||||
if awserr, ok := r.Error.(awserr.Error); ok {
|
|
||||||
m.SetException(getMetricException(awserr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m.TruncateFields()
|
|
||||||
rep.metricsCh.Push(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMetricException(err awserr.Error) metricException {
|
|
||||||
msg := err.Error()
|
|
||||||
code := err.Code()
|
|
||||||
|
|
||||||
switch code {
|
|
||||||
case request.ErrCodeRequestError,
|
|
||||||
request.ErrCodeSerialization,
|
|
||||||
request.CanceledErrorCode:
|
|
||||||
return sdkException{
|
|
||||||
requestException{exception: code, message: msg},
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return awsException{
|
|
||||||
requestException{exception: code, message: msg},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rep *Reporter) sendAPICallMetric(r *request.Request) {
|
|
||||||
if rep == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now()
|
|
||||||
m := metric{
|
|
||||||
ClientID: aws.String(rep.clientID),
|
|
||||||
API: aws.String(r.Operation.Name),
|
|
||||||
Service: aws.String(r.ClientInfo.ServiceID),
|
|
||||||
Timestamp: (*metricTime)(&now),
|
|
||||||
UserAgent: aws.String(r.HTTPRequest.Header.Get("User-Agent")),
|
|
||||||
Type: aws.String("ApiCall"),
|
|
||||||
AttemptCount: aws.Int(r.RetryCount + 1),
|
|
||||||
Region: r.Config.Region,
|
|
||||||
Latency: aws.Int(int(time.Since(r.Time) / time.Millisecond)),
|
|
||||||
XAmzRequestID: aws.String(r.RequestID),
|
|
||||||
MaxRetriesExceeded: aws.Int(boolIntValue(r.RetryCount >= r.MaxRetries())),
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
m.FinalHTTPStatusCode = aws.Int(r.HTTPResponse.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Error != nil {
|
|
||||||
if awserr, ok := r.Error.(awserr.Error); ok {
|
|
||||||
m.SetFinalException(getMetricException(awserr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m.TruncateFields()
|
|
||||||
|
|
||||||
// TODO: Probably want to figure something out for logging dropped
|
|
||||||
// metrics
|
|
||||||
rep.metricsCh.Push(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rep *Reporter) connect(network, url string) error {
|
|
||||||
if rep.conn != nil {
|
|
||||||
rep.conn.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
conn, err := net.Dial(network, url)
|
|
||||||
if err != nil {
|
|
||||||
return awserr.New("UDPError", "Could not connect", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rep.conn = conn
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rep *Reporter) close() {
|
|
||||||
if rep.done != nil {
|
|
||||||
close(rep.done)
|
|
||||||
}
|
|
||||||
|
|
||||||
rep.metricsCh.Pause()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rep *Reporter) start() {
|
|
||||||
defer func() {
|
|
||||||
rep.metricsCh.Pause()
|
|
||||||
}()
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-rep.done:
|
|
||||||
rep.done = nil
|
|
||||||
return
|
|
||||||
case m := <-rep.metricsCh.ch:
|
|
||||||
// TODO: What to do with this error? Probably should just log
|
|
||||||
b, err := json.Marshal(m)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
rep.conn.Write(b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pause will pause the metric channel preventing any new metrics from being
|
|
||||||
// added. It is safe to call concurrently with other calls to Pause, but if
|
|
||||||
// called concurently with Continue can lead to unexpected state.
|
|
||||||
func (rep *Reporter) Pause() {
|
|
||||||
lock.Lock()
|
|
||||||
defer lock.Unlock()
|
|
||||||
|
|
||||||
if rep == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
rep.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continue will reopen the metric channel and allow for monitoring to be
|
|
||||||
// resumed. It is safe to call concurrently with other calls to Continue, but
|
|
||||||
// if called concurently with Pause can lead to unexpected state.
|
|
||||||
func (rep *Reporter) Continue() {
|
|
||||||
lock.Lock()
|
|
||||||
defer lock.Unlock()
|
|
||||||
if rep == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !rep.metricsCh.IsPaused() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
rep.metricsCh.Continue()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client side metric handler names
|
|
||||||
const (
|
|
||||||
APICallMetricHandlerName = "awscsm.SendAPICallMetric"
|
|
||||||
APICallAttemptMetricHandlerName = "awscsm.SendAPICallAttemptMetric"
|
|
||||||
)
|
|
||||||
|
|
||||||
// InjectHandlers will will enable client side metrics and inject the proper
|
|
||||||
// handlers to handle how metrics are sent.
|
|
||||||
//
|
|
||||||
// InjectHandlers is NOT safe to call concurrently. Calling InjectHandlers
|
|
||||||
// multiple times may lead to unexpected behavior, (e.g. duplicate metrics).
|
|
||||||
//
|
|
||||||
// // Start must be called in order to inject the correct handlers
|
|
||||||
// r, err := csm.Start("clientID", "127.0.0.1:8094")
|
|
||||||
// if err != nil {
|
|
||||||
// panic(fmt.Errorf("expected no error, but received %v", err))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// sess := session.NewSession()
|
|
||||||
// r.InjectHandlers(&sess.Handlers)
|
|
||||||
//
|
|
||||||
// // create a new service client with our client side metric session
|
|
||||||
// svc := s3.New(sess)
|
|
||||||
func (rep *Reporter) InjectHandlers(handlers *request.Handlers) {
|
|
||||||
if rep == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
handlers.Complete.PushFrontNamed(request.NamedHandler{
|
|
||||||
Name: APICallMetricHandlerName,
|
|
||||||
Fn: rep.sendAPICallMetric,
|
|
||||||
})
|
|
||||||
|
|
||||||
handlers.CompleteAttempt.PushFrontNamed(request.NamedHandler{
|
|
||||||
Name: APICallAttemptMetricHandlerName,
|
|
||||||
Fn: rep.sendAPICallAttemptMetric,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// boolIntValue return 1 for true and 0 for false.
|
|
||||||
func boolIntValue(b bool) int {
|
|
||||||
if b {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
252
vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
generated
vendored
252
vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
generated
vendored
@ -1,252 +0,0 @@
|
|||||||
// Package defaults is a collection of helpers to retrieve the SDK's default
|
|
||||||
// configuration and handlers.
|
|
||||||
//
|
|
||||||
// Generally this package shouldn't be used directly, but session.Session
|
|
||||||
// instead. This package is useful when you need to reset the defaults
|
|
||||||
// of a session or service client to the SDK defaults before setting
|
|
||||||
// additional parameters.
|
|
||||||
package defaults
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials/endpointcreds"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/endpoints"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Defaults provides a collection of default values for SDK clients.
|
|
||||||
type Defaults struct {
|
|
||||||
Config *aws.Config
|
|
||||||
Handlers request.Handlers
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the SDK's default values with Config and handlers pre-configured.
|
|
||||||
func Get() Defaults {
|
|
||||||
cfg := Config()
|
|
||||||
handlers := Handlers()
|
|
||||||
cfg.Credentials = CredChain(cfg, handlers)
|
|
||||||
|
|
||||||
return Defaults{
|
|
||||||
Config: cfg,
|
|
||||||
Handlers: handlers,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Config returns the default configuration without credentials.
|
|
||||||
// To retrieve a config with credentials also included use
|
|
||||||
// `defaults.Get().Config` instead.
|
|
||||||
//
|
|
||||||
// Generally you shouldn't need to use this method directly, but
|
|
||||||
// is available if you need to reset the configuration of an
|
|
||||||
// existing service client or session.
|
|
||||||
func Config() *aws.Config {
|
|
||||||
return aws.NewConfig().
|
|
||||||
WithCredentials(credentials.AnonymousCredentials).
|
|
||||||
WithRegion(os.Getenv("AWS_REGION")).
|
|
||||||
WithHTTPClient(http.DefaultClient).
|
|
||||||
WithMaxRetries(aws.UseServiceDefaultRetries).
|
|
||||||
WithLogger(aws.NewDefaultLogger()).
|
|
||||||
WithLogLevel(aws.LogOff).
|
|
||||||
WithEndpointResolver(endpoints.DefaultResolver())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handlers returns the default request handlers.
|
|
||||||
//
|
|
||||||
// Generally you shouldn't need to use this method directly, but
|
|
||||||
// is available if you need to reset the request handlers of an
|
|
||||||
// existing service client or session.
|
|
||||||
func Handlers() request.Handlers {
|
|
||||||
var handlers request.Handlers
|
|
||||||
|
|
||||||
handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
|
|
||||||
handlers.Validate.AfterEachFn = request.HandlerListStopOnError
|
|
||||||
handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
|
|
||||||
handlers.Build.PushBackNamed(corehandlers.AddAwsInternal)
|
|
||||||
handlers.Build.PushBackNamed(corehandlers.AddHostExecEnvUserAgentHander)
|
|
||||||
handlers.Build.AfterEachFn = request.HandlerListStopOnError
|
|
||||||
handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
|
|
||||||
handlers.Send.PushBackNamed(corehandlers.ValidateReqSigHandler)
|
|
||||||
handlers.Send.PushBackNamed(corehandlers.SendHandler)
|
|
||||||
handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
|
|
||||||
handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler)
|
|
||||||
|
|
||||||
return handlers
|
|
||||||
}
|
|
||||||
|
|
||||||
// CredChain returns the default credential chain.
|
|
||||||
//
|
|
||||||
// Generally you shouldn't need to use this method directly, but
|
|
||||||
// is available if you need to reset the credentials of an
|
|
||||||
// existing service client or session's Config.
|
|
||||||
func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials {
|
|
||||||
return credentials.NewCredentials(&credentials.ChainProvider{
|
|
||||||
VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
|
|
||||||
Providers: CredProviders(cfg, handlers),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// CredProviders returns the slice of providers used in
|
|
||||||
// the default credential chain.
|
|
||||||
//
|
|
||||||
// For applications that need to use some other provider (for example use
|
|
||||||
// different environment variables for legacy reasons) but still fall back
|
|
||||||
// on the default chain of providers. This allows that default chaint to be
|
|
||||||
// automatically updated
|
|
||||||
func CredProviders(cfg *aws.Config, handlers request.Handlers) []credentials.Provider {
|
|
||||||
return []credentials.Provider{
|
|
||||||
&credentials.EnvProvider{},
|
|
||||||
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
|
|
||||||
RemoteCredProvider(*cfg, handlers),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
httpProviderAuthorizationEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN"
|
|
||||||
httpProviderAuthFileEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE"
|
|
||||||
httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
|
|
||||||
)
|
|
||||||
|
|
||||||
// direct representation of the IPv4 address for the ECS container
|
|
||||||
// "169.254.170.2"
|
|
||||||
var ecsContainerIPv4 net.IP = []byte{
|
|
||||||
169, 254, 170, 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
// direct representation of the IPv4 address for the EKS container
|
|
||||||
// "169.254.170.23"
|
|
||||||
var eksContainerIPv4 net.IP = []byte{
|
|
||||||
169, 254, 170, 23,
|
|
||||||
}
|
|
||||||
|
|
||||||
// direct representation of the IPv6 address for the EKS container
|
|
||||||
// "fd00:ec2::23"
|
|
||||||
var eksContainerIPv6 net.IP = []byte{
|
|
||||||
0xFD, 0, 0xE, 0xC2,
|
|
||||||
0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0x23,
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoteCredProvider returns a credentials provider for the default remote
|
|
||||||
// endpoints such as EC2 or ECS Roles.
|
|
||||||
func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
|
|
||||||
if u := os.Getenv(httpProviderEnvVar); len(u) > 0 {
|
|
||||||
return localHTTPCredProvider(cfg, handlers, u)
|
|
||||||
}
|
|
||||||
|
|
||||||
if uri := os.Getenv(shareddefaults.ECSCredsProviderEnvVar); len(uri) > 0 {
|
|
||||||
u := fmt.Sprintf("%s%s", shareddefaults.ECSContainerCredentialsURI, uri)
|
|
||||||
return httpCredProvider(cfg, handlers, u)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ec2RoleProvider(cfg, handlers)
|
|
||||||
}
|
|
||||||
|
|
||||||
var lookupHostFn = net.LookupHost
|
|
||||||
|
|
||||||
// isAllowedHost allows host to be loopback or known ECS/EKS container IPs
|
|
||||||
//
|
|
||||||
// host can either be an IP address OR an unresolved hostname - resolution will
|
|
||||||
// be automatically performed in the latter case
|
|
||||||
func isAllowedHost(host string) (bool, error) {
|
|
||||||
if ip := net.ParseIP(host); ip != nil {
|
|
||||||
return isIPAllowed(ip), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
addrs, err := lookupHostFn(host)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, addr := range addrs {
|
|
||||||
if ip := net.ParseIP(addr); ip == nil || !isIPAllowed(ip) {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isIPAllowed(ip net.IP) bool {
|
|
||||||
return ip.IsLoopback() ||
|
|
||||||
ip.Equal(ecsContainerIPv4) ||
|
|
||||||
ip.Equal(eksContainerIPv4) ||
|
|
||||||
ip.Equal(eksContainerIPv6)
|
|
||||||
}
|
|
||||||
|
|
||||||
func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider {
|
|
||||||
var errMsg string
|
|
||||||
|
|
||||||
parsed, err := url.Parse(u)
|
|
||||||
if err != nil {
|
|
||||||
errMsg = fmt.Sprintf("invalid URL, %v", err)
|
|
||||||
} else {
|
|
||||||
host := aws.URLHostname(parsed)
|
|
||||||
if len(host) == 0 {
|
|
||||||
errMsg = "unable to parse host from local HTTP cred provider URL"
|
|
||||||
} else if parsed.Scheme == "http" {
|
|
||||||
if isAllowedHost, allowHostErr := isAllowedHost(host); allowHostErr != nil {
|
|
||||||
errMsg = fmt.Sprintf("failed to resolve host %q, %v", host, allowHostErr)
|
|
||||||
} else if !isAllowedHost {
|
|
||||||
errMsg = fmt.Sprintf("invalid endpoint host, %q, only loopback/ecs/eks hosts are allowed.", host)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(errMsg) > 0 {
|
|
||||||
if cfg.Logger != nil {
|
|
||||||
cfg.Logger.Log("Ignoring, HTTP credential provider", errMsg, err)
|
|
||||||
}
|
|
||||||
return credentials.ErrorProvider{
|
|
||||||
Err: awserr.New("CredentialsEndpointError", errMsg, err),
|
|
||||||
ProviderName: endpointcreds.ProviderName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return httpCredProvider(cfg, handlers, u)
|
|
||||||
}
|
|
||||||
|
|
||||||
func httpCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider {
|
|
||||||
return endpointcreds.NewProviderClient(cfg, handlers, u,
|
|
||||||
func(p *endpointcreds.Provider) {
|
|
||||||
p.ExpiryWindow = 5 * time.Minute
|
|
||||||
p.AuthorizationToken = os.Getenv(httpProviderAuthorizationEnvVar)
|
|
||||||
if authFilePath := os.Getenv(httpProviderAuthFileEnvVar); authFilePath != "" {
|
|
||||||
p.AuthorizationTokenProvider = endpointcreds.TokenProviderFunc(func() (string, error) {
|
|
||||||
if contents, err := ioutil.ReadFile(authFilePath); err != nil {
|
|
||||||
return "", fmt.Errorf("failed to read authorization token from %v: %v", authFilePath, err)
|
|
||||||
} else {
|
|
||||||
return string(contents), nil
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ec2RoleProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
|
|
||||||
resolver := cfg.EndpointResolver
|
|
||||||
if resolver == nil {
|
|
||||||
resolver = endpoints.DefaultResolver()
|
|
||||||
}
|
|
||||||
|
|
||||||
e, _ := resolver.EndpointFor(endpoints.Ec2metadataServiceID, "")
|
|
||||||
return &ec2rolecreds.EC2RoleProvider{
|
|
||||||
Client: ec2metadata.NewClient(cfg, handlers, e.URL, e.SigningRegion),
|
|
||||||
ExpiryWindow: 5 * time.Minute,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
27
vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go
generated
vendored
27
vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go
generated
vendored
@ -1,27 +0,0 @@
|
|||||||
package defaults
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SharedCredentialsFilename returns the SDK's default file path
|
|
||||||
// for the shared credentials file.
|
|
||||||
//
|
|
||||||
// Builds the shared config file path based on the OS's platform.
|
|
||||||
//
|
|
||||||
// - Linux/Unix: $HOME/.aws/credentials
|
|
||||||
// - Windows: %USERPROFILE%\.aws\credentials
|
|
||||||
func SharedCredentialsFilename() string {
|
|
||||||
return shareddefaults.SharedCredentialsFilename()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SharedConfigFilename returns the SDK's default file path for
|
|
||||||
// the shared config file.
|
|
||||||
//
|
|
||||||
// Builds the shared config file path based on the OS's platform.
|
|
||||||
//
|
|
||||||
// - Linux/Unix: $HOME/.aws/config
|
|
||||||
// - Windows: %USERPROFILE%\.aws\config
|
|
||||||
func SharedConfigFilename() string {
|
|
||||||
return shareddefaults.SharedConfigFilename()
|
|
||||||
}
|
|
||||||
56
vendor/github.com/aws/aws-sdk-go/aws/doc.go
generated
vendored
56
vendor/github.com/aws/aws-sdk-go/aws/doc.go
generated
vendored
@ -1,56 +0,0 @@
|
|||||||
// Package aws provides the core SDK's utilities and shared types. Use this package's
|
|
||||||
// utilities to simplify setting and reading API operations parameters.
|
|
||||||
//
|
|
||||||
// Value and Pointer Conversion Utilities
|
|
||||||
//
|
|
||||||
// This package includes a helper conversion utility for each scalar type the SDK's
|
|
||||||
// API use. These utilities make getting a pointer of the scalar, and dereferencing
|
|
||||||
// a pointer easier.
|
|
||||||
//
|
|
||||||
// Each conversion utility comes in two forms. Value to Pointer and Pointer to Value.
|
|
||||||
// The Pointer to value will safely dereference the pointer and return its value.
|
|
||||||
// If the pointer was nil, the scalar's zero value will be returned.
|
|
||||||
//
|
|
||||||
// The value to pointer functions will be named after the scalar type. So get a
|
|
||||||
// *string from a string value use the "String" function. This makes it easy to
|
|
||||||
// to get pointer of a literal string value, because getting the address of a
|
|
||||||
// literal requires assigning the value to a variable first.
|
|
||||||
//
|
|
||||||
// var strPtr *string
|
|
||||||
//
|
|
||||||
// // Without the SDK's conversion functions
|
|
||||||
// str := "my string"
|
|
||||||
// strPtr = &str
|
|
||||||
//
|
|
||||||
// // With the SDK's conversion functions
|
|
||||||
// strPtr = aws.String("my string")
|
|
||||||
//
|
|
||||||
// // Convert *string to string value
|
|
||||||
// str = aws.StringValue(strPtr)
|
|
||||||
//
|
|
||||||
// In addition to scalars the aws package also includes conversion utilities for
|
|
||||||
// map and slice for commonly types used in API parameters. The map and slice
|
|
||||||
// conversion functions use similar naming pattern as the scalar conversion
|
|
||||||
// functions.
|
|
||||||
//
|
|
||||||
// var strPtrs []*string
|
|
||||||
// var strs []string = []string{"Go", "Gophers", "Go"}
|
|
||||||
//
|
|
||||||
// // Convert []string to []*string
|
|
||||||
// strPtrs = aws.StringSlice(strs)
|
|
||||||
//
|
|
||||||
// // Convert []*string to []string
|
|
||||||
// strs = aws.StringValueSlice(strPtrs)
|
|
||||||
//
|
|
||||||
// SDK Default HTTP Client
|
|
||||||
//
|
|
||||||
// The SDK will use the http.DefaultClient if a HTTP client is not provided to
|
|
||||||
// the SDK's Session, or service client constructor. This means that if the
|
|
||||||
// http.DefaultClient is modified by other components of your application the
|
|
||||||
// modifications will be picked up by the SDK as well.
|
|
||||||
//
|
|
||||||
// In some cases this might be intended, but it is a better practice to create
|
|
||||||
// a custom HTTP Client to share explicitly through your application. You can
|
|
||||||
// configure the SDK to use the custom HTTP Client by setting the HTTPClient
|
|
||||||
// value of the SDK's Config type when creating a Session or service client.
|
|
||||||
package aws
|
|
||||||
250
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
generated
vendored
250
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
generated
vendored
@ -1,250 +0,0 @@
|
|||||||
package ec2metadata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sdkuri"
|
|
||||||
)
|
|
||||||
|
|
||||||
// getToken uses the duration to return a token for EC2 metadata service,
|
|
||||||
// or an error if the request failed.
|
|
||||||
func (c *EC2Metadata) getToken(ctx aws.Context, duration time.Duration) (tokenOutput, error) {
|
|
||||||
op := &request.Operation{
|
|
||||||
Name: "GetToken",
|
|
||||||
HTTPMethod: "PUT",
|
|
||||||
HTTPPath: "/latest/api/token",
|
|
||||||
}
|
|
||||||
|
|
||||||
var output tokenOutput
|
|
||||||
req := c.NewRequest(op, nil, &output)
|
|
||||||
req.SetContext(ctx)
|
|
||||||
|
|
||||||
// remove the fetch token handler from the request handlers to avoid infinite recursion
|
|
||||||
req.Handlers.Sign.RemoveByName(fetchTokenHandlerName)
|
|
||||||
|
|
||||||
// Swap the unmarshalMetadataHandler with unmarshalTokenHandler on this request.
|
|
||||||
req.Handlers.Unmarshal.Swap(unmarshalMetadataHandlerName, unmarshalTokenHandler)
|
|
||||||
|
|
||||||
ttl := strconv.FormatInt(int64(duration/time.Second), 10)
|
|
||||||
req.HTTPRequest.Header.Set(ttlHeader, ttl)
|
|
||||||
|
|
||||||
err := req.Send()
|
|
||||||
|
|
||||||
// Errors with bad request status should be returned.
|
|
||||||
if err != nil {
|
|
||||||
err = awserr.NewRequestFailure(
|
|
||||||
awserr.New(req.HTTPResponse.Status, http.StatusText(req.HTTPResponse.StatusCode), err),
|
|
||||||
req.HTTPResponse.StatusCode, req.RequestID)
|
|
||||||
}
|
|
||||||
|
|
||||||
return output, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMetadata uses the path provided to request information from the EC2
|
|
||||||
// instance metadata service. The content will be returned as a string, or
|
|
||||||
// error if the request failed.
|
|
||||||
func (c *EC2Metadata) GetMetadata(p string) (string, error) {
|
|
||||||
return c.GetMetadataWithContext(aws.BackgroundContext(), p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMetadataWithContext uses the path provided to request information from the EC2
|
|
||||||
// instance metadata service. The content will be returned as a string, or
|
|
||||||
// error if the request failed.
|
|
||||||
func (c *EC2Metadata) GetMetadataWithContext(ctx aws.Context, p string) (string, error) {
|
|
||||||
op := &request.Operation{
|
|
||||||
Name: "GetMetadata",
|
|
||||||
HTTPMethod: "GET",
|
|
||||||
HTTPPath: sdkuri.PathJoin("/latest/meta-data", p),
|
|
||||||
}
|
|
||||||
output := &metadataOutput{}
|
|
||||||
|
|
||||||
req := c.NewRequest(op, nil, output)
|
|
||||||
|
|
||||||
req.SetContext(ctx)
|
|
||||||
|
|
||||||
err := req.Send()
|
|
||||||
return output.Content, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUserData returns the userdata that was configured for the service. If
|
|
||||||
// there is no user-data setup for the EC2 instance a "NotFoundError" error
|
|
||||||
// code will be returned.
|
|
||||||
func (c *EC2Metadata) GetUserData() (string, error) {
|
|
||||||
return c.GetUserDataWithContext(aws.BackgroundContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUserDataWithContext returns the userdata that was configured for the service. If
|
|
||||||
// there is no user-data setup for the EC2 instance a "NotFoundError" error
|
|
||||||
// code will be returned.
|
|
||||||
func (c *EC2Metadata) GetUserDataWithContext(ctx aws.Context) (string, error) {
|
|
||||||
op := &request.Operation{
|
|
||||||
Name: "GetUserData",
|
|
||||||
HTTPMethod: "GET",
|
|
||||||
HTTPPath: "/latest/user-data",
|
|
||||||
}
|
|
||||||
|
|
||||||
output := &metadataOutput{}
|
|
||||||
req := c.NewRequest(op, nil, output)
|
|
||||||
req.SetContext(ctx)
|
|
||||||
|
|
||||||
err := req.Send()
|
|
||||||
return output.Content, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDynamicData uses the path provided to request information from the EC2
|
|
||||||
// instance metadata service for dynamic data. The content will be returned
|
|
||||||
// as a string, or error if the request failed.
|
|
||||||
func (c *EC2Metadata) GetDynamicData(p string) (string, error) {
|
|
||||||
return c.GetDynamicDataWithContext(aws.BackgroundContext(), p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDynamicDataWithContext uses the path provided to request information from the EC2
|
|
||||||
// instance metadata service for dynamic data. The content will be returned
|
|
||||||
// as a string, or error if the request failed.
|
|
||||||
func (c *EC2Metadata) GetDynamicDataWithContext(ctx aws.Context, p string) (string, error) {
|
|
||||||
op := &request.Operation{
|
|
||||||
Name: "GetDynamicData",
|
|
||||||
HTTPMethod: "GET",
|
|
||||||
HTTPPath: sdkuri.PathJoin("/latest/dynamic", p),
|
|
||||||
}
|
|
||||||
|
|
||||||
output := &metadataOutput{}
|
|
||||||
req := c.NewRequest(op, nil, output)
|
|
||||||
req.SetContext(ctx)
|
|
||||||
|
|
||||||
err := req.Send()
|
|
||||||
return output.Content, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetInstanceIdentityDocument retrieves an identity document describing an
|
|
||||||
// instance. Error is returned if the request fails or is unable to parse
|
|
||||||
// the response.
|
|
||||||
func (c *EC2Metadata) GetInstanceIdentityDocument() (EC2InstanceIdentityDocument, error) {
|
|
||||||
return c.GetInstanceIdentityDocumentWithContext(aws.BackgroundContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetInstanceIdentityDocumentWithContext retrieves an identity document describing an
|
|
||||||
// instance. Error is returned if the request fails or is unable to parse
|
|
||||||
// the response.
|
|
||||||
func (c *EC2Metadata) GetInstanceIdentityDocumentWithContext(ctx aws.Context) (EC2InstanceIdentityDocument, error) {
|
|
||||||
resp, err := c.GetDynamicDataWithContext(ctx, "instance-identity/document")
|
|
||||||
if err != nil {
|
|
||||||
return EC2InstanceIdentityDocument{},
|
|
||||||
awserr.New("EC2MetadataRequestError",
|
|
||||||
"failed to get EC2 instance identity document", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
doc := EC2InstanceIdentityDocument{}
|
|
||||||
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&doc); err != nil {
|
|
||||||
return EC2InstanceIdentityDocument{},
|
|
||||||
awserr.New(request.ErrCodeSerialization,
|
|
||||||
"failed to decode EC2 instance identity document", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return doc, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IAMInfo retrieves IAM info from the metadata API
|
|
||||||
func (c *EC2Metadata) IAMInfo() (EC2IAMInfo, error) {
|
|
||||||
return c.IAMInfoWithContext(aws.BackgroundContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
// IAMInfoWithContext retrieves IAM info from the metadata API
|
|
||||||
func (c *EC2Metadata) IAMInfoWithContext(ctx aws.Context) (EC2IAMInfo, error) {
|
|
||||||
resp, err := c.GetMetadataWithContext(ctx, "iam/info")
|
|
||||||
if err != nil {
|
|
||||||
return EC2IAMInfo{},
|
|
||||||
awserr.New("EC2MetadataRequestError",
|
|
||||||
"failed to get EC2 IAM info", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
info := EC2IAMInfo{}
|
|
||||||
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&info); err != nil {
|
|
||||||
return EC2IAMInfo{},
|
|
||||||
awserr.New(request.ErrCodeSerialization,
|
|
||||||
"failed to decode EC2 IAM info", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.Code != "Success" {
|
|
||||||
errMsg := fmt.Sprintf("failed to get EC2 IAM Info (%s)", info.Code)
|
|
||||||
return EC2IAMInfo{},
|
|
||||||
awserr.New("EC2MetadataError", errMsg, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
return info, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Region returns the region the instance is running in.
|
|
||||||
func (c *EC2Metadata) Region() (string, error) {
|
|
||||||
return c.RegionWithContext(aws.BackgroundContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegionWithContext returns the region the instance is running in.
|
|
||||||
func (c *EC2Metadata) RegionWithContext(ctx aws.Context) (string, error) {
|
|
||||||
ec2InstanceIdentityDocument, err := c.GetInstanceIdentityDocumentWithContext(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
// extract region from the ec2InstanceIdentityDocument
|
|
||||||
region := ec2InstanceIdentityDocument.Region
|
|
||||||
if len(region) == 0 {
|
|
||||||
return "", awserr.New("EC2MetadataError", "invalid region received for ec2metadata instance", nil)
|
|
||||||
}
|
|
||||||
// returns region
|
|
||||||
return region, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Available returns if the application has access to the EC2 Metadata service.
|
|
||||||
// Can be used to determine if application is running within an EC2 Instance and
|
|
||||||
// the metadata service is available.
|
|
||||||
func (c *EC2Metadata) Available() bool {
|
|
||||||
return c.AvailableWithContext(aws.BackgroundContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
// AvailableWithContext returns if the application has access to the EC2 Metadata service.
|
|
||||||
// Can be used to determine if application is running within an EC2 Instance and
|
|
||||||
// the metadata service is available.
|
|
||||||
func (c *EC2Metadata) AvailableWithContext(ctx aws.Context) bool {
|
|
||||||
if _, err := c.GetMetadataWithContext(ctx, "instance-id"); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// An EC2IAMInfo provides the shape for unmarshaling
|
|
||||||
// an IAM info from the metadata API
|
|
||||||
type EC2IAMInfo struct {
|
|
||||||
Code string
|
|
||||||
LastUpdated time.Time
|
|
||||||
InstanceProfileArn string
|
|
||||||
InstanceProfileID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// An EC2InstanceIdentityDocument provides the shape for unmarshaling
|
|
||||||
// an instance identity document
|
|
||||||
type EC2InstanceIdentityDocument struct {
|
|
||||||
DevpayProductCodes []string `json:"devpayProductCodes"`
|
|
||||||
MarketplaceProductCodes []string `json:"marketplaceProductCodes"`
|
|
||||||
AvailabilityZone string `json:"availabilityZone"`
|
|
||||||
PrivateIP string `json:"privateIp"`
|
|
||||||
Version string `json:"version"`
|
|
||||||
Region string `json:"region"`
|
|
||||||
InstanceID string `json:"instanceId"`
|
|
||||||
BillingProducts []string `json:"billingProducts"`
|
|
||||||
InstanceType string `json:"instanceType"`
|
|
||||||
AccountID string `json:"accountId"`
|
|
||||||
PendingTime time.Time `json:"pendingTime"`
|
|
||||||
ImageID string `json:"imageId"`
|
|
||||||
KernelID string `json:"kernelId"`
|
|
||||||
RamdiskID string `json:"ramdiskId"`
|
|
||||||
Architecture string `json:"architecture"`
|
|
||||||
}
|
|
||||||
245
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go
generated
vendored
245
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go
generated
vendored
@ -1,245 +0,0 @@
|
|||||||
// Package ec2metadata provides the client for making API calls to the
|
|
||||||
// EC2 Metadata service.
|
|
||||||
//
|
|
||||||
// This package's client can be disabled completely by setting the environment
|
|
||||||
// variable "AWS_EC2_METADATA_DISABLED=true". This environment variable set to
|
|
||||||
// true instructs the SDK to disable the EC2 Metadata client. The client cannot
|
|
||||||
// be used while the environment variable is set to true, (case insensitive).
|
|
||||||
//
|
|
||||||
// The endpoint of the EC2 IMDS client can be configured via the environment
|
|
||||||
// variable, AWS_EC2_METADATA_SERVICE_ENDPOINT when creating the client with a
|
|
||||||
// Session. See aws/session#Options.EC2IMDSEndpoint for more details.
|
|
||||||
package ec2metadata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ServiceName is the name of the service.
|
|
||||||
ServiceName = "ec2metadata"
|
|
||||||
disableServiceEnvVar = "AWS_EC2_METADATA_DISABLED"
|
|
||||||
|
|
||||||
// Headers for Token and TTL
|
|
||||||
ttlHeader = "x-aws-ec2-metadata-token-ttl-seconds"
|
|
||||||
tokenHeader = "x-aws-ec2-metadata-token"
|
|
||||||
|
|
||||||
// Named Handler constants
|
|
||||||
fetchTokenHandlerName = "FetchTokenHandler"
|
|
||||||
unmarshalMetadataHandlerName = "unmarshalMetadataHandler"
|
|
||||||
unmarshalTokenHandlerName = "unmarshalTokenHandler"
|
|
||||||
enableTokenProviderHandlerName = "enableTokenProviderHandler"
|
|
||||||
|
|
||||||
// TTL constants
|
|
||||||
defaultTTL = 21600 * time.Second
|
|
||||||
ttlExpirationWindow = 30 * time.Second
|
|
||||||
)
|
|
||||||
|
|
||||||
// A EC2Metadata is an EC2 Metadata service Client.
|
|
||||||
type EC2Metadata struct {
|
|
||||||
*client.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new instance of the EC2Metadata client with a session.
|
|
||||||
// This client is safe to use across multiple goroutines.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// // Create a EC2Metadata client from just a session.
|
|
||||||
// svc := ec2metadata.New(mySession)
|
|
||||||
//
|
|
||||||
// // Create a EC2Metadata client with additional configuration
|
|
||||||
// svc := ec2metadata.New(mySession, aws.NewConfig().WithLogLevel(aws.LogDebugHTTPBody))
|
|
||||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2Metadata {
|
|
||||||
c := p.ClientConfig(ServiceName, cfgs...)
|
|
||||||
return NewClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClient returns a new EC2Metadata client. Should be used to create
|
|
||||||
// a client when not using a session. Generally using just New with a session
|
|
||||||
// is preferred.
|
|
||||||
//
|
|
||||||
// Will remove the URL path from the endpoint provided to ensure the EC2 IMDS
|
|
||||||
// client is able to communicate with the EC2 IMDS API.
|
|
||||||
//
|
|
||||||
// If an unmodified HTTP client is provided from the stdlib default, or no client
|
|
||||||
// the EC2RoleProvider's EC2Metadata HTTP client's timeout will be shortened.
|
|
||||||
// To disable this set Config.EC2MetadataDisableTimeoutOverride to false. Enabled by default.
|
|
||||||
func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string, opts ...func(*client.Client)) *EC2Metadata {
|
|
||||||
if !aws.BoolValue(cfg.EC2MetadataDisableTimeoutOverride) && httpClientZero(cfg.HTTPClient) {
|
|
||||||
// If the http client is unmodified and this feature is not disabled
|
|
||||||
// set custom timeouts for EC2Metadata requests.
|
|
||||||
cfg.HTTPClient = &http.Client{
|
|
||||||
// use a shorter timeout than default because the metadata
|
|
||||||
// service is local if it is running, and to fail faster
|
|
||||||
// if not running on an ec2 instance.
|
|
||||||
Timeout: 1 * time.Second,
|
|
||||||
}
|
|
||||||
// max number of retries on the client operation
|
|
||||||
cfg.MaxRetries = aws.Int(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
if u, err := url.Parse(endpoint); err == nil {
|
|
||||||
// Remove path from the endpoint since it will be added by requests.
|
|
||||||
// This is an artifact of the SDK adding `/latest` to the endpoint for
|
|
||||||
// EC2 IMDS, but this is now moved to the operation definition.
|
|
||||||
u.Path = ""
|
|
||||||
u.RawPath = ""
|
|
||||||
endpoint = u.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
svc := &EC2Metadata{
|
|
||||||
Client: client.New(
|
|
||||||
cfg,
|
|
||||||
metadata.ClientInfo{
|
|
||||||
ServiceName: ServiceName,
|
|
||||||
ServiceID: ServiceName,
|
|
||||||
Endpoint: endpoint,
|
|
||||||
APIVersion: "latest",
|
|
||||||
},
|
|
||||||
handlers,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
// token provider instance
|
|
||||||
tp := newTokenProvider(svc, defaultTTL)
|
|
||||||
|
|
||||||
// NamedHandler for fetching token
|
|
||||||
svc.Handlers.Sign.PushBackNamed(request.NamedHandler{
|
|
||||||
Name: fetchTokenHandlerName,
|
|
||||||
Fn: tp.fetchTokenHandler,
|
|
||||||
})
|
|
||||||
// NamedHandler for enabling token provider
|
|
||||||
svc.Handlers.Complete.PushBackNamed(request.NamedHandler{
|
|
||||||
Name: enableTokenProviderHandlerName,
|
|
||||||
Fn: tp.enableTokenProviderHandler,
|
|
||||||
})
|
|
||||||
|
|
||||||
svc.Handlers.Unmarshal.PushBackNamed(unmarshalHandler)
|
|
||||||
svc.Handlers.UnmarshalError.PushBack(unmarshalError)
|
|
||||||
svc.Handlers.Validate.Clear()
|
|
||||||
svc.Handlers.Validate.PushBack(validateEndpointHandler)
|
|
||||||
|
|
||||||
// Disable the EC2 Metadata service if the environment variable is set.
|
|
||||||
// This short-circuits the service's functionality to always fail to send
|
|
||||||
// requests.
|
|
||||||
if strings.ToLower(os.Getenv(disableServiceEnvVar)) == "true" {
|
|
||||||
svc.Handlers.Send.SwapNamed(request.NamedHandler{
|
|
||||||
Name: corehandlers.SendHandler.Name,
|
|
||||||
Fn: func(r *request.Request) {
|
|
||||||
r.HTTPResponse = &http.Response{
|
|
||||||
Header: http.Header{},
|
|
||||||
}
|
|
||||||
r.Error = awserr.New(
|
|
||||||
request.CanceledErrorCode,
|
|
||||||
"EC2 IMDS access disabled via "+disableServiceEnvVar+" env var",
|
|
||||||
nil)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add additional options to the service config
|
|
||||||
for _, option := range opts {
|
|
||||||
option(svc.Client)
|
|
||||||
}
|
|
||||||
return svc
|
|
||||||
}
|
|
||||||
|
|
||||||
func httpClientZero(c *http.Client) bool {
|
|
||||||
return c == nil || (c.Transport == nil && c.CheckRedirect == nil && c.Jar == nil && c.Timeout == 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
type metadataOutput struct {
|
|
||||||
Content string
|
|
||||||
}
|
|
||||||
|
|
||||||
type tokenOutput struct {
|
|
||||||
Token string
|
|
||||||
TTL time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// unmarshal token handler is used to parse the response of a getToken operation
|
|
||||||
var unmarshalTokenHandler = request.NamedHandler{
|
|
||||||
Name: unmarshalTokenHandlerName,
|
|
||||||
Fn: func(r *request.Request) {
|
|
||||||
defer r.HTTPResponse.Body.Close()
|
|
||||||
var b bytes.Buffer
|
|
||||||
if _, err := io.Copy(&b, r.HTTPResponse.Body); err != nil {
|
|
||||||
r.Error = awserr.NewRequestFailure(awserr.New(request.ErrCodeSerialization,
|
|
||||||
"unable to unmarshal EC2 metadata response", err), r.HTTPResponse.StatusCode, r.RequestID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
v := r.HTTPResponse.Header.Get(ttlHeader)
|
|
||||||
data, ok := r.Data.(*tokenOutput)
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data.Token = b.String()
|
|
||||||
// TTL is in seconds
|
|
||||||
i, err := strconv.ParseInt(v, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
r.Error = awserr.NewRequestFailure(awserr.New(request.ParamFormatErrCode,
|
|
||||||
"unable to parse EC2 token TTL response", err), r.HTTPResponse.StatusCode, r.RequestID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t := time.Duration(i) * time.Second
|
|
||||||
data.TTL = t
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var unmarshalHandler = request.NamedHandler{
|
|
||||||
Name: unmarshalMetadataHandlerName,
|
|
||||||
Fn: func(r *request.Request) {
|
|
||||||
defer r.HTTPResponse.Body.Close()
|
|
||||||
var b bytes.Buffer
|
|
||||||
if _, err := io.Copy(&b, r.HTTPResponse.Body); err != nil {
|
|
||||||
r.Error = awserr.NewRequestFailure(awserr.New(request.ErrCodeSerialization,
|
|
||||||
"unable to unmarshal EC2 metadata response", err), r.HTTPResponse.StatusCode, r.RequestID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if data, ok := r.Data.(*metadataOutput); ok {
|
|
||||||
data.Content = b.String()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalError(r *request.Request) {
|
|
||||||
defer r.HTTPResponse.Body.Close()
|
|
||||||
var b bytes.Buffer
|
|
||||||
|
|
||||||
if _, err := io.Copy(&b, r.HTTPResponse.Body); err != nil {
|
|
||||||
r.Error = awserr.NewRequestFailure(
|
|
||||||
awserr.New(request.ErrCodeSerialization, "unable to unmarshal EC2 metadata error response", err),
|
|
||||||
r.HTTPResponse.StatusCode, r.RequestID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response body format is not consistent between metadata endpoints.
|
|
||||||
// Grab the error message as a string and include that as the source error
|
|
||||||
r.Error = awserr.NewRequestFailure(
|
|
||||||
awserr.New("EC2MetadataError", "failed to make EC2Metadata request\n"+b.String(), nil),
|
|
||||||
r.HTTPResponse.StatusCode, r.RequestID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateEndpointHandler(r *request.Request) {
|
|
||||||
if r.ClientInfo.Endpoint == "" {
|
|
||||||
r.Error = aws.ErrMissingEndpoint
|
|
||||||
}
|
|
||||||
}
|
|
||||||
99
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/token_provider.go
generated
vendored
99
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/token_provider.go
generated
vendored
@ -1,99 +0,0 @@
|
|||||||
package ec2metadata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"net/http"
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A tokenProvider struct provides access to EC2Metadata client
|
|
||||||
// and atomic instance of a token, along with configuredTTL for it.
|
|
||||||
// tokenProvider also provides an atomic flag to disable the
|
|
||||||
// fetch token operation.
|
|
||||||
// The disabled member will use 0 as false, and 1 as true.
|
|
||||||
type tokenProvider struct {
|
|
||||||
client *EC2Metadata
|
|
||||||
token atomic.Value
|
|
||||||
configuredTTL time.Duration
|
|
||||||
disabled uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
// A ec2Token struct helps use of token in EC2 Metadata service ops
|
|
||||||
type ec2Token struct {
|
|
||||||
token string
|
|
||||||
credentials.Expiry
|
|
||||||
}
|
|
||||||
|
|
||||||
// newTokenProvider provides a pointer to a tokenProvider instance
|
|
||||||
func newTokenProvider(c *EC2Metadata, duration time.Duration) *tokenProvider {
|
|
||||||
return &tokenProvider{client: c, configuredTTL: duration}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if fallback is enabled
|
|
||||||
func (t *tokenProvider) fallbackEnabled() bool {
|
|
||||||
return t.client.Config.EC2MetadataEnableFallback == nil || *t.client.Config.EC2MetadataEnableFallback
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetchTokenHandler fetches token for EC2Metadata service client by default.
|
|
||||||
func (t *tokenProvider) fetchTokenHandler(r *request.Request) {
|
|
||||||
// short-circuits to insecure data flow if tokenProvider is disabled.
|
|
||||||
if v := atomic.LoadUint32(&t.disabled); v == 1 && t.fallbackEnabled() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if ec2Token, ok := t.token.Load().(ec2Token); ok && !ec2Token.IsExpired() {
|
|
||||||
r.HTTPRequest.Header.Set(tokenHeader, ec2Token.token)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
output, err := t.client.getToken(r.Context(), t.configuredTTL)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
// only attempt fallback to insecure data flow if IMDSv1 is enabled
|
|
||||||
if !t.fallbackEnabled() {
|
|
||||||
r.Error = awserr.New("EC2MetadataError", "failed to get IMDSv2 token and fallback to IMDSv1 is disabled", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// change the disabled flag on token provider to true and fallback
|
|
||||||
if requestFailureError, ok := err.(awserr.RequestFailure); ok {
|
|
||||||
switch requestFailureError.StatusCode() {
|
|
||||||
case http.StatusForbidden, http.StatusNotFound, http.StatusMethodNotAllowed:
|
|
||||||
atomic.StoreUint32(&t.disabled, 1)
|
|
||||||
if t.client.Config.LogLevel.Matches(aws.LogDebugWithDeprecated) {
|
|
||||||
t.client.Config.Logger.Log(fmt.Sprintf("WARN: failed to get session token, falling back to IMDSv1: %v", requestFailureError))
|
|
||||||
}
|
|
||||||
case http.StatusBadRequest:
|
|
||||||
r.Error = requestFailureError
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
newToken := ec2Token{
|
|
||||||
token: output.Token,
|
|
||||||
}
|
|
||||||
newToken.SetExpiration(time.Now().Add(output.TTL), ttlExpirationWindow)
|
|
||||||
t.token.Store(newToken)
|
|
||||||
|
|
||||||
// Inject token header to the request.
|
|
||||||
if ec2Token, ok := t.token.Load().(ec2Token); ok {
|
|
||||||
r.HTTPRequest.Header.Set(tokenHeader, ec2Token.token)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// enableTokenProviderHandler enables the token provider
|
|
||||||
func (t *tokenProvider) enableTokenProviderHandler(r *request.Request) {
|
|
||||||
// If the error code status is 401, we enable the token provider
|
|
||||||
if e, ok := r.Error.(awserr.RequestFailure); ok && e != nil &&
|
|
||||||
e.StatusCode() == http.StatusUnauthorized {
|
|
||||||
t.token.Store(ec2Token{})
|
|
||||||
atomic.StoreUint32(&t.disabled, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
193
vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
generated
vendored
193
vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
generated
vendored
@ -1,193 +0,0 @@
|
|||||||
package endpoints
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
type modelDefinition map[string]json.RawMessage
|
|
||||||
|
|
||||||
// A DecodeModelOptions are the options for how the endpoints model definition
|
|
||||||
// are decoded.
|
|
||||||
type DecodeModelOptions struct {
|
|
||||||
SkipCustomizations bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set combines all of the option functions together.
|
|
||||||
func (d *DecodeModelOptions) Set(optFns ...func(*DecodeModelOptions)) {
|
|
||||||
for _, fn := range optFns {
|
|
||||||
fn(d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeModel unmarshals a Regions and Endpoint model definition file into
|
|
||||||
// a endpoint Resolver. If the file format is not supported, or an error occurs
|
|
||||||
// when unmarshaling the model an error will be returned.
|
|
||||||
//
|
|
||||||
// Casting the return value of this func to a EnumPartitions will
|
|
||||||
// allow you to get a list of the partitions in the order the endpoints
|
|
||||||
// will be resolved in.
|
|
||||||
//
|
|
||||||
// resolver, err := endpoints.DecodeModel(reader)
|
|
||||||
//
|
|
||||||
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
|
|
||||||
// for _, p := range partitions {
|
|
||||||
// // ... inspect partitions
|
|
||||||
// }
|
|
||||||
func DecodeModel(r io.Reader, optFns ...func(*DecodeModelOptions)) (Resolver, error) {
|
|
||||||
var opts DecodeModelOptions
|
|
||||||
opts.Set(optFns...)
|
|
||||||
|
|
||||||
// Get the version of the partition file to determine what
|
|
||||||
// unmarshaling model to use.
|
|
||||||
modelDef := modelDefinition{}
|
|
||||||
if err := json.NewDecoder(r).Decode(&modelDef); err != nil {
|
|
||||||
return nil, newDecodeModelError("failed to decode endpoints model", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var version string
|
|
||||||
if b, ok := modelDef["version"]; ok {
|
|
||||||
version = string(b)
|
|
||||||
} else {
|
|
||||||
return nil, newDecodeModelError("endpoints version not found in model", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
if version == "3" {
|
|
||||||
return decodeV3Endpoints(modelDef, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, newDecodeModelError(
|
|
||||||
fmt.Sprintf("endpoints version %s, not supported", version), nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resolver, error) {
|
|
||||||
b, ok := modelDef["partitions"]
|
|
||||||
if !ok {
|
|
||||||
return nil, newDecodeModelError("endpoints model missing partitions", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
ps := partitions{}
|
|
||||||
if err := json.Unmarshal(b, &ps); err != nil {
|
|
||||||
return nil, newDecodeModelError("failed to decode endpoints model", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.SkipCustomizations {
|
|
||||||
return ps, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Customization
|
|
||||||
for i := 0; i < len(ps); i++ {
|
|
||||||
p := &ps[i]
|
|
||||||
custRegionalS3(p)
|
|
||||||
custRmIotDataService(p)
|
|
||||||
custFixAppAutoscalingChina(p)
|
|
||||||
custFixAppAutoscalingUsGov(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ps, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func custRegionalS3(p *partition) {
|
|
||||||
if p.ID != "aws" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
service, ok := p.Services["s3"]
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const awsGlobal = "aws-global"
|
|
||||||
const usEast1 = "us-east-1"
|
|
||||||
|
|
||||||
// If global endpoint already exists no customization needed.
|
|
||||||
if _, ok := service.Endpoints[endpointKey{Region: awsGlobal}]; ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
service.PartitionEndpoint = awsGlobal
|
|
||||||
if _, ok := service.Endpoints[endpointKey{Region: usEast1}]; !ok {
|
|
||||||
service.Endpoints[endpointKey{Region: usEast1}] = endpoint{}
|
|
||||||
}
|
|
||||||
service.Endpoints[endpointKey{Region: awsGlobal}] = endpoint{
|
|
||||||
Hostname: "s3.amazonaws.com",
|
|
||||||
CredentialScope: credentialScope{
|
|
||||||
Region: usEast1,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
p.Services["s3"] = service
|
|
||||||
}
|
|
||||||
|
|
||||||
func custRmIotDataService(p *partition) {
|
|
||||||
delete(p.Services, "data.iot")
|
|
||||||
}
|
|
||||||
|
|
||||||
func custFixAppAutoscalingChina(p *partition) {
|
|
||||||
if p.ID != "aws-cn" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const serviceName = "application-autoscaling"
|
|
||||||
s, ok := p.Services[serviceName]
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const expectHostname = `autoscaling.{region}.amazonaws.com`
|
|
||||||
serviceDefault := s.Defaults[defaultKey{}]
|
|
||||||
if e, a := expectHostname, serviceDefault.Hostname; e != a {
|
|
||||||
fmt.Printf("custFixAppAutoscalingChina: ignoring customization, expected %s, got %s\n", e, a)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
serviceDefault.Hostname = expectHostname + ".cn"
|
|
||||||
s.Defaults[defaultKey{}] = serviceDefault
|
|
||||||
p.Services[serviceName] = s
|
|
||||||
}
|
|
||||||
|
|
||||||
func custFixAppAutoscalingUsGov(p *partition) {
|
|
||||||
if p.ID != "aws-us-gov" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const serviceName = "application-autoscaling"
|
|
||||||
s, ok := p.Services[serviceName]
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceDefault := s.Defaults[defaultKey{}]
|
|
||||||
if a := serviceDefault.CredentialScope.Service; a != "" {
|
|
||||||
fmt.Printf("custFixAppAutoscalingUsGov: ignoring customization, expected empty credential scope service, got %s\n", a)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if a := serviceDefault.Hostname; a != "" {
|
|
||||||
fmt.Printf("custFixAppAutoscalingUsGov: ignoring customization, expected empty hostname, got %s\n", a)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceDefault.CredentialScope.Service = "application-autoscaling"
|
|
||||||
serviceDefault.Hostname = "autoscaling.{region}.amazonaws.com"
|
|
||||||
|
|
||||||
if s.Defaults == nil {
|
|
||||||
s.Defaults = make(endpointDefaults)
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Defaults[defaultKey{}] = serviceDefault
|
|
||||||
|
|
||||||
p.Services[serviceName] = s
|
|
||||||
}
|
|
||||||
|
|
||||||
type decodeModelError struct {
|
|
||||||
awsError
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDecodeModelError(msg string, err error) decodeModelError {
|
|
||||||
return decodeModelError{
|
|
||||||
awsError: awserr.New("DecodeEndpointsModelError", msg, err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
45225
vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
generated
vendored
45225
vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
generated
vendored
File diff suppressed because it is too large
Load Diff
141
vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go
generated
vendored
141
vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go
generated
vendored
@ -1,141 +0,0 @@
|
|||||||
package endpoints
|
|
||||||
|
|
||||||
// Service identifiers
|
|
||||||
//
|
|
||||||
// Deprecated: Use client package's EndpointsID value instead of these
|
|
||||||
// ServiceIDs. These IDs are not maintained, and are out of date.
|
|
||||||
const (
|
|
||||||
A4bServiceID = "a4b" // A4b.
|
|
||||||
AcmServiceID = "acm" // Acm.
|
|
||||||
AcmPcaServiceID = "acm-pca" // AcmPca.
|
|
||||||
ApiMediatailorServiceID = "api.mediatailor" // ApiMediatailor.
|
|
||||||
ApiPricingServiceID = "api.pricing" // ApiPricing.
|
|
||||||
ApiSagemakerServiceID = "api.sagemaker" // ApiSagemaker.
|
|
||||||
ApigatewayServiceID = "apigateway" // Apigateway.
|
|
||||||
ApplicationAutoscalingServiceID = "application-autoscaling" // ApplicationAutoscaling.
|
|
||||||
Appstream2ServiceID = "appstream2" // Appstream2.
|
|
||||||
AppsyncServiceID = "appsync" // Appsync.
|
|
||||||
AthenaServiceID = "athena" // Athena.
|
|
||||||
AutoscalingServiceID = "autoscaling" // Autoscaling.
|
|
||||||
AutoscalingPlansServiceID = "autoscaling-plans" // AutoscalingPlans.
|
|
||||||
BatchServiceID = "batch" // Batch.
|
|
||||||
BudgetsServiceID = "budgets" // Budgets.
|
|
||||||
CeServiceID = "ce" // Ce.
|
|
||||||
ChimeServiceID = "chime" // Chime.
|
|
||||||
Cloud9ServiceID = "cloud9" // Cloud9.
|
|
||||||
ClouddirectoryServiceID = "clouddirectory" // Clouddirectory.
|
|
||||||
CloudformationServiceID = "cloudformation" // Cloudformation.
|
|
||||||
CloudfrontServiceID = "cloudfront" // Cloudfront.
|
|
||||||
CloudhsmServiceID = "cloudhsm" // Cloudhsm.
|
|
||||||
Cloudhsmv2ServiceID = "cloudhsmv2" // Cloudhsmv2.
|
|
||||||
CloudsearchServiceID = "cloudsearch" // Cloudsearch.
|
|
||||||
CloudtrailServiceID = "cloudtrail" // Cloudtrail.
|
|
||||||
CodebuildServiceID = "codebuild" // Codebuild.
|
|
||||||
CodecommitServiceID = "codecommit" // Codecommit.
|
|
||||||
CodedeployServiceID = "codedeploy" // Codedeploy.
|
|
||||||
CodepipelineServiceID = "codepipeline" // Codepipeline.
|
|
||||||
CodestarServiceID = "codestar" // Codestar.
|
|
||||||
CognitoIdentityServiceID = "cognito-identity" // CognitoIdentity.
|
|
||||||
CognitoIdpServiceID = "cognito-idp" // CognitoIdp.
|
|
||||||
CognitoSyncServiceID = "cognito-sync" // CognitoSync.
|
|
||||||
ComprehendServiceID = "comprehend" // Comprehend.
|
|
||||||
ConfigServiceID = "config" // Config.
|
|
||||||
CurServiceID = "cur" // Cur.
|
|
||||||
DatapipelineServiceID = "datapipeline" // Datapipeline.
|
|
||||||
DaxServiceID = "dax" // Dax.
|
|
||||||
DevicefarmServiceID = "devicefarm" // Devicefarm.
|
|
||||||
DirectconnectServiceID = "directconnect" // Directconnect.
|
|
||||||
DiscoveryServiceID = "discovery" // Discovery.
|
|
||||||
DmsServiceID = "dms" // Dms.
|
|
||||||
DsServiceID = "ds" // Ds.
|
|
||||||
DynamodbServiceID = "dynamodb" // Dynamodb.
|
|
||||||
Ec2ServiceID = "ec2" // Ec2.
|
|
||||||
Ec2metadataServiceID = "ec2metadata" // Ec2metadata.
|
|
||||||
EcrServiceID = "ecr" // Ecr.
|
|
||||||
EcsServiceID = "ecs" // Ecs.
|
|
||||||
ElasticacheServiceID = "elasticache" // Elasticache.
|
|
||||||
ElasticbeanstalkServiceID = "elasticbeanstalk" // Elasticbeanstalk.
|
|
||||||
ElasticfilesystemServiceID = "elasticfilesystem" // Elasticfilesystem.
|
|
||||||
ElasticloadbalancingServiceID = "elasticloadbalancing" // Elasticloadbalancing.
|
|
||||||
ElasticmapreduceServiceID = "elasticmapreduce" // Elasticmapreduce.
|
|
||||||
ElastictranscoderServiceID = "elastictranscoder" // Elastictranscoder.
|
|
||||||
EmailServiceID = "email" // Email.
|
|
||||||
EntitlementMarketplaceServiceID = "entitlement.marketplace" // EntitlementMarketplace.
|
|
||||||
EsServiceID = "es" // Es.
|
|
||||||
EventsServiceID = "events" // Events.
|
|
||||||
FirehoseServiceID = "firehose" // Firehose.
|
|
||||||
FmsServiceID = "fms" // Fms.
|
|
||||||
GameliftServiceID = "gamelift" // Gamelift.
|
|
||||||
GlacierServiceID = "glacier" // Glacier.
|
|
||||||
GlueServiceID = "glue" // Glue.
|
|
||||||
GreengrassServiceID = "greengrass" // Greengrass.
|
|
||||||
GuarddutyServiceID = "guardduty" // Guardduty.
|
|
||||||
HealthServiceID = "health" // Health.
|
|
||||||
IamServiceID = "iam" // Iam.
|
|
||||||
ImportexportServiceID = "importexport" // Importexport.
|
|
||||||
InspectorServiceID = "inspector" // Inspector.
|
|
||||||
IotServiceID = "iot" // Iot.
|
|
||||||
IotanalyticsServiceID = "iotanalytics" // Iotanalytics.
|
|
||||||
KinesisServiceID = "kinesis" // Kinesis.
|
|
||||||
KinesisanalyticsServiceID = "kinesisanalytics" // Kinesisanalytics.
|
|
||||||
KinesisvideoServiceID = "kinesisvideo" // Kinesisvideo.
|
|
||||||
KmsServiceID = "kms" // Kms.
|
|
||||||
LambdaServiceID = "lambda" // Lambda.
|
|
||||||
LightsailServiceID = "lightsail" // Lightsail.
|
|
||||||
LogsServiceID = "logs" // Logs.
|
|
||||||
MachinelearningServiceID = "machinelearning" // Machinelearning.
|
|
||||||
MarketplacecommerceanalyticsServiceID = "marketplacecommerceanalytics" // Marketplacecommerceanalytics.
|
|
||||||
MediaconvertServiceID = "mediaconvert" // Mediaconvert.
|
|
||||||
MedialiveServiceID = "medialive" // Medialive.
|
|
||||||
MediapackageServiceID = "mediapackage" // Mediapackage.
|
|
||||||
MediastoreServiceID = "mediastore" // Mediastore.
|
|
||||||
MeteringMarketplaceServiceID = "metering.marketplace" // MeteringMarketplace.
|
|
||||||
MghServiceID = "mgh" // Mgh.
|
|
||||||
MobileanalyticsServiceID = "mobileanalytics" // Mobileanalytics.
|
|
||||||
ModelsLexServiceID = "models.lex" // ModelsLex.
|
|
||||||
MonitoringServiceID = "monitoring" // Monitoring.
|
|
||||||
MturkRequesterServiceID = "mturk-requester" // MturkRequester.
|
|
||||||
NeptuneServiceID = "neptune" // Neptune.
|
|
||||||
OpsworksServiceID = "opsworks" // Opsworks.
|
|
||||||
OpsworksCmServiceID = "opsworks-cm" // OpsworksCm.
|
|
||||||
OrganizationsServiceID = "organizations" // Organizations.
|
|
||||||
PinpointServiceID = "pinpoint" // Pinpoint.
|
|
||||||
PollyServiceID = "polly" // Polly.
|
|
||||||
RdsServiceID = "rds" // Rds.
|
|
||||||
RedshiftServiceID = "redshift" // Redshift.
|
|
||||||
RekognitionServiceID = "rekognition" // Rekognition.
|
|
||||||
ResourceGroupsServiceID = "resource-groups" // ResourceGroups.
|
|
||||||
Route53ServiceID = "route53" // Route53.
|
|
||||||
Route53domainsServiceID = "route53domains" // Route53domains.
|
|
||||||
RuntimeLexServiceID = "runtime.lex" // RuntimeLex.
|
|
||||||
RuntimeSagemakerServiceID = "runtime.sagemaker" // RuntimeSagemaker.
|
|
||||||
S3ServiceID = "s3" // S3.
|
|
||||||
S3ControlServiceID = "s3-control" // S3Control.
|
|
||||||
SagemakerServiceID = "api.sagemaker" // Sagemaker.
|
|
||||||
SdbServiceID = "sdb" // Sdb.
|
|
||||||
SecretsmanagerServiceID = "secretsmanager" // Secretsmanager.
|
|
||||||
ServerlessrepoServiceID = "serverlessrepo" // Serverlessrepo.
|
|
||||||
ServicecatalogServiceID = "servicecatalog" // Servicecatalog.
|
|
||||||
ServicediscoveryServiceID = "servicediscovery" // Servicediscovery.
|
|
||||||
ShieldServiceID = "shield" // Shield.
|
|
||||||
SmsServiceID = "sms" // Sms.
|
|
||||||
SnowballServiceID = "snowball" // Snowball.
|
|
||||||
SnsServiceID = "sns" // Sns.
|
|
||||||
SqsServiceID = "sqs" // Sqs.
|
|
||||||
SsmServiceID = "ssm" // Ssm.
|
|
||||||
StatesServiceID = "states" // States.
|
|
||||||
StoragegatewayServiceID = "storagegateway" // Storagegateway.
|
|
||||||
StreamsDynamodbServiceID = "streams.dynamodb" // StreamsDynamodb.
|
|
||||||
StsServiceID = "sts" // Sts.
|
|
||||||
SupportServiceID = "support" // Support.
|
|
||||||
SwfServiceID = "swf" // Swf.
|
|
||||||
TaggingServiceID = "tagging" // Tagging.
|
|
||||||
TransferServiceID = "transfer" // Transfer.
|
|
||||||
TranslateServiceID = "translate" // Translate.
|
|
||||||
WafServiceID = "waf" // Waf.
|
|
||||||
WafRegionalServiceID = "waf-regional" // WafRegional.
|
|
||||||
WorkdocsServiceID = "workdocs" // Workdocs.
|
|
||||||
WorkmailServiceID = "workmail" // Workmail.
|
|
||||||
WorkspacesServiceID = "workspaces" // Workspaces.
|
|
||||||
XrayServiceID = "xray" // Xray.
|
|
||||||
)
|
|
||||||
65
vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go
generated
vendored
65
vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go
generated
vendored
@ -1,65 +0,0 @@
|
|||||||
// Package endpoints provides the types and functionality for defining regions
|
|
||||||
// and endpoints, as well as querying those definitions.
|
|
||||||
//
|
|
||||||
// The SDK's Regions and Endpoints metadata is code generated into the endpoints
|
|
||||||
// package, and is accessible via the DefaultResolver function. This function
|
|
||||||
// returns a endpoint Resolver will search the metadata and build an associated
|
|
||||||
// endpoint if one is found. The default resolver will search all partitions
|
|
||||||
// known by the SDK. e.g AWS Standard (aws), AWS China (aws-cn), and
|
|
||||||
// AWS GovCloud (US) (aws-us-gov).
|
|
||||||
// .
|
|
||||||
//
|
|
||||||
// # Enumerating Regions and Endpoint Metadata
|
|
||||||
//
|
|
||||||
// Casting the Resolver returned by DefaultResolver to a EnumPartitions interface
|
|
||||||
// will allow you to get access to the list of underlying Partitions with the
|
|
||||||
// Partitions method. This is helpful if you want to limit the SDK's endpoint
|
|
||||||
// resolving to a single partition, or enumerate regions, services, and endpoints
|
|
||||||
// in the partition.
|
|
||||||
//
|
|
||||||
// resolver := endpoints.DefaultResolver()
|
|
||||||
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
|
|
||||||
//
|
|
||||||
// for _, p := range partitions {
|
|
||||||
// fmt.Println("Regions for", p.ID())
|
|
||||||
// for id, _ := range p.Regions() {
|
|
||||||
// fmt.Println("*", id)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fmt.Println("Services for", p.ID())
|
|
||||||
// for id, _ := range p.Services() {
|
|
||||||
// fmt.Println("*", id)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// # Using Custom Endpoints
|
|
||||||
//
|
|
||||||
// The endpoints package also gives you the ability to use your own logic how
|
|
||||||
// endpoints are resolved. This is a great way to define a custom endpoint
|
|
||||||
// for select services, without passing that logic down through your code.
|
|
||||||
//
|
|
||||||
// If a type implements the Resolver interface it can be used to resolve
|
|
||||||
// endpoints. To use this with the SDK's Session and Config set the value
|
|
||||||
// of the type to the EndpointsResolver field of aws.Config when initializing
|
|
||||||
// the session, or service client.
|
|
||||||
//
|
|
||||||
// In addition the ResolverFunc is a wrapper for a func matching the signature
|
|
||||||
// of Resolver.EndpointFor, converting it to a type that satisfies the
|
|
||||||
// Resolver interface.
|
|
||||||
//
|
|
||||||
// myCustomResolver := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
|
|
||||||
// if service == endpoints.S3ServiceID {
|
|
||||||
// return endpoints.ResolvedEndpoint{
|
|
||||||
// URL: "s3.custom.endpoint.com",
|
|
||||||
// SigningRegion: "custom-signing-region",
|
|
||||||
// }, nil
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return endpoints.DefaultResolver().EndpointFor(service, region, optFns...)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// sess := session.Must(session.NewSession(&aws.Config{
|
|
||||||
// Region: aws.String("us-west-2"),
|
|
||||||
// EndpointResolver: endpoints.ResolverFunc(myCustomResolver),
|
|
||||||
// }))
|
|
||||||
package endpoints
|
|
||||||
708
vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go
generated
vendored
708
vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go
generated
vendored
@ -1,708 +0,0 @@
|
|||||||
package endpoints
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Logger is a minimalistic interface for the SDK to log messages to.
|
|
||||||
type Logger interface {
|
|
||||||
Log(...interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// DualStackEndpointState is a constant to describe the dual-stack endpoint resolution
|
|
||||||
// behavior.
|
|
||||||
type DualStackEndpointState uint
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DualStackEndpointStateUnset is the default value behavior for dual-stack endpoint
|
|
||||||
// resolution.
|
|
||||||
DualStackEndpointStateUnset DualStackEndpointState = iota
|
|
||||||
|
|
||||||
// DualStackEndpointStateEnabled enable dual-stack endpoint resolution for endpoints.
|
|
||||||
DualStackEndpointStateEnabled
|
|
||||||
|
|
||||||
// DualStackEndpointStateDisabled disables dual-stack endpoint resolution for endpoints.
|
|
||||||
DualStackEndpointStateDisabled
|
|
||||||
)
|
|
||||||
|
|
||||||
// FIPSEndpointState is a constant to describe the FIPS endpoint resolution behavior.
|
|
||||||
type FIPSEndpointState uint
|
|
||||||
|
|
||||||
const (
|
|
||||||
// FIPSEndpointStateUnset is the default value behavior for FIPS endpoint resolution.
|
|
||||||
FIPSEndpointStateUnset FIPSEndpointState = iota
|
|
||||||
|
|
||||||
// FIPSEndpointStateEnabled enables FIPS endpoint resolution for service endpoints.
|
|
||||||
FIPSEndpointStateEnabled
|
|
||||||
|
|
||||||
// FIPSEndpointStateDisabled disables FIPS endpoint resolution for endpoints.
|
|
||||||
FIPSEndpointStateDisabled
|
|
||||||
)
|
|
||||||
|
|
||||||
// Options provide the configuration needed to direct how the
|
|
||||||
// endpoints will be resolved.
|
|
||||||
type Options struct {
|
|
||||||
// DisableSSL forces the endpoint to be resolved as HTTP.
|
|
||||||
// instead of HTTPS if the service supports it.
|
|
||||||
DisableSSL bool
|
|
||||||
|
|
||||||
// Sets the resolver to resolve the endpoint as a dualstack endpoint
|
|
||||||
// for the service. If dualstack support for a service is not known and
|
|
||||||
// StrictMatching is not enabled a dualstack endpoint for the service will
|
|
||||||
// be returned. This endpoint may not be valid. If StrictMatching is
|
|
||||||
// enabled only services that are known to support dualstack will return
|
|
||||||
// dualstack endpoints.
|
|
||||||
//
|
|
||||||
// Deprecated: This option will continue to function for S3 and S3 Control for backwards compatibility.
|
|
||||||
// UseDualStackEndpoint should be used to enable usage of a service's dual-stack endpoint for all service clients
|
|
||||||
// moving forward. For S3 and S3 Control, when UseDualStackEndpoint is set to a non-zero value it takes higher
|
|
||||||
// precedence then this option.
|
|
||||||
UseDualStack bool
|
|
||||||
|
|
||||||
// Sets the resolver to resolve a dual-stack endpoint for the service.
|
|
||||||
UseDualStackEndpoint DualStackEndpointState
|
|
||||||
|
|
||||||
// UseFIPSEndpoint specifies the resolver must resolve a FIPS endpoint.
|
|
||||||
UseFIPSEndpoint FIPSEndpointState
|
|
||||||
|
|
||||||
// Enables strict matching of services and regions resolved endpoints.
|
|
||||||
// If the partition doesn't enumerate the exact service and region an
|
|
||||||
// error will be returned. This option will prevent returning endpoints
|
|
||||||
// that look valid, but may not resolve to any real endpoint.
|
|
||||||
StrictMatching bool
|
|
||||||
|
|
||||||
// Enables resolving a service endpoint based on the region provided if the
|
|
||||||
// service does not exist. The service endpoint ID will be used as the service
|
|
||||||
// domain name prefix. By default the endpoint resolver requires the service
|
|
||||||
// to be known when resolving endpoints.
|
|
||||||
//
|
|
||||||
// If resolving an endpoint on the partition list the provided region will
|
|
||||||
// be used to determine which partition's domain name pattern to the service
|
|
||||||
// endpoint ID with. If both the service and region are unknown and resolving
|
|
||||||
// the endpoint on partition list an UnknownEndpointError error will be returned.
|
|
||||||
//
|
|
||||||
// If resolving and endpoint on a partition specific resolver that partition's
|
|
||||||
// domain name pattern will be used with the service endpoint ID. If both
|
|
||||||
// region and service do not exist when resolving an endpoint on a specific
|
|
||||||
// partition the partition's domain pattern will be used to combine the
|
|
||||||
// endpoint and region together.
|
|
||||||
//
|
|
||||||
// This option is ignored if StrictMatching is enabled.
|
|
||||||
ResolveUnknownService bool
|
|
||||||
|
|
||||||
// Specifies the EC2 Instance Metadata Service default endpoint selection mode (IPv4 or IPv6)
|
|
||||||
EC2MetadataEndpointMode EC2IMDSEndpointModeState
|
|
||||||
|
|
||||||
// STS Regional Endpoint flag helps with resolving the STS endpoint
|
|
||||||
STSRegionalEndpoint STSRegionalEndpoint
|
|
||||||
|
|
||||||
// S3 Regional Endpoint flag helps with resolving the S3 endpoint
|
|
||||||
S3UsEast1RegionalEndpoint S3UsEast1RegionalEndpoint
|
|
||||||
|
|
||||||
// ResolvedRegion is the resolved region string. If provided (non-zero length) it takes priority
|
|
||||||
// over the region name passed to the ResolveEndpoint call.
|
|
||||||
ResolvedRegion string
|
|
||||||
|
|
||||||
// Logger is the logger that will be used to log messages.
|
|
||||||
Logger Logger
|
|
||||||
|
|
||||||
// Determines whether logging of deprecated endpoints usage is enabled.
|
|
||||||
LogDeprecated bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o Options) getEndpointVariant(service string) (v endpointVariant) {
|
|
||||||
const s3 = "s3"
|
|
||||||
const s3Control = "s3-control"
|
|
||||||
|
|
||||||
if (o.UseDualStackEndpoint == DualStackEndpointStateEnabled) ||
|
|
||||||
((service == s3 || service == s3Control) && (o.UseDualStackEndpoint == DualStackEndpointStateUnset && o.UseDualStack)) {
|
|
||||||
v |= dualStackVariant
|
|
||||||
}
|
|
||||||
if o.UseFIPSEndpoint == FIPSEndpointStateEnabled {
|
|
||||||
v |= fipsVariant
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// EC2IMDSEndpointModeState is an enum configuration variable describing the client endpoint mode.
|
|
||||||
type EC2IMDSEndpointModeState uint
|
|
||||||
|
|
||||||
// Enumeration values for EC2IMDSEndpointModeState
|
|
||||||
const (
|
|
||||||
EC2IMDSEndpointModeStateUnset EC2IMDSEndpointModeState = iota
|
|
||||||
EC2IMDSEndpointModeStateIPv4
|
|
||||||
EC2IMDSEndpointModeStateIPv6
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetFromString sets the EC2IMDSEndpointModeState based on the provided string value. Unknown values will default to EC2IMDSEndpointModeStateUnset
|
|
||||||
func (e *EC2IMDSEndpointModeState) SetFromString(v string) error {
|
|
||||||
v = strings.TrimSpace(v)
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case len(v) == 0:
|
|
||||||
*e = EC2IMDSEndpointModeStateUnset
|
|
||||||
case strings.EqualFold(v, "IPv6"):
|
|
||||||
*e = EC2IMDSEndpointModeStateIPv6
|
|
||||||
case strings.EqualFold(v, "IPv4"):
|
|
||||||
*e = EC2IMDSEndpointModeStateIPv4
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unknown EC2 IMDS endpoint mode, must be either IPv6 or IPv4")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// STSRegionalEndpoint is an enum for the states of the STS Regional Endpoint
|
|
||||||
// options.
|
|
||||||
type STSRegionalEndpoint int
|
|
||||||
|
|
||||||
func (e STSRegionalEndpoint) String() string {
|
|
||||||
switch e {
|
|
||||||
case LegacySTSEndpoint:
|
|
||||||
return "legacy"
|
|
||||||
case RegionalSTSEndpoint:
|
|
||||||
return "regional"
|
|
||||||
case UnsetSTSEndpoint:
|
|
||||||
return ""
|
|
||||||
default:
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
|
|
||||||
// UnsetSTSEndpoint represents that STS Regional Endpoint flag is not specified.
|
|
||||||
UnsetSTSEndpoint STSRegionalEndpoint = iota
|
|
||||||
|
|
||||||
// LegacySTSEndpoint represents when STS Regional Endpoint flag is specified
|
|
||||||
// to use legacy endpoints.
|
|
||||||
LegacySTSEndpoint
|
|
||||||
|
|
||||||
// RegionalSTSEndpoint represents when STS Regional Endpoint flag is specified
|
|
||||||
// to use regional endpoints.
|
|
||||||
RegionalSTSEndpoint
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetSTSRegionalEndpoint function returns the STSRegionalEndpointFlag based
|
|
||||||
// on the input string provided in env config or shared config by the user.
|
|
||||||
//
|
|
||||||
// `legacy`, `regional` are the only case-insensitive valid strings for
|
|
||||||
// resolving the STS regional Endpoint flag.
|
|
||||||
func GetSTSRegionalEndpoint(s string) (STSRegionalEndpoint, error) {
|
|
||||||
switch {
|
|
||||||
case strings.EqualFold(s, "legacy"):
|
|
||||||
return LegacySTSEndpoint, nil
|
|
||||||
case strings.EqualFold(s, "regional"):
|
|
||||||
return RegionalSTSEndpoint, nil
|
|
||||||
default:
|
|
||||||
return UnsetSTSEndpoint, fmt.Errorf("unable to resolve the value of STSRegionalEndpoint for %v", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// S3UsEast1RegionalEndpoint is an enum for the states of the S3 us-east-1
|
|
||||||
// Regional Endpoint options.
|
|
||||||
type S3UsEast1RegionalEndpoint int
|
|
||||||
|
|
||||||
func (e S3UsEast1RegionalEndpoint) String() string {
|
|
||||||
switch e {
|
|
||||||
case LegacyS3UsEast1Endpoint:
|
|
||||||
return "legacy"
|
|
||||||
case RegionalS3UsEast1Endpoint:
|
|
||||||
return "regional"
|
|
||||||
case UnsetS3UsEast1Endpoint:
|
|
||||||
return ""
|
|
||||||
default:
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
|
|
||||||
// UnsetS3UsEast1Endpoint represents that S3 Regional Endpoint flag is not
|
|
||||||
// specified.
|
|
||||||
UnsetS3UsEast1Endpoint S3UsEast1RegionalEndpoint = iota
|
|
||||||
|
|
||||||
// LegacyS3UsEast1Endpoint represents when S3 Regional Endpoint flag is
|
|
||||||
// specified to use legacy endpoints.
|
|
||||||
LegacyS3UsEast1Endpoint
|
|
||||||
|
|
||||||
// RegionalS3UsEast1Endpoint represents when S3 Regional Endpoint flag is
|
|
||||||
// specified to use regional endpoints.
|
|
||||||
RegionalS3UsEast1Endpoint
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetS3UsEast1RegionalEndpoint function returns the S3UsEast1RegionalEndpointFlag based
|
|
||||||
// on the input string provided in env config or shared config by the user.
|
|
||||||
//
|
|
||||||
// `legacy`, `regional` are the only case-insensitive valid strings for
|
|
||||||
// resolving the S3 regional Endpoint flag.
|
|
||||||
func GetS3UsEast1RegionalEndpoint(s string) (S3UsEast1RegionalEndpoint, error) {
|
|
||||||
switch {
|
|
||||||
case strings.EqualFold(s, "legacy"):
|
|
||||||
return LegacyS3UsEast1Endpoint, nil
|
|
||||||
case strings.EqualFold(s, "regional"):
|
|
||||||
return RegionalS3UsEast1Endpoint, nil
|
|
||||||
default:
|
|
||||||
return UnsetS3UsEast1Endpoint,
|
|
||||||
fmt.Errorf("unable to resolve the value of S3UsEast1RegionalEndpoint for %v", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set combines all of the option functions together.
|
|
||||||
func (o *Options) Set(optFns ...func(*Options)) {
|
|
||||||
for _, fn := range optFns {
|
|
||||||
fn(o)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DisableSSLOption sets the DisableSSL options. Can be used as a functional
|
|
||||||
// option when resolving endpoints.
|
|
||||||
func DisableSSLOption(o *Options) {
|
|
||||||
o.DisableSSL = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// UseDualStackOption sets the UseDualStack option. Can be used as a functional
|
|
||||||
// option when resolving endpoints.
|
|
||||||
//
|
|
||||||
// Deprecated: UseDualStackEndpointOption should be used to enable usage of a service's dual-stack endpoint.
|
|
||||||
// When DualStackEndpointState is set to a non-zero value it takes higher precedence then this option.
|
|
||||||
func UseDualStackOption(o *Options) {
|
|
||||||
o.UseDualStack = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// UseDualStackEndpointOption sets the UseDualStackEndpoint option to enabled. Can be used as a functional
|
|
||||||
// option when resolving endpoints.
|
|
||||||
func UseDualStackEndpointOption(o *Options) {
|
|
||||||
o.UseDualStackEndpoint = DualStackEndpointStateEnabled
|
|
||||||
}
|
|
||||||
|
|
||||||
// UseFIPSEndpointOption sets the UseFIPSEndpoint option to enabled. Can be used as a functional
|
|
||||||
// option when resolving endpoints.
|
|
||||||
func UseFIPSEndpointOption(o *Options) {
|
|
||||||
o.UseFIPSEndpoint = FIPSEndpointStateEnabled
|
|
||||||
}
|
|
||||||
|
|
||||||
// StrictMatchingOption sets the StrictMatching option. Can be used as a functional
|
|
||||||
// option when resolving endpoints.
|
|
||||||
func StrictMatchingOption(o *Options) {
|
|
||||||
o.StrictMatching = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResolveUnknownServiceOption sets the ResolveUnknownService option. Can be used
|
|
||||||
// as a functional option when resolving endpoints.
|
|
||||||
func ResolveUnknownServiceOption(o *Options) {
|
|
||||||
o.ResolveUnknownService = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// STSRegionalEndpointOption enables the STS endpoint resolver behavior to resolve
|
|
||||||
// STS endpoint to their regional endpoint, instead of the global endpoint.
|
|
||||||
func STSRegionalEndpointOption(o *Options) {
|
|
||||||
o.STSRegionalEndpoint = RegionalSTSEndpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Resolver provides the interface for functionality to resolve endpoints.
|
|
||||||
// The build in Partition and DefaultResolver return value satisfy this interface.
|
|
||||||
type Resolver interface {
|
|
||||||
EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResolverFunc is a helper utility that wraps a function so it satisfies the
|
|
||||||
// Resolver interface. This is useful when you want to add additional endpoint
|
|
||||||
// resolving logic, or stub out specific endpoints with custom values.
|
|
||||||
type ResolverFunc func(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
|
|
||||||
|
|
||||||
// EndpointFor wraps the ResolverFunc function to satisfy the Resolver interface.
|
|
||||||
func (fn ResolverFunc) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
|
||||||
return fn(service, region, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
var schemeRE = regexp.MustCompile("^([^:]+)://")
|
|
||||||
|
|
||||||
// AddScheme adds the HTTP or HTTPS schemes to a endpoint URL if there is no
|
|
||||||
// scheme. If disableSSL is true HTTP will set HTTP instead of the default HTTPS.
|
|
||||||
//
|
|
||||||
// If disableSSL is set, it will only set the URL's scheme if the URL does not
|
|
||||||
// contain a scheme.
|
|
||||||
func AddScheme(endpoint string, disableSSL bool) string {
|
|
||||||
if !schemeRE.MatchString(endpoint) {
|
|
||||||
scheme := "https"
|
|
||||||
if disableSSL {
|
|
||||||
scheme = "http"
|
|
||||||
}
|
|
||||||
endpoint = fmt.Sprintf("%s://%s", scheme, endpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
return endpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnumPartitions a provides a way to retrieve the underlying partitions that
|
|
||||||
// make up the SDK's default Resolver, or any resolver decoded from a model
|
|
||||||
// file.
|
|
||||||
//
|
|
||||||
// Use this interface with DefaultResolver and DecodeModels to get the list of
|
|
||||||
// Partitions.
|
|
||||||
type EnumPartitions interface {
|
|
||||||
Partitions() []Partition
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegionsForService returns a map of regions for the partition and service.
|
|
||||||
// If either the partition or service does not exist false will be returned
|
|
||||||
// as the second parameter.
|
|
||||||
//
|
|
||||||
// This example shows how to get the regions for DynamoDB in the AWS partition.
|
|
||||||
//
|
|
||||||
// rs, exists := endpoints.RegionsForService(endpoints.DefaultPartitions(), endpoints.AwsPartitionID, endpoints.DynamodbServiceID)
|
|
||||||
//
|
|
||||||
// This is equivalent to using the partition directly.
|
|
||||||
//
|
|
||||||
// rs := endpoints.AwsPartition().Services()[endpoints.DynamodbServiceID].Regions()
|
|
||||||
func RegionsForService(ps []Partition, partitionID, serviceID string) (map[string]Region, bool) {
|
|
||||||
for _, p := range ps {
|
|
||||||
if p.ID() != partitionID {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, ok := p.p.Services[serviceID]; !(ok || serviceID == Ec2metadataServiceID) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
s := Service{
|
|
||||||
id: serviceID,
|
|
||||||
p: p.p,
|
|
||||||
}
|
|
||||||
return s.Regions(), true
|
|
||||||
}
|
|
||||||
|
|
||||||
return map[string]Region{}, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionForRegion returns the first partition which includes the region
|
|
||||||
// passed in. This includes both known regions and regions which match
|
|
||||||
// a pattern supported by the partition which may include regions that are
|
|
||||||
// not explicitly known by the partition. Use the Regions method of the
|
|
||||||
// returned Partition if explicit support is needed.
|
|
||||||
func PartitionForRegion(ps []Partition, regionID string) (Partition, bool) {
|
|
||||||
for _, p := range ps {
|
|
||||||
if _, ok := p.p.Regions[regionID]; ok || p.p.RegionRegex.MatchString(regionID) {
|
|
||||||
return p, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Partition{}, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Partition provides the ability to enumerate the partition's regions
|
|
||||||
// and services.
|
|
||||||
type Partition struct {
|
|
||||||
id, dnsSuffix string
|
|
||||||
p *partition
|
|
||||||
}
|
|
||||||
|
|
||||||
// DNSSuffix returns the base domain name of the partition.
|
|
||||||
func (p Partition) DNSSuffix() string { return p.dnsSuffix }
|
|
||||||
|
|
||||||
// ID returns the identifier of the partition.
|
|
||||||
func (p Partition) ID() string { return p.id }
|
|
||||||
|
|
||||||
// EndpointFor attempts to resolve the endpoint based on service and region.
|
|
||||||
// See Options for information on configuring how the endpoint is resolved.
|
|
||||||
//
|
|
||||||
// If the service cannot be found in the metadata the UnknownServiceError
|
|
||||||
// error will be returned. This validation will occur regardless if
|
|
||||||
// StrictMatching is enabled. To enable resolving unknown services set the
|
|
||||||
// "ResolveUnknownService" option to true. When StrictMatching is disabled
|
|
||||||
// this option allows the partition resolver to resolve a endpoint based on
|
|
||||||
// the service endpoint ID provided.
|
|
||||||
//
|
|
||||||
// When resolving endpoints you can choose to enable StrictMatching. This will
|
|
||||||
// require the provided service and region to be known by the partition.
|
|
||||||
// If the endpoint cannot be strictly resolved an error will be returned. This
|
|
||||||
// mode is useful to ensure the endpoint resolved is valid. Without
|
|
||||||
// StrictMatching enabled the endpoint returned may look valid but may not work.
|
|
||||||
// StrictMatching requires the SDK to be updated if you want to take advantage
|
|
||||||
// of new regions and services expansions.
|
|
||||||
//
|
|
||||||
// Errors that can be returned.
|
|
||||||
// - UnknownServiceError
|
|
||||||
// - UnknownEndpointError
|
|
||||||
func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
|
||||||
return p.p.EndpointFor(service, region, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regions returns a map of Regions indexed by their ID. This is useful for
|
|
||||||
// enumerating over the regions in a partition.
|
|
||||||
func (p Partition) Regions() map[string]Region {
|
|
||||||
rs := make(map[string]Region, len(p.p.Regions))
|
|
||||||
for id, r := range p.p.Regions {
|
|
||||||
rs[id] = Region{
|
|
||||||
id: id,
|
|
||||||
desc: r.Description,
|
|
||||||
p: p.p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
// Services returns a map of Service indexed by their ID. This is useful for
|
|
||||||
// enumerating over the services in a partition.
|
|
||||||
func (p Partition) Services() map[string]Service {
|
|
||||||
ss := make(map[string]Service, len(p.p.Services))
|
|
||||||
|
|
||||||
for id := range p.p.Services {
|
|
||||||
ss[id] = Service{
|
|
||||||
id: id,
|
|
||||||
p: p.p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since we have removed the customization that injected this into the model
|
|
||||||
// we still need to pretend that this is a modeled service.
|
|
||||||
if _, ok := ss[Ec2metadataServiceID]; !ok {
|
|
||||||
ss[Ec2metadataServiceID] = Service{
|
|
||||||
id: Ec2metadataServiceID,
|
|
||||||
p: p.p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Region provides information about a region, and ability to resolve an
|
|
||||||
// endpoint from the context of a region, given a service.
|
|
||||||
type Region struct {
|
|
||||||
id, desc string
|
|
||||||
p *partition
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns the region's identifier.
|
|
||||||
func (r Region) ID() string { return r.id }
|
|
||||||
|
|
||||||
// Description returns the region's description. The region description
|
|
||||||
// is free text, it can be empty, and it may change between SDK releases.
|
|
||||||
func (r Region) Description() string { return r.desc }
|
|
||||||
|
|
||||||
// ResolveEndpoint resolves an endpoint from the context of the region given
|
|
||||||
// a service. See Partition.EndpointFor for usage and errors that can be returned.
|
|
||||||
func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
|
||||||
return r.p.EndpointFor(service, r.id, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Services returns a list of all services that are known to be in this region.
|
|
||||||
func (r Region) Services() map[string]Service {
|
|
||||||
ss := map[string]Service{}
|
|
||||||
for id, s := range r.p.Services {
|
|
||||||
if _, ok := s.Endpoints[endpointKey{Region: r.id}]; ok {
|
|
||||||
ss[id] = Service{
|
|
||||||
id: id,
|
|
||||||
p: r.p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Service provides information about a service, and ability to resolve an
|
|
||||||
// endpoint from the context of a service, given a region.
|
|
||||||
type Service struct {
|
|
||||||
id string
|
|
||||||
p *partition
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns the identifier for the service.
|
|
||||||
func (s Service) ID() string { return s.id }
|
|
||||||
|
|
||||||
// ResolveEndpoint resolves an endpoint from the context of a service given
|
|
||||||
// a region. See Partition.EndpointFor for usage and errors that can be returned.
|
|
||||||
func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
|
||||||
return s.p.EndpointFor(s.id, region, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regions returns a map of Regions that the service is present in.
|
|
||||||
//
|
|
||||||
// A region is the AWS region the service exists in. Whereas a Endpoint is
|
|
||||||
// an URL that can be resolved to a instance of a service.
|
|
||||||
func (s Service) Regions() map[string]Region {
|
|
||||||
rs := map[string]Region{}
|
|
||||||
|
|
||||||
service, ok := s.p.Services[s.id]
|
|
||||||
|
|
||||||
// Since ec2metadata customization has been removed we need to check
|
|
||||||
// if it was defined in non-standard endpoints.json file. If it's not
|
|
||||||
// then we can return the empty map as there is no regional-endpoints for IMDS.
|
|
||||||
// Otherwise, we iterate need to iterate the non-standard model.
|
|
||||||
if s.id == Ec2metadataServiceID && !ok {
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
for id := range service.Endpoints {
|
|
||||||
if id.Variant != 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if r, ok := s.p.Regions[id.Region]; ok {
|
|
||||||
rs[id.Region] = Region{
|
|
||||||
id: id.Region,
|
|
||||||
desc: r.Description,
|
|
||||||
p: s.p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
// Endpoints returns a map of Endpoints indexed by their ID for all known
|
|
||||||
// endpoints for a service.
|
|
||||||
//
|
|
||||||
// A region is the AWS region the service exists in. Whereas a Endpoint is
|
|
||||||
// an URL that can be resolved to a instance of a service.
|
|
||||||
func (s Service) Endpoints() map[string]Endpoint {
|
|
||||||
es := make(map[string]Endpoint, len(s.p.Services[s.id].Endpoints))
|
|
||||||
for id := range s.p.Services[s.id].Endpoints {
|
|
||||||
if id.Variant != 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
es[id.Region] = Endpoint{
|
|
||||||
id: id.Region,
|
|
||||||
serviceID: s.id,
|
|
||||||
p: s.p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return es
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Endpoint provides information about endpoints, and provides the ability
|
|
||||||
// to resolve that endpoint for the service, and the region the endpoint
|
|
||||||
// represents.
|
|
||||||
type Endpoint struct {
|
|
||||||
id string
|
|
||||||
serviceID string
|
|
||||||
p *partition
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns the identifier for an endpoint.
|
|
||||||
func (e Endpoint) ID() string { return e.id }
|
|
||||||
|
|
||||||
// ServiceID returns the identifier the endpoint belongs to.
|
|
||||||
func (e Endpoint) ServiceID() string { return e.serviceID }
|
|
||||||
|
|
||||||
// ResolveEndpoint resolves an endpoint from the context of a service and
|
|
||||||
// region the endpoint represents. See Partition.EndpointFor for usage and
|
|
||||||
// errors that can be returned.
|
|
||||||
func (e Endpoint) ResolveEndpoint(opts ...func(*Options)) (ResolvedEndpoint, error) {
|
|
||||||
return e.p.EndpointFor(e.serviceID, e.id, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A ResolvedEndpoint is an endpoint that has been resolved based on a partition
|
|
||||||
// service, and region.
|
|
||||||
type ResolvedEndpoint struct {
|
|
||||||
// The endpoint URL
|
|
||||||
URL string
|
|
||||||
|
|
||||||
// The endpoint partition
|
|
||||||
PartitionID string
|
|
||||||
|
|
||||||
// The region that should be used for signing requests.
|
|
||||||
SigningRegion string
|
|
||||||
|
|
||||||
// The service name that should be used for signing requests.
|
|
||||||
SigningName string
|
|
||||||
|
|
||||||
// States that the signing name for this endpoint was derived from metadata
|
|
||||||
// passed in, but was not explicitly modeled.
|
|
||||||
SigningNameDerived bool
|
|
||||||
|
|
||||||
// The signing method that should be used for signing requests.
|
|
||||||
SigningMethod string
|
|
||||||
}
|
|
||||||
|
|
||||||
// So that the Error interface type can be included as an anonymous field
|
|
||||||
// in the requestError struct and not conflict with the error.Error() method.
|
|
||||||
type awsError awserr.Error
|
|
||||||
|
|
||||||
// A EndpointNotFoundError is returned when in StrictMatching mode, and the
|
|
||||||
// endpoint for the service and region cannot be found in any of the partitions.
|
|
||||||
type EndpointNotFoundError struct {
|
|
||||||
awsError
|
|
||||||
Partition string
|
|
||||||
Service string
|
|
||||||
Region string
|
|
||||||
}
|
|
||||||
|
|
||||||
// A UnknownServiceError is returned when the service does not resolve to an
|
|
||||||
// endpoint. Includes a list of all known services for the partition. Returned
|
|
||||||
// when a partition does not support the service.
|
|
||||||
type UnknownServiceError struct {
|
|
||||||
awsError
|
|
||||||
Partition string
|
|
||||||
Service string
|
|
||||||
Known []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUnknownServiceError builds and returns UnknownServiceError.
|
|
||||||
func NewUnknownServiceError(p, s string, known []string) UnknownServiceError {
|
|
||||||
return UnknownServiceError{
|
|
||||||
awsError: awserr.New("UnknownServiceError",
|
|
||||||
"could not resolve endpoint for unknown service", nil),
|
|
||||||
Partition: p,
|
|
||||||
Service: s,
|
|
||||||
Known: known,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
func (e UnknownServiceError) Error() string {
|
|
||||||
extra := fmt.Sprintf("partition: %q, service: %q",
|
|
||||||
e.Partition, e.Service)
|
|
||||||
if len(e.Known) > 0 {
|
|
||||||
extra += fmt.Sprintf(", known: %v", e.Known)
|
|
||||||
}
|
|
||||||
return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
func (e UnknownServiceError) String() string {
|
|
||||||
return e.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// A UnknownEndpointError is returned when in StrictMatching mode and the
|
|
||||||
// service is valid, but the region does not resolve to an endpoint. Includes
|
|
||||||
// a list of all known endpoints for the service.
|
|
||||||
type UnknownEndpointError struct {
|
|
||||||
awsError
|
|
||||||
Partition string
|
|
||||||
Service string
|
|
||||||
Region string
|
|
||||||
Known []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUnknownEndpointError builds and returns UnknownEndpointError.
|
|
||||||
func NewUnknownEndpointError(p, s, r string, known []string) UnknownEndpointError {
|
|
||||||
return UnknownEndpointError{
|
|
||||||
awsError: awserr.New("UnknownEndpointError",
|
|
||||||
"could not resolve endpoint", nil),
|
|
||||||
Partition: p,
|
|
||||||
Service: s,
|
|
||||||
Region: r,
|
|
||||||
Known: known,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
func (e UnknownEndpointError) Error() string {
|
|
||||||
extra := fmt.Sprintf("partition: %q, service: %q, region: %q",
|
|
||||||
e.Partition, e.Service, e.Region)
|
|
||||||
if len(e.Known) > 0 {
|
|
||||||
extra += fmt.Sprintf(", known: %v", e.Known)
|
|
||||||
}
|
|
||||||
return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
func (e UnknownEndpointError) String() string {
|
|
||||||
return e.Error()
|
|
||||||
}
|
|
||||||
24
vendor/github.com/aws/aws-sdk-go/aws/endpoints/legacy_regions.go
generated
vendored
24
vendor/github.com/aws/aws-sdk-go/aws/endpoints/legacy_regions.go
generated
vendored
@ -1,24 +0,0 @@
|
|||||||
package endpoints
|
|
||||||
|
|
||||||
var legacyGlobalRegions = map[string]map[string]struct{}{
|
|
||||||
"sts": {
|
|
||||||
"ap-northeast-1": {},
|
|
||||||
"ap-south-1": {},
|
|
||||||
"ap-southeast-1": {},
|
|
||||||
"ap-southeast-2": {},
|
|
||||||
"ca-central-1": {},
|
|
||||||
"eu-central-1": {},
|
|
||||||
"eu-north-1": {},
|
|
||||||
"eu-west-1": {},
|
|
||||||
"eu-west-2": {},
|
|
||||||
"eu-west-3": {},
|
|
||||||
"sa-east-1": {},
|
|
||||||
"us-east-1": {},
|
|
||||||
"us-east-2": {},
|
|
||||||
"us-west-1": {},
|
|
||||||
"us-west-2": {},
|
|
||||||
},
|
|
||||||
"s3": {
|
|
||||||
"us-east-1": {},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
594
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go
generated
vendored
594
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go
generated
vendored
@ -1,594 +0,0 @@
|
|||||||
package endpoints
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
ec2MetadataEndpointIPv6 = "http://[fd00:ec2::254]/latest"
|
|
||||||
ec2MetadataEndpointIPv4 = "http://169.254.169.254/latest"
|
|
||||||
)
|
|
||||||
|
|
||||||
const dnsSuffixTemplateKey = "{dnsSuffix}"
|
|
||||||
|
|
||||||
// defaultKey is a compound map key of a variant and other values.
|
|
||||||
type defaultKey struct {
|
|
||||||
Variant endpointVariant
|
|
||||||
ServiceVariant serviceVariant
|
|
||||||
}
|
|
||||||
|
|
||||||
// endpointKey is a compound map key of a region and associated variant value.
|
|
||||||
type endpointKey struct {
|
|
||||||
Region string
|
|
||||||
Variant endpointVariant
|
|
||||||
}
|
|
||||||
|
|
||||||
// endpointVariant is a bit field to describe the endpoints attributes.
|
|
||||||
type endpointVariant uint64
|
|
||||||
|
|
||||||
// serviceVariant is a bit field to describe the service endpoint attributes.
|
|
||||||
type serviceVariant uint64
|
|
||||||
|
|
||||||
const (
|
|
||||||
// fipsVariant indicates that the endpoint is FIPS capable.
|
|
||||||
fipsVariant endpointVariant = 1 << (64 - 1 - iota)
|
|
||||||
|
|
||||||
// dualStackVariant indicates that the endpoint is DualStack capable.
|
|
||||||
dualStackVariant
|
|
||||||
)
|
|
||||||
|
|
||||||
var regionValidationRegex = regexp.MustCompile(`^[[:alnum:]]([[:alnum:]\-]*[[:alnum:]])?$`)
|
|
||||||
|
|
||||||
type partitions []partition
|
|
||||||
|
|
||||||
func (ps partitions) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
|
||||||
var opt Options
|
|
||||||
opt.Set(opts...)
|
|
||||||
|
|
||||||
if len(opt.ResolvedRegion) > 0 {
|
|
||||||
region = opt.ResolvedRegion
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < len(ps); i++ {
|
|
||||||
if !ps[i].canResolveEndpoint(service, region, opt) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
return ps[i].EndpointFor(service, region, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If loose matching fallback to first partition format to use
|
|
||||||
// when resolving the endpoint.
|
|
||||||
if !opt.StrictMatching && len(ps) > 0 {
|
|
||||||
return ps[0].EndpointFor(service, region, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResolvedEndpoint{}, NewUnknownEndpointError("all partitions", service, region, []string{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Partitions satisfies the EnumPartitions interface and returns a list
|
|
||||||
// of Partitions representing each partition represented in the SDK's
|
|
||||||
// endpoints model.
|
|
||||||
func (ps partitions) Partitions() []Partition {
|
|
||||||
parts := make([]Partition, 0, len(ps))
|
|
||||||
for i := 0; i < len(ps); i++ {
|
|
||||||
parts = append(parts, ps[i].Partition())
|
|
||||||
}
|
|
||||||
|
|
||||||
return parts
|
|
||||||
}
|
|
||||||
|
|
||||||
type endpointWithVariants struct {
|
|
||||||
endpoint
|
|
||||||
Variants []endpointWithTags `json:"variants"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type endpointWithTags struct {
|
|
||||||
endpoint
|
|
||||||
Tags []string `json:"tags"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type endpointDefaults map[defaultKey]endpoint
|
|
||||||
|
|
||||||
func (p *endpointDefaults) UnmarshalJSON(data []byte) error {
|
|
||||||
if *p == nil {
|
|
||||||
*p = make(endpointDefaults)
|
|
||||||
}
|
|
||||||
|
|
||||||
var e endpointWithVariants
|
|
||||||
if err := json.Unmarshal(data, &e); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
(*p)[defaultKey{Variant: 0}] = e.endpoint
|
|
||||||
|
|
||||||
e.Hostname = ""
|
|
||||||
e.DNSSuffix = ""
|
|
||||||
|
|
||||||
for _, variant := range e.Variants {
|
|
||||||
endpointVariant, unknown := parseVariantTags(variant.Tags)
|
|
||||||
if unknown {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var ve endpoint
|
|
||||||
ve.mergeIn(e.endpoint)
|
|
||||||
ve.mergeIn(variant.endpoint)
|
|
||||||
|
|
||||||
(*p)[defaultKey{Variant: endpointVariant}] = ve
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseVariantTags(tags []string) (ev endpointVariant, unknown bool) {
|
|
||||||
if len(tags) == 0 {
|
|
||||||
unknown = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tag := range tags {
|
|
||||||
switch {
|
|
||||||
case strings.EqualFold("fips", tag):
|
|
||||||
ev |= fipsVariant
|
|
||||||
case strings.EqualFold("dualstack", tag):
|
|
||||||
ev |= dualStackVariant
|
|
||||||
default:
|
|
||||||
unknown = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ev, unknown
|
|
||||||
}
|
|
||||||
|
|
||||||
type partition struct {
|
|
||||||
ID string `json:"partition"`
|
|
||||||
Name string `json:"partitionName"`
|
|
||||||
DNSSuffix string `json:"dnsSuffix"`
|
|
||||||
RegionRegex regionRegex `json:"regionRegex"`
|
|
||||||
Defaults endpointDefaults `json:"defaults"`
|
|
||||||
Regions regions `json:"regions"`
|
|
||||||
Services services `json:"services"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p partition) Partition() Partition {
|
|
||||||
return Partition{
|
|
||||||
dnsSuffix: p.DNSSuffix,
|
|
||||||
id: p.ID,
|
|
||||||
p: &p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p partition) canResolveEndpoint(service, region string, options Options) bool {
|
|
||||||
s, hasService := p.Services[service]
|
|
||||||
_, hasEndpoint := s.Endpoints[endpointKey{
|
|
||||||
Region: region,
|
|
||||||
Variant: options.getEndpointVariant(service),
|
|
||||||
}]
|
|
||||||
|
|
||||||
if hasEndpoint && hasService {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if options.StrictMatching {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return p.RegionRegex.MatchString(region)
|
|
||||||
}
|
|
||||||
|
|
||||||
func allowLegacyEmptyRegion(service string) bool {
|
|
||||||
legacy := map[string]struct{}{
|
|
||||||
"budgets": {},
|
|
||||||
"ce": {},
|
|
||||||
"chime": {},
|
|
||||||
"cloudfront": {},
|
|
||||||
"ec2metadata": {},
|
|
||||||
"iam": {},
|
|
||||||
"importexport": {},
|
|
||||||
"organizations": {},
|
|
||||||
"route53": {},
|
|
||||||
"sts": {},
|
|
||||||
"support": {},
|
|
||||||
"waf": {},
|
|
||||||
}
|
|
||||||
|
|
||||||
_, allowed := legacy[service]
|
|
||||||
return allowed
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p partition) EndpointFor(service, region string, opts ...func(*Options)) (resolved ResolvedEndpoint, err error) {
|
|
||||||
var opt Options
|
|
||||||
opt.Set(opts...)
|
|
||||||
|
|
||||||
if len(opt.ResolvedRegion) > 0 {
|
|
||||||
region = opt.ResolvedRegion
|
|
||||||
}
|
|
||||||
|
|
||||||
s, hasService := p.Services[service]
|
|
||||||
|
|
||||||
if service == Ec2metadataServiceID && !hasService {
|
|
||||||
endpoint := getEC2MetadataEndpoint(p.ID, service, opt.EC2MetadataEndpointMode)
|
|
||||||
return endpoint, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(service) == 0 || !(hasService || opt.ResolveUnknownService) {
|
|
||||||
// Only return error if the resolver will not fallback to creating
|
|
||||||
// endpoint based on service endpoint ID passed in.
|
|
||||||
return resolved, NewUnknownServiceError(p.ID, service, serviceList(p.Services))
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(region) == 0 && allowLegacyEmptyRegion(service) && len(s.PartitionEndpoint) != 0 {
|
|
||||||
region = s.PartitionEndpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
if r, ok := isLegacyGlobalRegion(service, region, opt); ok {
|
|
||||||
region = r
|
|
||||||
}
|
|
||||||
|
|
||||||
variant := opt.getEndpointVariant(service)
|
|
||||||
|
|
||||||
endpoints := s.Endpoints
|
|
||||||
|
|
||||||
serviceDefaults, hasServiceDefault := s.Defaults[defaultKey{Variant: variant}]
|
|
||||||
// If we searched for a variant which may have no explicit service defaults,
|
|
||||||
// then we need to inherit the standard service defaults except the hostname and dnsSuffix
|
|
||||||
if variant != 0 && !hasServiceDefault {
|
|
||||||
serviceDefaults = s.Defaults[defaultKey{}]
|
|
||||||
serviceDefaults.Hostname = ""
|
|
||||||
serviceDefaults.DNSSuffix = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
partitionDefaults, hasPartitionDefault := p.Defaults[defaultKey{Variant: variant}]
|
|
||||||
|
|
||||||
var dnsSuffix string
|
|
||||||
if len(serviceDefaults.DNSSuffix) > 0 {
|
|
||||||
dnsSuffix = serviceDefaults.DNSSuffix
|
|
||||||
} else if variant == 0 {
|
|
||||||
// For legacy reasons the partition dnsSuffix is not in the defaults, so if we looked for
|
|
||||||
// a non-variant endpoint then we need to set the dnsSuffix.
|
|
||||||
dnsSuffix = p.DNSSuffix
|
|
||||||
}
|
|
||||||
|
|
||||||
noDefaults := !hasServiceDefault && !hasPartitionDefault
|
|
||||||
|
|
||||||
e, hasEndpoint := s.endpointForRegion(region, endpoints, variant)
|
|
||||||
if len(region) == 0 || (!hasEndpoint && (opt.StrictMatching || noDefaults)) {
|
|
||||||
return resolved, NewUnknownEndpointError(p.ID, service, region, endpointList(endpoints, variant))
|
|
||||||
}
|
|
||||||
|
|
||||||
defs := []endpoint{partitionDefaults, serviceDefaults}
|
|
||||||
|
|
||||||
return e.resolve(service, p.ID, region, dnsSuffixTemplateKey, dnsSuffix, defs, opt)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getEC2MetadataEndpoint(partitionID, service string, mode EC2IMDSEndpointModeState) ResolvedEndpoint {
|
|
||||||
switch mode {
|
|
||||||
case EC2IMDSEndpointModeStateIPv6:
|
|
||||||
return ResolvedEndpoint{
|
|
||||||
URL: ec2MetadataEndpointIPv6,
|
|
||||||
PartitionID: partitionID,
|
|
||||||
SigningRegion: "aws-global",
|
|
||||||
SigningName: service,
|
|
||||||
SigningNameDerived: true,
|
|
||||||
SigningMethod: "v4",
|
|
||||||
}
|
|
||||||
case EC2IMDSEndpointModeStateIPv4:
|
|
||||||
fallthrough
|
|
||||||
default:
|
|
||||||
return ResolvedEndpoint{
|
|
||||||
URL: ec2MetadataEndpointIPv4,
|
|
||||||
PartitionID: partitionID,
|
|
||||||
SigningRegion: "aws-global",
|
|
||||||
SigningName: service,
|
|
||||||
SigningNameDerived: true,
|
|
||||||
SigningMethod: "v4",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func isLegacyGlobalRegion(service string, region string, opt Options) (string, bool) {
|
|
||||||
if opt.getEndpointVariant(service) != 0 {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
sts = "sts"
|
|
||||||
s3 = "s3"
|
|
||||||
awsGlobal = "aws-global"
|
|
||||||
)
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case service == sts && opt.STSRegionalEndpoint == RegionalSTSEndpoint:
|
|
||||||
return region, false
|
|
||||||
case service == s3 && opt.S3UsEast1RegionalEndpoint == RegionalS3UsEast1Endpoint:
|
|
||||||
return region, false
|
|
||||||
default:
|
|
||||||
if _, ok := legacyGlobalRegions[service][region]; ok {
|
|
||||||
return awsGlobal, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return region, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func serviceList(ss services) []string {
|
|
||||||
list := make([]string, 0, len(ss))
|
|
||||||
for k := range ss {
|
|
||||||
list = append(list, k)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
func endpointList(es serviceEndpoints, variant endpointVariant) []string {
|
|
||||||
list := make([]string, 0, len(es))
|
|
||||||
for k := range es {
|
|
||||||
if k.Variant != variant {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
list = append(list, k.Region)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
type regionRegex struct {
|
|
||||||
*regexp.Regexp
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rr *regionRegex) UnmarshalJSON(b []byte) (err error) {
|
|
||||||
// Strip leading and trailing quotes
|
|
||||||
regex, err := strconv.Unquote(string(b))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to strip quotes from regex, %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rr.Regexp, err = regexp.Compile(regex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to unmarshal region regex, %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type regions map[string]region
|
|
||||||
|
|
||||||
type region struct {
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type services map[string]service
|
|
||||||
|
|
||||||
type service struct {
|
|
||||||
PartitionEndpoint string `json:"partitionEndpoint"`
|
|
||||||
IsRegionalized boxedBool `json:"isRegionalized,omitempty"`
|
|
||||||
Defaults endpointDefaults `json:"defaults"`
|
|
||||||
Endpoints serviceEndpoints `json:"endpoints"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *service) endpointForRegion(region string, endpoints serviceEndpoints, variant endpointVariant) (endpoint, bool) {
|
|
||||||
if e, ok := endpoints[endpointKey{Region: region, Variant: variant}]; ok {
|
|
||||||
return e, true
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.IsRegionalized == boxedFalse {
|
|
||||||
return endpoints[endpointKey{Region: s.PartitionEndpoint, Variant: variant}], region == s.PartitionEndpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unable to find any matching endpoint, return
|
|
||||||
// blank that will be used for generic endpoint creation.
|
|
||||||
return endpoint{}, false
|
|
||||||
}
|
|
||||||
|
|
||||||
type serviceEndpoints map[endpointKey]endpoint
|
|
||||||
|
|
||||||
func (s *serviceEndpoints) UnmarshalJSON(data []byte) error {
|
|
||||||
if *s == nil {
|
|
||||||
*s = make(serviceEndpoints)
|
|
||||||
}
|
|
||||||
|
|
||||||
var regionToEndpoint map[string]endpointWithVariants
|
|
||||||
|
|
||||||
if err := json.Unmarshal(data, ®ionToEndpoint); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for region, e := range regionToEndpoint {
|
|
||||||
(*s)[endpointKey{Region: region}] = e.endpoint
|
|
||||||
|
|
||||||
e.Hostname = ""
|
|
||||||
e.DNSSuffix = ""
|
|
||||||
|
|
||||||
for _, variant := range e.Variants {
|
|
||||||
endpointVariant, unknown := parseVariantTags(variant.Tags)
|
|
||||||
if unknown {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var ve endpoint
|
|
||||||
ve.mergeIn(e.endpoint)
|
|
||||||
ve.mergeIn(variant.endpoint)
|
|
||||||
|
|
||||||
(*s)[endpointKey{Region: region, Variant: endpointVariant}] = ve
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type endpoint struct {
|
|
||||||
Hostname string `json:"hostname"`
|
|
||||||
Protocols []string `json:"protocols"`
|
|
||||||
CredentialScope credentialScope `json:"credentialScope"`
|
|
||||||
|
|
||||||
DNSSuffix string `json:"dnsSuffix"`
|
|
||||||
|
|
||||||
// Signature Version not used
|
|
||||||
SignatureVersions []string `json:"signatureVersions"`
|
|
||||||
|
|
||||||
// SSLCommonName not used.
|
|
||||||
SSLCommonName string `json:"sslCommonName"`
|
|
||||||
|
|
||||||
Deprecated boxedBool `json:"deprecated"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// isZero returns whether the endpoint structure is an empty (zero) value.
|
|
||||||
func (e endpoint) isZero() bool {
|
|
||||||
switch {
|
|
||||||
case len(e.Hostname) != 0:
|
|
||||||
return false
|
|
||||||
case len(e.Protocols) != 0:
|
|
||||||
return false
|
|
||||||
case e.CredentialScope != (credentialScope{}):
|
|
||||||
return false
|
|
||||||
case len(e.SignatureVersions) != 0:
|
|
||||||
return false
|
|
||||||
case len(e.SSLCommonName) != 0:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
defaultProtocol = "https"
|
|
||||||
defaultSigner = "v4"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
protocolPriority = []string{"https", "http"}
|
|
||||||
signerPriority = []string{"v4", "v2"}
|
|
||||||
)
|
|
||||||
|
|
||||||
func getByPriority(s []string, p []string, def string) string {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return def
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < len(p); i++ {
|
|
||||||
for j := 0; j < len(s); j++ {
|
|
||||||
if s[j] == p[i] {
|
|
||||||
return s[j]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return s[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e endpoint) resolve(service, partitionID, region, dnsSuffixTemplateVariable, dnsSuffix string, defs []endpoint, opts Options) (ResolvedEndpoint, error) {
|
|
||||||
var merged endpoint
|
|
||||||
for _, def := range defs {
|
|
||||||
merged.mergeIn(def)
|
|
||||||
}
|
|
||||||
merged.mergeIn(e)
|
|
||||||
e = merged
|
|
||||||
|
|
||||||
signingRegion := e.CredentialScope.Region
|
|
||||||
if len(signingRegion) == 0 {
|
|
||||||
signingRegion = region
|
|
||||||
}
|
|
||||||
|
|
||||||
signingName := e.CredentialScope.Service
|
|
||||||
var signingNameDerived bool
|
|
||||||
if len(signingName) == 0 {
|
|
||||||
signingName = service
|
|
||||||
signingNameDerived = true
|
|
||||||
}
|
|
||||||
|
|
||||||
hostname := e.Hostname
|
|
||||||
|
|
||||||
if !validateInputRegion(region) {
|
|
||||||
return ResolvedEndpoint{}, fmt.Errorf("invalid region identifier format provided")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(merged.DNSSuffix) > 0 {
|
|
||||||
dnsSuffix = merged.DNSSuffix
|
|
||||||
}
|
|
||||||
|
|
||||||
u := strings.Replace(hostname, "{service}", service, 1)
|
|
||||||
u = strings.Replace(u, "{region}", region, 1)
|
|
||||||
u = strings.Replace(u, dnsSuffixTemplateVariable, dnsSuffix, 1)
|
|
||||||
|
|
||||||
scheme := getEndpointScheme(e.Protocols, opts.DisableSSL)
|
|
||||||
u = fmt.Sprintf("%s://%s", scheme, u)
|
|
||||||
|
|
||||||
if e.Deprecated == boxedTrue && opts.LogDeprecated && opts.Logger != nil {
|
|
||||||
opts.Logger.Log(fmt.Sprintf("endpoint identifier %q, url %q marked as deprecated", region, u))
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResolvedEndpoint{
|
|
||||||
URL: u,
|
|
||||||
PartitionID: partitionID,
|
|
||||||
SigningRegion: signingRegion,
|
|
||||||
SigningName: signingName,
|
|
||||||
SigningNameDerived: signingNameDerived,
|
|
||||||
SigningMethod: getByPriority(e.SignatureVersions, signerPriority, defaultSigner),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getEndpointScheme(protocols []string, disableSSL bool) string {
|
|
||||||
if disableSSL {
|
|
||||||
return "http"
|
|
||||||
}
|
|
||||||
|
|
||||||
return getByPriority(protocols, protocolPriority, defaultProtocol)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *endpoint) mergeIn(other endpoint) {
|
|
||||||
if len(other.Hostname) > 0 {
|
|
||||||
e.Hostname = other.Hostname
|
|
||||||
}
|
|
||||||
if len(other.Protocols) > 0 {
|
|
||||||
e.Protocols = other.Protocols
|
|
||||||
}
|
|
||||||
if len(other.SignatureVersions) > 0 {
|
|
||||||
e.SignatureVersions = other.SignatureVersions
|
|
||||||
}
|
|
||||||
if len(other.CredentialScope.Region) > 0 {
|
|
||||||
e.CredentialScope.Region = other.CredentialScope.Region
|
|
||||||
}
|
|
||||||
if len(other.CredentialScope.Service) > 0 {
|
|
||||||
e.CredentialScope.Service = other.CredentialScope.Service
|
|
||||||
}
|
|
||||||
if len(other.SSLCommonName) > 0 {
|
|
||||||
e.SSLCommonName = other.SSLCommonName
|
|
||||||
}
|
|
||||||
if len(other.DNSSuffix) > 0 {
|
|
||||||
e.DNSSuffix = other.DNSSuffix
|
|
||||||
}
|
|
||||||
if other.Deprecated != boxedBoolUnset {
|
|
||||||
e.Deprecated = other.Deprecated
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type credentialScope struct {
|
|
||||||
Region string `json:"region"`
|
|
||||||
Service string `json:"service"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type boxedBool int
|
|
||||||
|
|
||||||
func (b *boxedBool) UnmarshalJSON(buf []byte) error {
|
|
||||||
v, err := strconv.ParseBool(string(buf))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if v {
|
|
||||||
*b = boxedTrue
|
|
||||||
} else {
|
|
||||||
*b = boxedFalse
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
boxedBoolUnset boxedBool = iota
|
|
||||||
boxedFalse
|
|
||||||
boxedTrue
|
|
||||||
)
|
|
||||||
|
|
||||||
func validateInputRegion(region string) bool {
|
|
||||||
return regionValidationRegex.MatchString(region)
|
|
||||||
}
|
|
||||||
412
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go
generated
vendored
412
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go
generated
vendored
@ -1,412 +0,0 @@
|
|||||||
//go:build codegen
|
|
||||||
// +build codegen
|
|
||||||
|
|
||||||
package endpoints
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"text/template"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A CodeGenOptions are the options for code generating the endpoints into
|
|
||||||
// Go code from the endpoints model definition.
|
|
||||||
type CodeGenOptions struct {
|
|
||||||
// Options for how the model will be decoded.
|
|
||||||
DecodeModelOptions DecodeModelOptions
|
|
||||||
|
|
||||||
// Disables code generation of the service endpoint prefix IDs defined in
|
|
||||||
// the model.
|
|
||||||
DisableGenerateServiceIDs bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set combines all of the option functions together
|
|
||||||
func (d *CodeGenOptions) Set(optFns ...func(*CodeGenOptions)) {
|
|
||||||
for _, fn := range optFns {
|
|
||||||
fn(d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CodeGenModel given a endpoints model file will decode it and attempt to
|
|
||||||
// generate Go code from the model definition. Error will be returned if
|
|
||||||
// the code is unable to be generated, or decoded.
|
|
||||||
func CodeGenModel(modelFile io.Reader, outFile io.Writer, optFns ...func(*CodeGenOptions)) error {
|
|
||||||
var opts CodeGenOptions
|
|
||||||
opts.Set(optFns...)
|
|
||||||
|
|
||||||
resolver, err := DecodeModel(modelFile, func(d *DecodeModelOptions) {
|
|
||||||
*d = opts.DecodeModelOptions
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
v := struct {
|
|
||||||
Resolver
|
|
||||||
CodeGenOptions
|
|
||||||
}{
|
|
||||||
Resolver: resolver,
|
|
||||||
CodeGenOptions: opts,
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpl := template.Must(template.New("tmpl").Funcs(funcMap).Parse(v3Tmpl))
|
|
||||||
if err := tmpl.ExecuteTemplate(outFile, "defaults", v); err != nil {
|
|
||||||
return fmt.Errorf("failed to execute template, %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func toSymbol(v string) string {
|
|
||||||
out := []rune{}
|
|
||||||
for _, c := range strings.Title(v) {
|
|
||||||
if !(unicode.IsNumber(c) || unicode.IsLetter(c)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
out = append(out, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
func quoteString(v string) string {
|
|
||||||
return fmt.Sprintf("%q", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func regionConstName(p, r string) string {
|
|
||||||
return toSymbol(p) + toSymbol(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func partitionGetter(id string) string {
|
|
||||||
return fmt.Sprintf("%sPartition", toSymbol(id))
|
|
||||||
}
|
|
||||||
|
|
||||||
func partitionVarName(id string) string {
|
|
||||||
return fmt.Sprintf("%sPartition", strings.ToLower(toSymbol(id)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func listPartitionNames(ps partitions) string {
|
|
||||||
names := []string{}
|
|
||||||
switch len(ps) {
|
|
||||||
case 1:
|
|
||||||
return ps[0].Name
|
|
||||||
case 2:
|
|
||||||
return fmt.Sprintf("%s and %s", ps[0].Name, ps[1].Name)
|
|
||||||
default:
|
|
||||||
for i, p := range ps {
|
|
||||||
if i == len(ps)-1 {
|
|
||||||
names = append(names, "and "+p.Name)
|
|
||||||
} else {
|
|
||||||
names = append(names, p.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strings.Join(names, ", ")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func boxedBoolIfSet(msg string, v boxedBool) string {
|
|
||||||
switch v {
|
|
||||||
case boxedTrue:
|
|
||||||
return fmt.Sprintf(msg, "boxedTrue")
|
|
||||||
case boxedFalse:
|
|
||||||
return fmt.Sprintf(msg, "boxedFalse")
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringIfSet(msg, v string) string {
|
|
||||||
if len(v) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf(msg, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringSliceIfSet(msg string, vs []string) string {
|
|
||||||
if len(vs) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
names := []string{}
|
|
||||||
for _, v := range vs {
|
|
||||||
names = append(names, `"`+v+`"`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf(msg, strings.Join(names, ","))
|
|
||||||
}
|
|
||||||
|
|
||||||
func endpointIsSet(v endpoint) bool {
|
|
||||||
return !reflect.DeepEqual(v, endpoint{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func serviceSet(ps partitions) map[string]struct{} {
|
|
||||||
set := map[string]struct{}{}
|
|
||||||
for _, p := range ps {
|
|
||||||
for id := range p.Services {
|
|
||||||
set[id] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return set
|
|
||||||
}
|
|
||||||
|
|
||||||
func endpointVariantSetter(variant endpointVariant) (string, error) {
|
|
||||||
if variant == 0 {
|
|
||||||
return "0", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if variant > (fipsVariant | dualStackVariant) {
|
|
||||||
return "", fmt.Errorf("unknown endpoint variant")
|
|
||||||
}
|
|
||||||
|
|
||||||
var symbols []string
|
|
||||||
if variant&fipsVariant != 0 {
|
|
||||||
symbols = append(symbols, "fipsVariant")
|
|
||||||
}
|
|
||||||
if variant&dualStackVariant != 0 {
|
|
||||||
symbols = append(symbols, "dualStackVariant")
|
|
||||||
}
|
|
||||||
v := strings.Join(symbols, "|")
|
|
||||||
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func endpointKeySetter(e endpointKey) (string, error) {
|
|
||||||
var sb strings.Builder
|
|
||||||
sb.WriteString("endpointKey{\n")
|
|
||||||
sb.WriteString(fmt.Sprintf("Region: %q,\n", e.Region))
|
|
||||||
if e.Variant != 0 {
|
|
||||||
variantSetter, err := endpointVariantSetter(e.Variant)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
sb.WriteString(fmt.Sprintf("Variant: %s,\n", variantSetter))
|
|
||||||
}
|
|
||||||
sb.WriteString("}")
|
|
||||||
return sb.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func defaultKeySetter(e defaultKey) (string, error) {
|
|
||||||
var sb strings.Builder
|
|
||||||
sb.WriteString("defaultKey{\n")
|
|
||||||
if e.Variant != 0 {
|
|
||||||
variantSetter, err := endpointVariantSetter(e.Variant)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
sb.WriteString(fmt.Sprintf("Variant: %s,\n", variantSetter))
|
|
||||||
}
|
|
||||||
sb.WriteString("}")
|
|
||||||
return sb.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var funcMap = template.FuncMap{
|
|
||||||
"ToSymbol": toSymbol,
|
|
||||||
"QuoteString": quoteString,
|
|
||||||
"RegionConst": regionConstName,
|
|
||||||
"PartitionGetter": partitionGetter,
|
|
||||||
"PartitionVarName": partitionVarName,
|
|
||||||
"ListPartitionNames": listPartitionNames,
|
|
||||||
"BoxedBoolIfSet": boxedBoolIfSet,
|
|
||||||
"StringIfSet": stringIfSet,
|
|
||||||
"StringSliceIfSet": stringSliceIfSet,
|
|
||||||
"EndpointIsSet": endpointIsSet,
|
|
||||||
"ServicesSet": serviceSet,
|
|
||||||
"EndpointVariantSetter": endpointVariantSetter,
|
|
||||||
"EndpointKeySetter": endpointKeySetter,
|
|
||||||
"DefaultKeySetter": defaultKeySetter,
|
|
||||||
}
|
|
||||||
|
|
||||||
const v3Tmpl = `
|
|
||||||
{{ define "defaults" -}}
|
|
||||||
// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT.
|
|
||||||
|
|
||||||
package endpoints
|
|
||||||
|
|
||||||
import (
|
|
||||||
"regexp"
|
|
||||||
)
|
|
||||||
|
|
||||||
{{ template "partition consts" $.Resolver }}
|
|
||||||
|
|
||||||
{{ range $_, $partition := $.Resolver }}
|
|
||||||
{{ template "partition region consts" $partition }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ if not $.DisableGenerateServiceIDs -}}
|
|
||||||
{{ template "service consts" $.Resolver }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ template "endpoint resolvers" $.Resolver }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "partition consts" }}
|
|
||||||
// Partition identifiers
|
|
||||||
const (
|
|
||||||
{{ range $_, $p := . -}}
|
|
||||||
{{ ToSymbol $p.ID }}PartitionID = {{ QuoteString $p.ID }} // {{ $p.Name }} partition.
|
|
||||||
{{ end -}}
|
|
||||||
)
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "partition region consts" }}
|
|
||||||
// {{ .Name }} partition's regions.
|
|
||||||
const (
|
|
||||||
{{ range $id, $region := .Regions -}}
|
|
||||||
{{ ToSymbol $id }}RegionID = {{ QuoteString $id }} // {{ $region.Description }}.
|
|
||||||
{{ end -}}
|
|
||||||
)
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "service consts" }}
|
|
||||||
// Service identifiers
|
|
||||||
const (
|
|
||||||
{{ $serviceSet := ServicesSet . -}}
|
|
||||||
{{ range $id, $_ := $serviceSet -}}
|
|
||||||
{{ ToSymbol $id }}ServiceID = {{ QuoteString $id }} // {{ ToSymbol $id }}.
|
|
||||||
{{ end -}}
|
|
||||||
)
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "endpoint resolvers" }}
|
|
||||||
// DefaultResolver returns an Endpoint resolver that will be able
|
|
||||||
// to resolve endpoints for: {{ ListPartitionNames . }}.
|
|
||||||
//
|
|
||||||
// Use DefaultPartitions() to get the list of the default partitions.
|
|
||||||
func DefaultResolver() Resolver {
|
|
||||||
return defaultPartitions
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultPartitions returns a list of the partitions the SDK is bundled
|
|
||||||
// with. The available partitions are: {{ ListPartitionNames . }}.
|
|
||||||
//
|
|
||||||
// partitions := endpoints.DefaultPartitions
|
|
||||||
// for _, p := range partitions {
|
|
||||||
// // ... inspect partitions
|
|
||||||
// }
|
|
||||||
func DefaultPartitions() []Partition {
|
|
||||||
return defaultPartitions.Partitions()
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultPartitions = partitions{
|
|
||||||
{{ range $_, $partition := . -}}
|
|
||||||
{{ PartitionVarName $partition.ID }},
|
|
||||||
{{ end }}
|
|
||||||
}
|
|
||||||
|
|
||||||
{{ range $_, $partition := . -}}
|
|
||||||
{{ $name := PartitionGetter $partition.ID -}}
|
|
||||||
// {{ $name }} returns the Resolver for {{ $partition.Name }}.
|
|
||||||
func {{ $name }}() Partition {
|
|
||||||
return {{ PartitionVarName $partition.ID }}.Partition()
|
|
||||||
}
|
|
||||||
var {{ PartitionVarName $partition.ID }} = {{ template "gocode Partition" $partition }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ define "default partitions" }}
|
|
||||||
func DefaultPartitions() []Partition {
|
|
||||||
return []partition{
|
|
||||||
{{ range $_, $partition := . -}}
|
|
||||||
// {{ ToSymbol $partition.ID}}Partition(),
|
|
||||||
{{ end }}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ define "gocode Partition" -}}
|
|
||||||
partition{
|
|
||||||
{{ StringIfSet "ID: %q,\n" .ID -}}
|
|
||||||
{{ StringIfSet "Name: %q,\n" .Name -}}
|
|
||||||
{{ StringIfSet "DNSSuffix: %q,\n" .DNSSuffix -}}
|
|
||||||
RegionRegex: {{ template "gocode RegionRegex" .RegionRegex }},
|
|
||||||
{{ if (gt (len .Defaults) 0) -}}
|
|
||||||
Defaults: {{ template "gocode Defaults" .Defaults -}},
|
|
||||||
{{ end -}}
|
|
||||||
Regions: {{ template "gocode Regions" .Regions }},
|
|
||||||
Services: {{ template "gocode Services" .Services }},
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode RegionRegex" -}}
|
|
||||||
regionRegex{
|
|
||||||
Regexp: func() *regexp.Regexp{
|
|
||||||
reg, _ := regexp.Compile({{ QuoteString .Regexp.String }})
|
|
||||||
return reg
|
|
||||||
}(),
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Regions" -}}
|
|
||||||
regions{
|
|
||||||
{{ range $id, $region := . -}}
|
|
||||||
"{{ $id }}": {{ template "gocode Region" $region }},
|
|
||||||
{{ end -}}
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Region" -}}
|
|
||||||
region{
|
|
||||||
{{ StringIfSet "Description: %q,\n" .Description -}}
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Services" -}}
|
|
||||||
services{
|
|
||||||
{{ range $id, $service := . -}}
|
|
||||||
"{{ $id }}": {{ template "gocode Service" $service }},
|
|
||||||
{{ end }}
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Service" -}}
|
|
||||||
service{
|
|
||||||
{{ StringIfSet "PartitionEndpoint: %q,\n" .PartitionEndpoint -}}
|
|
||||||
{{ BoxedBoolIfSet "IsRegionalized: %s,\n" .IsRegionalized -}}
|
|
||||||
{{ if (gt (len .Defaults) 0) -}}
|
|
||||||
Defaults: {{ template "gocode Defaults" .Defaults -}},
|
|
||||||
{{ end -}}
|
|
||||||
{{ if .Endpoints -}}
|
|
||||||
Endpoints: {{ template "gocode Endpoints" .Endpoints }},
|
|
||||||
{{- end }}
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Defaults" -}}
|
|
||||||
endpointDefaults{
|
|
||||||
{{ range $id, $endpoint := . -}}
|
|
||||||
{{ DefaultKeySetter $id }}: {{ template "gocode Endpoint" $endpoint }},
|
|
||||||
{{ end }}
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Endpoints" -}}
|
|
||||||
serviceEndpoints{
|
|
||||||
{{ range $id, $endpoint := . -}}
|
|
||||||
{{ EndpointKeySetter $id }}: {{ template "gocode Endpoint" $endpoint }},
|
|
||||||
{{ end }}
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Endpoint" -}}
|
|
||||||
endpoint{
|
|
||||||
{{ StringIfSet "Hostname: %q,\n" .Hostname -}}
|
|
||||||
{{ StringIfSet "DNSSuffix: %q,\n" .DNSSuffix -}}
|
|
||||||
{{ StringIfSet "SSLCommonName: %q,\n" .SSLCommonName -}}
|
|
||||||
{{ StringSliceIfSet "Protocols: []string{%s},\n" .Protocols -}}
|
|
||||||
{{ StringSliceIfSet "SignatureVersions: []string{%s},\n" .SignatureVersions -}}
|
|
||||||
{{ if or .CredentialScope.Region .CredentialScope.Service -}}
|
|
||||||
CredentialScope: credentialScope{
|
|
||||||
{{ StringIfSet "Region: %q,\n" .CredentialScope.Region -}}
|
|
||||||
{{ StringIfSet "Service: %q,\n" .CredentialScope.Service -}}
|
|
||||||
},
|
|
||||||
{{- end }}
|
|
||||||
{{ BoxedBoolIfSet "Deprecated: %s,\n" .Deprecated -}}
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
`
|
|
||||||
13
vendor/github.com/aws/aws-sdk-go/aws/errors.go
generated
vendored
13
vendor/github.com/aws/aws-sdk-go/aws/errors.go
generated
vendored
@ -1,13 +0,0 @@
|
|||||||
package aws
|
|
||||||
|
|
||||||
import "github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrMissingRegion is an error that is returned if region configuration is
|
|
||||||
// not found.
|
|
||||||
ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil)
|
|
||||||
|
|
||||||
// ErrMissingEndpoint is an error that is returned if an endpoint cannot be
|
|
||||||
// resolved for a service.
|
|
||||||
ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil)
|
|
||||||
)
|
|
||||||
12
vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go
generated
vendored
12
vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
package aws
|
|
||||||
|
|
||||||
// JSONValue is a representation of a grab bag type that will be marshaled
|
|
||||||
// into a json string. This type can be used just like any other map.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// values := aws.JSONValue{
|
|
||||||
// "Foo": "Bar",
|
|
||||||
// }
|
|
||||||
// values["Baz"] = "Qux"
|
|
||||||
type JSONValue map[string]interface{}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user