Merge pull request #5 from fnproject/move_under_apps

Move all endpoints on v1 to be under apps
This commit is contained in:
Denis Makogon
2017-07-28 17:36:38 +03:00
committed by GitHub
4057 changed files with 1104178 additions and 640 deletions

View File

@@ -13,6 +13,7 @@ import (
"strings"
"github.com/Sirupsen/logrus"
"github.com/fnproject/fn/api/models"
"github.com/go-sql-driver/mysql"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
@@ -20,7 +21,6 @@ import (
_ "github.com/lib/pq"
"github.com/mattn/go-sqlite3"
_ "github.com/mattn/go-sqlite3"
"github.com/fnproject/fn/api/models"
)
// this aims to be an ANSI-SQL compliant package that uses only question
@@ -736,9 +736,12 @@ func buildFilterCallQuery(filter *models.CallFilter) (string, []interface{}) {
}
}
where("path=", filter.Path)
where("app_name=", filter.AppName)
if filter.Path != "" {
where("path=", filter.Path)
}
return b.String(), args
}

View File

@@ -3,38 +3,22 @@ package server
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/fnproject/fn/api"
"github.com/fnproject/fn/api/models"
"github.com/gin-gonic/gin"
)
func (s *Server) handleCallList(c *gin.Context) {
ctx := c.Request.Context()
appName, ok := c.MustGet(api.AppName).(string)
if ok && appName == "" {
name, ok := c.Get(api.AppName)
appName, conv := name.(string)
if ok && conv && appName == "" {
handleErrorResponse(c, models.ErrRoutesValidationMissingAppName)
return
}
_, err := s.Datastore.GetApp(c, appName)
if err != nil {
handleErrorResponse(c, err)
return
}
appRoute, ok := c.MustGet(api.Path).(string)
if ok && appRoute == "" {
handleErrorResponse(c, models.ErrRoutesValidationMissingPath)
return
}
_, err = s.Datastore.GetRoute(c, appName, appRoute)
if err != nil {
handleErrorResponse(c, err)
return
}
filter := models.CallFilter{AppName: appName, Path: appRoute}
filter := models.CallFilter{AppName: appName, Path: c.Query(api.CRoute)}
calls, err := s.Datastore.GetTasks(ctx, &filter)
if err != nil {
@@ -42,5 +26,21 @@ func (s *Server) handleCallList(c *gin.Context) {
return
}
if len(calls) == 0 {
_, err = s.Datastore.GetApp(c, appName)
if err != nil {
handleErrorResponse(c, err)
return
}
if filter.Path != "" {
_, err = s.Datastore.GetRoute(c, appName, filter.Path)
if err != nil {
handleErrorResponse(c, err)
return
}
}
}
c.JSON(http.StatusOK, fnCallsResponse{"Successfully listed calls", calls})
}

View File

@@ -14,12 +14,6 @@ import (
"github.com/Sirupsen/logrus"
"github.com/ccirello/supervisor"
"github.com/gin-gonic/gin"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/openzipkin/zipkin-go-opentracing"
"github.com/patrickmn/go-cache"
"github.com/spf13/viper"
"github.com/fnproject/fn/api"
"github.com/fnproject/fn/api/datastore"
"github.com/fnproject/fn/api/id"
@@ -28,6 +22,12 @@ import (
"github.com/fnproject/fn/api/mqs"
"github.com/fnproject/fn/api/runner"
"github.com/fnproject/fn/api/runner/common"
"github.com/gin-gonic/gin"
"github.com/opentracing/opentracing-go"
"github.com/opentracing/opentracing-go/ext"
"github.com/openzipkin/zipkin-go-opentracing"
"github.com/patrickmn/go-cache"
"github.com/spf13/viper"
)
const (
@@ -350,12 +350,6 @@ func (s *Server) bindHandlers(ctx context.Context) {
v1.PATCH("/apps/:app", s.handleAppUpdate)
v1.DELETE("/apps/:app", s.handleAppDelete)
v1.GET("/routes", s.handleRouteList)
v1.GET("/calls/:call", s.handleCallGet)
v1.GET("/calls/:call/log", s.handleCallLogGet)
v1.DELETE("/calls/:call/log", s.handleCallLogDelete)
apps := v1.Group("/apps/:app")
{
apps.GET("/routes", s.handleRouteList)
@@ -364,7 +358,13 @@ func (s *Server) bindHandlers(ctx context.Context) {
apps.PATCH("/routes/*route", s.handleRouteCreateOrUpdate)
apps.PUT("/routes/*route", s.handleRouteCreateOrUpdate)
apps.DELETE("/routes/*route", s.handleRouteDelete)
apps.GET("/calls/*route", s.handleCallList)
apps.GET("/calls", s.handleCallList)
apps.GET("/calls/:call", s.handleCallGet)
apps.GET("/calls/:call/log", s.handleCallLogGet)
apps.DELETE("/calls/:call/log", s.handleCallLogDelete)
}
}

View File

@@ -4,11 +4,11 @@ import (
"context"
"fmt"
client "github.com/fnproject/fn/cli/client"
fnclient "github.com/funcy/functions_go/client"
apicall "github.com/funcy/functions_go/client/call"
"github.com/funcy/functions_go/models"
"github.com/urfave/cli"
client "github.com/fnproject/fn/cli/client"
)
type callsCmd struct {
@@ -20,20 +20,20 @@ func calls() cli.Command {
return cli.Command{
Name: "calls",
Usage: "manage function calls",
Usage: "manage function calls for apps",
Subcommands: []cli.Command{
{
Name: "get",
Aliases: []string{"g"},
Usage: "get function call info",
ArgsUsage: "<call-id>",
Usage: "get function call info per app",
ArgsUsage: "<app> <call-id>",
Action: c.get,
},
{
Name: "list",
Aliases: []string{"l"},
Usage: "list all calls for specific route",
ArgsUsage: "<app> <route>",
Usage: "list all calls for specific app / route route is optional",
ArgsUsage: "<app> [route]",
Action: c.list,
},
},
@@ -56,16 +56,17 @@ func printCalls(calls []*models.Call) {
}
func (call *callsCmd) get(ctx *cli.Context) error {
callID := ctx.Args().Get(0)
params := apicall.GetCallsCallParams{
app, callID := ctx.Args().Get(0), ctx.Args().Get(1)
params := apicall.GetAppsAppCallsCallParams{
Call: callID,
App: app,
Context: context.Background(),
}
resp, err := call.client.Call.GetCallsCall(&params)
resp, err := call.client.Call.GetAppsAppCallsCall(&params)
if err != nil {
switch err.(type) {
case *apicall.GetCallsCallNotFound:
return fmt.Errorf("error: %v", err.(*apicall.GetCallsCallNotFound).Payload.Error.Message)
case *apicall.GetAppsAppCallsCallNotFound:
return fmt.Errorf("error: %v", err.(*apicall.GetAppsAppCallsCallNotFound).Payload.Error.Message)
}
return fmt.Errorf("unexpected error: %v", err)
@@ -75,13 +76,16 @@ func (call *callsCmd) get(ctx *cli.Context) error {
}
func (call *callsCmd) list(ctx *cli.Context) error {
app, route := ctx.Args().Get(0), ctx.Args().Get(1)
params := apicall.GetAppsAppCallsRouteParams{
app := ctx.Args().Get(0)
params := apicall.GetAppsAppCallsParams{
App: app,
Route: route,
Context: context.Background(),
}
resp, err := call.client.Call.GetAppsAppCallsRoute(&params)
if ctx.Args().Get(1) != "" {
route := ctx.Args().Get(1)
params.Route = &route
}
resp, err := call.client.Call.GetAppsAppCalls(&params)
if err != nil {
switch err.(type) {
case *apicall.GetCallsCallNotFound:

8
cli/glide.lock generated
View File

@@ -1,10 +1,10 @@
hash: 4cce7a5074b5b856c40bc5a97c7fac81546f835c42fd16aeff728f66ca65dd00
updated: 2017-07-19T15:40:45.33026105-07:00
hash: ac1f86c693857c54f425217105213884d89e2e3f1818804faba74b7eb5839b6c
updated: 2017-07-26T12:39:47.375642177-07:00
imports:
- name: github.com/asaskevich/govalidator
version: aa5cce4a76edb1a5acecab1870c17abbffb5419e
- name: github.com/aws/aws-sdk-go
version: 8da51c33f6001c4dda06a2561c2234be4cece1ed
version: 61b379ef486ea3baa55e10c358f3217f06e7b5ad
subpackages:
- aws
- aws/awserr
@@ -50,7 +50,7 @@ imports:
- name: github.com/docker/go-units
version: 0dadbb0345b35ec7ef35e228dabb8de89a65bf52
- name: github.com/funcy/functions_go
version: 601696a734d8df755f42bff262e699bb2eeb69b3
version: c540b7a8e1af8dad992a3b520175db85f8e53636
subpackages:
- client
- client/apps

View File

@@ -18,7 +18,7 @@ import:
subpackages:
- semver
- package: github.com/funcy/functions_go
version: ^0.1.34
version: ^0.1.35
subpackages:
- client
- client/apps

View File

@@ -1,3 +1,35 @@
Release v1.10.16 (2017-07-26)
===
### Service Client Updates
* `service/clouddirectory`: Updates service API and documentation
* Cloud Directory adds support for additional batch operations.
* `service/cloudformation`: Updates service API and documentation
* AWS CloudFormation StackSets enables you to manage stacks across multiple accounts and regions.
### SDK Enhancements
* `aws/signer/v4`: Optimize V4 signer's header duplicate space stripping. [#1417](https://github.com/aws/aws-sdk-go/pull/1417)
Release v1.10.15 (2017-07-24)
===
### Service Client Updates
* `service/appstream`: Updates service API, documentation, and waiters
* Amazon AppStream 2.0 image builders and fleets can now access applications and network resources that rely on Microsoft Active Directory (AD) for authentication and permissions. This new feature allows you to join your streaming instances to your AD, so you can use your existing AD user management tools.
* `service/ec2`: Updates service API and documentation
* Spot Fleet tagging capability allows customers to automatically tag instances launched by Spot Fleet. You can use this feature to label or distinguish instances created by distinct Spot Fleets. Tagging your EC2 instances also enables you to see instance cost allocation by tag in your AWS bill.
### SDK Bugs
* `aws/signer/v4`: Fix out of bounds panic in stripExcessSpaces [#1412](https://github.com/aws/aws-sdk-go/pull/1412)
* Fixes the out of bands panic in stripExcessSpaces caused by an incorrect calculation of the stripToIdx value. Simplified to code also.
* Fixes [#1411](https://github.com/aws/aws-sdk-go/issues/1411)
Release v1.10.14 (2017-07-20)
===
### Service Client Updates
* `service/elasticmapreduce`: Updates service API and documentation
* Amazon EMR now includes the ability to use a custom Amazon Linux AMI and adjustable root volume size when launching a cluster.
Release v1.10.13 (2017-07-19)
===

View File

@@ -21,12 +21,12 @@
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
//
// for _, p := range partitions {
// fmt.Println("Regions for", p.Name)
// fmt.Println("Regions for", p.ID())
// for id, _ := range p.Regions() {
// fmt.Println("*", id)
// }
//
// fmt.Println("Services for", p.Name)
// fmt.Println("Services for", p.ID())
// for id, _ := range p.Services() {
// fmt.Println("*", id)
// }

View File

@@ -55,7 +55,6 @@
package v4
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
@@ -614,8 +613,8 @@ func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) {
strings.Join(ctx.SignedHeaderVals[k], ",")
}
}
ctx.canonicalHeaders = strings.Join(stripExcessSpaces(headerValues), "\n")
stripExcessSpaces(headerValues)
ctx.canonicalHeaders = strings.Join(headerValues, "\n")
}
func (ctx *signingCtx) buildCanonicalString() {
@@ -717,45 +716,46 @@ func makeSha256Reader(reader io.ReadSeeker) []byte {
return hash.Sum(nil)
}
const doubleSpaces = " "
const doubleSpace = " "
var doubleSpaceBytes = []byte(doubleSpaces)
// stripExcessSpaces will rewrite the passed in slice's string values to not
// contain muliple side-by-side spaces.
func stripExcessSpaces(vals []string) {
var j, k, l, m, spaces int
for i, str := range vals {
// Trim trailing spaces
for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- {
}
func stripExcessSpaces(headerVals []string) []string {
vals := make([]string, len(headerVals))
for i, str := range headerVals {
// Trim leading and trailing spaces
trimmed := strings.TrimSpace(str)
// Trim leading spaces
for k = 0; k < j && str[k] == ' '; k++ {
}
str = str[k : j+1]
idx := strings.Index(trimmed, doubleSpaces)
if idx < 0 {
vals[i] = trimmed
// Strip multiple spaces.
j = strings.Index(str, doubleSpace)
if j < 0 {
vals[i] = str
continue
}
buf := []byte(trimmed)
for idx > -1 {
stripToIdx := -1
for j := idx + 1; j < len(buf); j++ {
if buf[j] != ' ' {
buf = append(buf[:idx+1], buf[j:]...)
stripToIdx = j - idx - 1
break
}
}
if stripToIdx >= 0 {
// Find next double space
idx = bytes.Index(buf[stripToIdx:], doubleSpaceBytes)
if idx >= 0 {
idx += stripToIdx
buf := []byte(str)
for k, m, l = j, j, len(buf); k < l; k++ {
if buf[k] == ' ' {
if spaces == 0 {
// First space.
buf[m] = buf[k]
m++
}
spaces++
} else {
idx = -1
// End of multiple spaces.
spaces = 0
buf[m] = buf[k]
m++
}
}
vals[i] = string(buf)
vals[i] = string(buf[:m])
}
return vals
}

View File

@@ -20,8 +20,10 @@ import (
func TestStripExcessHeaders(t *testing.T) {
vals := []string{
"",
"123",
"1 2 3",
"1 2 3 ",
" 1 2 3",
"1 2 3",
"1 23",
@@ -30,24 +32,30 @@ func TestStripExcessHeaders(t *testing.T) {
" 1 2 ",
"12 3",
"12 3 1",
"12 3 1",
"12 3 1abc123",
}
expected := []string{
"",
"123",
"1 2 3",
"1 2 3",
"1 2 3",
"1 2 3",
"1 23",
"1 2 3",
"1 2",
"1 2",
"12 3",
"12 3 1",
"12 3 1",
"12 3 1abc123",
}
newVals := stripExcessSpaces(vals)
for i := 0; i < len(newVals); i++ {
assert.Equal(t, expected[i], newVals[i], "test: %d", i)
stripExcessSpaces(vals)
for i := 0; i < len(vals); i++ {
assert.Equal(t, expected[i], vals[i], "test: %d", i)
}
}
@@ -507,15 +515,29 @@ func BenchmarkSignRequest(b *testing.B) {
}
}
func BenchmarkStripExcessSpaces(b *testing.B) {
vals := []string{
`AWS4-HMAC-SHA256 Credential=AKIDFAKEIDFAKEID/20160628/us-west-2/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature=1234567890abcdef1234567890abcdef1234567890abcdef`,
`123 321 123 321`,
` 123 321 123 321 `,
}
var stripExcessSpaceCases = []string{
`AWS4-HMAC-SHA256 Credential=AKIDFAKEIDFAKEID/20160628/us-west-2/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature=1234567890abcdef1234567890abcdef1234567890abcdef`,
`123 321 123 321`,
` 123 321 123 321 `,
` 123 321 123 321 `,
"123",
"1 2 3",
" 1 2 3",
"1 2 3",
"1 23",
"1 2 3",
"1 2 ",
" 1 2 ",
"12 3",
"12 3 1",
"12 3 1",
"12 3 1abc123",
}
b.ResetTimer()
func BenchmarkStripExcessSpaces(b *testing.B) {
for i := 0; i < b.N; i++ {
stripExcessSpaces(vals)
// Make sure to start with a copy of the cases
cases := append([]string{}, stripExcessSpaceCases...)
stripExcessSpaces(cases)
}
}

View File

@@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK
const SDKVersion = "1.10.13"
const SDKVersion = "1.10.16"

View File

@@ -24,7 +24,21 @@
{"shape":"LimitExceededException"},
{"shape":"ResourceNotFoundException"},
{"shape":"ConcurrentModificationException"},
{"shape":"IncompatibleImageException"}
{"shape":"IncompatibleImageException"},
{"shape":"OperationNotPermittedException"}
]
},
"CreateDirectoryConfig":{
"name":"CreateDirectoryConfig",
"http":{
"method":"POST",
"requestUri":"/"
},
"input":{"shape":"CreateDirectoryConfigRequest"},
"output":{"shape":"CreateDirectoryConfigResult"},
"errors":[
{"shape":"ResourceAlreadyExistsException"},
{"shape":"LimitExceededException"}
]
},
"CreateFleet":{
@@ -41,7 +55,9 @@
{"shape":"ResourceNotFoundException"},
{"shape":"LimitExceededException"},
{"shape":"InvalidRoleException"},
{"shape":"ConcurrentModificationException"}
{"shape":"ConcurrentModificationException"},
{"shape":"InvalidParameterCombinationException"},
{"shape":"IncompatibleImageException"}
]
},
"CreateStack":{
@@ -76,6 +92,19 @@
{"shape":"InvalidParameterCombinationException"}
]
},
"DeleteDirectoryConfig":{
"name":"DeleteDirectoryConfig",
"http":{
"method":"POST",
"requestUri":"/"
},
"input":{"shape":"DeleteDirectoryConfigRequest"},
"output":{"shape":"DeleteDirectoryConfigResult"},
"errors":[
{"shape":"ResourceInUseException"},
{"shape":"ResourceNotFoundException"}
]
},
"DeleteFleet":{
"name":"DeleteFleet",
"http":{
@@ -104,6 +133,18 @@
{"shape":"ConcurrentModificationException"}
]
},
"DescribeDirectoryConfigs":{
"name":"DescribeDirectoryConfigs",
"http":{
"method":"POST",
"requestUri":"/"
},
"input":{"shape":"DescribeDirectoryConfigsRequest"},
"output":{"shape":"DescribeDirectoryConfigsResult"},
"errors":[
{"shape":"ResourceNotFoundException"}
]
},
"DescribeFleets":{
"name":"DescribeFleets",
"http":{
@@ -221,6 +262,20 @@
{"shape":"ConcurrentModificationException"}
]
},
"UpdateDirectoryConfig":{
"name":"UpdateDirectoryConfig",
"http":{
"method":"POST",
"requestUri":"/"
},
"input":{"shape":"UpdateDirectoryConfigRequest"},
"output":{"shape":"UpdateDirectoryConfigResult"},
"errors":[
{"shape":"ResourceInUseException"},
{"shape":"ResourceNotFoundException"},
{"shape":"ConcurrentModificationException"}
]
},
"UpdateFleet":{
"name":"UpdateFleet",
"http":{
@@ -237,7 +292,8 @@
{"shape":"ResourceNotAvailableException"},
{"shape":"InvalidParameterCombinationException"},
{"shape":"ConcurrentModificationException"},
{"shape":"IncompatibleImageException"}
{"shape":"IncompatibleImageException"},
{"shape":"OperationNotPermittedException"}
]
},
"UpdateStack":{
@@ -259,6 +315,17 @@
}
},
"shapes":{
"AccountName":{
"type":"string",
"min":1,
"sensitive":true
},
"AccountPassword":{
"type":"string",
"max":127,
"min":1,
"sensitive":true
},
"Application":{
"type":"structure",
"members":{
@@ -329,6 +396,25 @@
},
"exception":true
},
"CreateDirectoryConfigRequest":{
"type":"structure",
"required":[
"DirectoryName",
"OrganizationalUnitDistinguishedNames",
"ServiceAccountCredentials"
],
"members":{
"DirectoryName":{"shape":"DirectoryName"},
"OrganizationalUnitDistinguishedNames":{"shape":"OrganizationalUnitDistinguishedNamesList"},
"ServiceAccountCredentials":{"shape":"ServiceAccountCredentials"}
}
},
"CreateDirectoryConfigResult":{
"type":"structure",
"members":{
"DirectoryConfig":{"shape":"DirectoryConfig"}
}
},
"CreateFleetRequest":{
"type":"structure",
"required":[
@@ -347,7 +433,8 @@
"DisconnectTimeoutInSeconds":{"shape":"Integer"},
"Description":{"shape":"Description"},
"DisplayName":{"shape":"DisplayName"},
"EnableDefaultInternetAccess":{"shape":"BooleanObject"}
"EnableDefaultInternetAccess":{"shape":"BooleanObject"},
"DomainJoinInfo":{"shape":"DomainJoinInfo"}
}
},
"CreateFleetResult":{
@@ -382,7 +469,7 @@
"members":{
"StackName":{"shape":"String"},
"FleetName":{"shape":"String"},
"UserId":{"shape":"UserId"},
"UserId":{"shape":"StreamingUrlUserId"},
"ApplicationId":{"shape":"String"},
"Validity":{"shape":"Long"},
"SessionContext":{"shape":"String"}
@@ -395,6 +482,18 @@
"Expires":{"shape":"Timestamp"}
}
},
"DeleteDirectoryConfigRequest":{
"type":"structure",
"required":["DirectoryName"],
"members":{
"DirectoryName":{"shape":"DirectoryName"}
}
},
"DeleteDirectoryConfigResult":{
"type":"structure",
"members":{
}
},
"DeleteFleetRequest":{
"type":"structure",
"required":["Name"],
@@ -419,6 +518,21 @@
"members":{
}
},
"DescribeDirectoryConfigsRequest":{
"type":"structure",
"members":{
"DirectoryNames":{"shape":"DirectoryNameList"},
"MaxResults":{"shape":"Integer"},
"NextToken":{"shape":"String"}
}
},
"DescribeDirectoryConfigsResult":{
"type":"structure",
"members":{
"DirectoryConfigs":{"shape":"DirectoryConfigList"},
"NextToken":{"shape":"String"}
}
},
"DescribeFleetsRequest":{
"type":"structure",
"members":{
@@ -485,6 +599,25 @@
"type":"string",
"max":256
},
"DirectoryConfig":{
"type":"structure",
"required":["DirectoryName"],
"members":{
"DirectoryName":{"shape":"DirectoryName"},
"OrganizationalUnitDistinguishedNames":{"shape":"OrganizationalUnitDistinguishedNamesList"},
"ServiceAccountCredentials":{"shape":"ServiceAccountCredentials"},
"CreatedTime":{"shape":"Timestamp"}
}
},
"DirectoryConfigList":{
"type":"list",
"member":{"shape":"DirectoryConfig"}
},
"DirectoryName":{"type":"string"},
"DirectoryNameList":{
"type":"list",
"member":{"shape":"DirectoryName"}
},
"DisassociateFleetRequest":{
"type":"structure",
"required":[
@@ -505,6 +638,13 @@
"type":"string",
"max":100
},
"DomainJoinInfo":{
"type":"structure",
"members":{
"DirectoryName":{"shape":"DirectoryName"},
"OrganizationalUnitDistinguishedName":{"shape":"OrganizationalUnitDistinguishedName"}
}
},
"ErrorMessage":{"type":"string"},
"ExpireSessionRequest":{
"type":"structure",
@@ -542,14 +682,16 @@
"VpcConfig":{"shape":"VpcConfig"},
"CreatedTime":{"shape":"Timestamp"},
"FleetErrors":{"shape":"FleetErrors"},
"EnableDefaultInternetAccess":{"shape":"BooleanObject"}
"EnableDefaultInternetAccess":{"shape":"BooleanObject"},
"DomainJoinInfo":{"shape":"DomainJoinInfo"}
}
},
"FleetAttribute":{
"type":"string",
"enum":[
"VPC_CONFIGURATION",
"VPC_CONFIGURATION_SECURITY_GROUP_IDS"
"VPC_CONFIGURATION_SECURITY_GROUP_IDS",
"DOMAIN_JOIN_INFO"
]
},
"FleetAttributes":{
@@ -576,7 +718,21 @@
"IAM_SERVICE_ROLE_MISSING_DESCRIBE_SUBNET_ACTION",
"SUBNET_NOT_FOUND",
"IMAGE_NOT_FOUND",
"INVALID_SUBNET_CONFIGURATION"
"INVALID_SUBNET_CONFIGURATION",
"SECURITY_GROUPS_NOT_FOUND",
"IAM_SERVICE_ROLE_MISSING_DESCRIBE_SECURITY_GROUPS_ACTION",
"DOMAIN_JOIN_ERROR_FILE_NOT_FOUND",
"DOMAIN_JOIN_ERROR_ACCESS_DENIED",
"DOMAIN_JOIN_ERROR_LOGON_FAILURE",
"DOMAIN_JOIN_ERROR_INVALID_PARAMETER",
"DOMAIN_JOIN_ERROR_MORE_DATA",
"DOMAIN_JOIN_ERROR_NO_SUCH_DOMAIN",
"DOMAIN_JOIN_ERROR_NOT_SUPPORTED",
"DOMAIN_JOIN_NERR_INVALID_WORKGROUP_NAME",
"DOMAIN_JOIN_NERR_WORKSTATION_NOT_STARTED",
"DOMAIN_JOIN_ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED",
"DOMAIN_JOIN_NERR_PASSWORD_EXPIRED",
"DOMAIN_JOIN_INTERNAL_SERVICE_ERROR"
]
},
"FleetErrors":{
@@ -718,6 +874,14 @@
},
"exception":true
},
"OrganizationalUnitDistinguishedName":{
"type":"string",
"max":2000
},
"OrganizationalUnitDistinguishedNamesList":{
"type":"list",
"member":{"shape":"OrganizationalUnitDistinguishedName"}
},
"PlatformType":{
"type":"string",
"enum":["WINDOWS"]
@@ -759,6 +923,17 @@
"member":{"shape":"String"},
"max":5
},
"ServiceAccountCredentials":{
"type":"structure",
"required":[
"AccountName",
"AccountPassword"
],
"members":{
"AccountName":{"shape":"AccountName"},
"AccountPassword":{"shape":"AccountPassword"}
}
},
"Session":{
"type":"structure",
"required":[
@@ -864,6 +1039,12 @@
"type":"string",
"enum":["HOMEFOLDERS"]
},
"StreamingUrlUserId":{
"type":"string",
"max":32,
"min":2,
"pattern":"[\\w+=,.@-]*"
},
"String":{
"type":"string",
"min":1
@@ -877,6 +1058,21 @@
"member":{"shape":"String"}
},
"Timestamp":{"type":"timestamp"},
"UpdateDirectoryConfigRequest":{
"type":"structure",
"required":["DirectoryName"],
"members":{
"DirectoryName":{"shape":"DirectoryName"},
"OrganizationalUnitDistinguishedNames":{"shape":"OrganizationalUnitDistinguishedNamesList"},
"ServiceAccountCredentials":{"shape":"ServiceAccountCredentials"}
}
},
"UpdateDirectoryConfigResult":{
"type":"structure",
"members":{
"DirectoryConfig":{"shape":"DirectoryConfig"}
}
},
"UpdateFleetRequest":{
"type":"structure",
"required":["Name"],
@@ -895,6 +1091,7 @@
"Description":{"shape":"Description"},
"DisplayName":{"shape":"DisplayName"},
"EnableDefaultInternetAccess":{"shape":"BooleanObject"},
"DomainJoinInfo":{"shape":"DomainJoinInfo"},
"AttributesToDelete":{"shape":"FleetAttributes"}
}
},

View File

@@ -3,25 +3,41 @@
"service": "<fullname>Amazon AppStream 2.0</fullname> <p>API documentation for Amazon AppStream 2.0.</p>",
"operations": {
"AssociateFleet": "<p>Associate a fleet to a stack.</p>",
"CreateDirectoryConfig": "<p>Creates a directory configuration with the given parameters.</p>",
"CreateFleet": "<p>Creates a new fleet.</p>",
"CreateStack": "<p>Create a new stack.</p>",
"CreateStreamingURL": "<p>Creates a URL to start an AppStream 2.0 streaming session for a user. By default, the URL is valid only for 1 minute from the time that it is generated.</p>",
"DeleteDirectoryConfig": "<p>Deletes the directory configuration with the given parameters.</p>",
"DeleteFleet": "<p>Deletes a fleet.</p>",
"DeleteStack": "<p>Deletes the stack. After this operation completes, the environment can no longer be activated, and any reservations made for the stack are released.</p>",
"DescribeDirectoryConfigs": "<p>Returns a list describing the specified directory configurations.</p>",
"DescribeFleets": "<p>If fleet names are provided, this operation describes the specified fleets; otherwise, all the fleets in the account are described.</p>",
"DescribeImages": "<p>Describes the images. If a list of names is not provided, all images in your account are returned. This operation does not return a paginated result.</p>",
"DescribeSessions": "<p>Describes the streaming sessions for a stack and a fleet. If a user ID is provided, this operation returns streaming sessions for only that user. Pass this value for the <code>nextToken</code> parameter in a subsequent call to this operation to retrieve the next set of items. If an authentication type is not provided, the operation defaults to users authenticated using a streaming URL.</p>",
"DescribeStacks": "<p>If stack names are not provided, this operation describes the specified stacks; otherwise, all stacks in the account are described. Pass the <code>nextToken</code> value in a subsequent call to this operation to retrieve the next set of items.</p>",
"DescribeSessions": "<p>Describes the streaming sessions for a stack and a fleet. If a user ID is provided, this operation returns streaming sessions for only that user. To retrieve the next set of items, pass this value for the <code>nextToken</code> parameter in a subsequent call to this operation. If an authentication type is not provided, the operation defaults to users authenticated using a streaming URL.</p>",
"DescribeStacks": "<p>If stack names are not provided, this operation describes the specified stacks; otherwise, all stacks in the account are described. To retrieve the next set of items, pass the <code>nextToken</code> value in a subsequent call to this operation.</p>",
"DisassociateFleet": "<p>Disassociates a fleet from a stack.</p>",
"ExpireSession": "<p>This operation immediately stops a streaming session.</p>",
"ListAssociatedFleets": "<p>Lists all fleets associated with the stack.</p>",
"ListAssociatedStacks": "<p>Lists all stacks to which the specified fleet is associated.</p>",
"StartFleet": "<p>Starts a fleet.</p>",
"StopFleet": "<p>Stops a fleet.</p>",
"UpdateDirectoryConfig": "<p>Updates the directory configuration with the given parameters.</p>",
"UpdateFleet": "<p>Updates an existing fleet. All the attributes except the fleet name can be updated in the <b>STOPPED</b> state. When a fleet is in the <b>RUNNING</b> state, only <code>DisplayName</code> and <code>ComputeCapacity</code> can be updated. A fleet cannot be updated in a status of <b>STARTING</b> or <b>STOPPING</b>.</p>",
"UpdateStack": "<p>Updates the specified fields in the stack with the specified name.</p>"
},
"shapes": {
"AccountName": {
"base": null,
"refs": {
"ServiceAccountCredentials$AccountName": "<p>The user name of an account in the directory that is used by AppStream 2.0 streaming instances to connect to the directory. This account must have the following privileges: create computer objects, join computers to the domain, change/reset the password on descendant computer objects for the organizational units specified.</p>"
}
},
"AccountPassword": {
"base": null,
"refs": {
"ServiceAccountCredentials$AccountPassword": "<p>The password for the user account for directory actions.</p>"
}
},
"Application": {
"base": "<p>An entry for a single application in the application catalog.</p>",
"refs": {
@@ -63,7 +79,7 @@
"Boolean": {
"base": null,
"refs": {
"Application$Enabled": "<p>An application can be disabled after image creation if there is a problem.</p>",
"Application$Enabled": "<p>If there is a problem, an application can be disabled after image creation.</p>",
"Image$ImageBuilderSupported": "<p>Whether an image builder can be launched from this image.</p>",
"UpdateFleetRequest$DeleteVpcConfig": "<p>Delete the VPC association for the specified fleet.</p>",
"UpdateStackRequest$DeleteStorageConnectors": "<p>Remove all the storage connectors currently enabled for the stack.</p>"
@@ -72,9 +88,9 @@
"BooleanObject": {
"base": null,
"refs": {
"CreateFleetRequest$EnableDefaultInternetAccess": "<p>Enables or disables default Internet access for the fleet.</p>",
"Fleet$EnableDefaultInternetAccess": "<p>Whether default Internet access is enabled for the fleet. </p>",
"UpdateFleetRequest$EnableDefaultInternetAccess": "<p>Enables or disables default Internet access for the fleet.</p>"
"CreateFleetRequest$EnableDefaultInternetAccess": "<p>Enables or disables default internet access for the fleet.</p>",
"Fleet$EnableDefaultInternetAccess": "<p>Whether default internet access is enabled for the fleet. </p>",
"UpdateFleetRequest$EnableDefaultInternetAccess": "<p>Enables or disables default internet access for the fleet.</p>"
}
},
"ComputeCapacity": {
@@ -95,6 +111,16 @@
"refs": {
}
},
"CreateDirectoryConfigRequest": {
"base": null,
"refs": {
}
},
"CreateDirectoryConfigResult": {
"base": null,
"refs": {
}
},
"CreateFleetRequest": {
"base": "<p>Contains the parameters for the new fleet to create.</p>",
"refs": {
@@ -125,6 +151,16 @@
"refs": {
}
},
"DeleteDirectoryConfigRequest": {
"base": null,
"refs": {
}
},
"DeleteDirectoryConfigResult": {
"base": null,
"refs": {
}
},
"DeleteFleetRequest": {
"base": null,
"refs": {
@@ -145,6 +181,16 @@
"refs": {
}
},
"DescribeDirectoryConfigsRequest": {
"base": null,
"refs": {
}
},
"DescribeDirectoryConfigsResult": {
"base": null,
"refs": {
}
},
"DescribeFleetsRequest": {
"base": null,
"refs": {
@@ -194,6 +240,37 @@
"UpdateStackRequest$Description": "<p>The description displayed to end users on the AppStream 2.0 portal.</p>"
}
},
"DirectoryConfig": {
"base": "<p>Full directory configuration details, which are used to join domains for the AppStream 2.0 streaming instances.</p>",
"refs": {
"CreateDirectoryConfigResult$DirectoryConfig": "<p>Directory configuration details.</p>",
"DirectoryConfigList$member": null,
"UpdateDirectoryConfigResult$DirectoryConfig": "<p>The updated directory configuration details.</p>"
}
},
"DirectoryConfigList": {
"base": null,
"refs": {
"DescribeDirectoryConfigsResult$DirectoryConfigs": "<p>The list of directory configurations.</p>"
}
},
"DirectoryName": {
"base": null,
"refs": {
"CreateDirectoryConfigRequest$DirectoryName": "<p>The fully qualified name of the directory, such as corp.example.com</p>",
"DeleteDirectoryConfigRequest$DirectoryName": "<p>The name of the directory configuration to be deleted.</p>",
"DirectoryConfig$DirectoryName": "<p>The fully qualified name of the directory, such as corp.example.com</p>",
"DirectoryNameList$member": null,
"DomainJoinInfo$DirectoryName": "<p>The fully qualified name of the directory, such as corp.example.com</p>",
"UpdateDirectoryConfigRequest$DirectoryName": "<p>The name of the existing directory configuration to be updated.</p>"
}
},
"DirectoryNameList": {
"base": null,
"refs": {
"DescribeDirectoryConfigsRequest$DirectoryNames": "<p>A specific list of directory names.</p>"
}
},
"DisassociateFleetRequest": {
"base": null,
"refs": {
@@ -213,6 +290,14 @@
"UpdateStackRequest$DisplayName": "<p>The name displayed to end users on the AppStream 2.0 portal.</p>"
}
},
"DomainJoinInfo": {
"base": "<p>The <i>DirectoryName</i> and <i>OrganizationalUnitDistinguishedName</i> values, which are used to join domains for the AppStream 2.0 streaming instances.</p>",
"refs": {
"CreateFleetRequest$DomainJoinInfo": "<p>The <i>DirectoryName</i> and <i>OrganizationalUnitDistinguishedName</i> values, which are used to join domains for the AppStream 2.0 streaming instances.</p>",
"Fleet$DomainJoinInfo": "<p>The <i>DirectoryName</i> and <i>OrganizationalUnitDistinguishedName</i> values, which are used to join domains for the AppStream 2.0 streaming instances.</p>",
"UpdateFleetRequest$DomainJoinInfo": "<p>The <i>DirectoryName</i> and <i>OrganizationalUnitDistinguishedName</i> values, which are used to join domains for the AppStream 2.0 streaming instances.</p>"
}
},
"ErrorMessage": {
"base": "<p>The error message in the exception.</p>",
"refs": {
@@ -303,7 +388,7 @@
"ImageState": {
"base": null,
"refs": {
"Image$State": "<p>The image starts in the <b>PENDING</b> state, and then moves to <b>AVAILABLE</b> if image creation succeeds and <b>FAILED</b> if image creation has failed.</p>"
"Image$State": "<p>The image starts in the <b>PENDING</b> state. If image creation succeeds, it moves to <b>AVAILABLE</b>. If image creation fails, it moves to <b>FAILED</b>.</p>"
}
},
"ImageStateChangeReason": {
@@ -333,6 +418,7 @@
"ComputeCapacityStatus$Available": "<p>The number of currently available instances that can be used to stream sessions.</p>",
"CreateFleetRequest$MaxUserDurationInSeconds": "<p>The maximum time for which a streaming session can run. The input can be any numeric value in seconds between 600 and 57600.</p>",
"CreateFleetRequest$DisconnectTimeoutInSeconds": "<p>The time after disconnection when a session is considered to have ended. If a user who got disconnected reconnects within this timeout interval, the user is connected back to their previous session. The input can be any numeric value in seconds between 60 and 57600. </p>",
"DescribeDirectoryConfigsRequest$MaxResults": "<p>The size of each page of results.</p>",
"DescribeSessionsRequest$Limit": "<p>The size of each page of results. The default value is 20 and the maximum supported value is 50.</p>",
"Fleet$MaxUserDurationInSeconds": "<p>The maximum time for which a streaming session can run. The value can be any numeric value in seconds between 600 and 57600.</p>",
"Fleet$DisconnectTimeoutInSeconds": "<p>The time after disconnection when a session is considered to have ended. If a user who got disconnected reconnects within this timeout interval, the user is connected back to their previous session. The input can be any numeric value in seconds between 60 and 57600.</p>",
@@ -398,6 +484,21 @@
"refs": {
}
},
"OrganizationalUnitDistinguishedName": {
"base": null,
"refs": {
"DomainJoinInfo$OrganizationalUnitDistinguishedName": "<p>The distinguished name of the organizational unit to place the computer account in.</p>",
"OrganizationalUnitDistinguishedNamesList$member": null
}
},
"OrganizationalUnitDistinguishedNamesList": {
"base": null,
"refs": {
"CreateDirectoryConfigRequest$OrganizationalUnitDistinguishedNames": "<p>The list of the distinguished names of organizational units to place computer accounts in.</p>",
"DirectoryConfig$OrganizationalUnitDistinguishedNames": "<p>The list of the distinguished names of organizational units in which to place computer accounts.</p>",
"UpdateDirectoryConfigRequest$OrganizationalUnitDistinguishedNames": "<p>The list of the distinguished names of organizational units to place computer accounts in.</p>"
}
},
"PlatformType": {
"base": null,
"refs": {
@@ -436,6 +537,14 @@
"VpcConfig$SecurityGroupIds": "<p>Security groups associated with the fleet.</p>"
}
},
"ServiceAccountCredentials": {
"base": "<p>The <i>AccountName</i> and <i>AccountPassword</i> of the service account, to be used by the streaming instance to connect to the directory.</p>",
"refs": {
"CreateDirectoryConfigRequest$ServiceAccountCredentials": "<p>The <i>AccountName</i> and <i>AccountPassword</i> values for the service account, which are used by the streaming instance to connect to the directory.</p>",
"DirectoryConfig$ServiceAccountCredentials": "<p>The <i>AccountName</i> and <i>AccountPassword</i> of the service account, to be used by the streaming instance to connect to the directory.</p>",
"UpdateDirectoryConfigRequest$ServiceAccountCredentials": "<p>The <i>AccountName</i> and <i>AccountPassword</i> values for the service account, which are used by the streaming instance to connect to the directory</p>"
}
},
"Session": {
"base": "<p>Contains the parameters for a streaming session.</p>",
"refs": {
@@ -526,6 +635,12 @@
"StorageConnector$ConnectorType": "<p>The type of storage connector. The possible values include: HOMEFOLDERS.</p>"
}
},
"StreamingUrlUserId": {
"base": null,
"refs": {
"CreateStreamingURLRequest$UserId": "<p>A unique user ID for whom the URL is generated.</p>"
}
},
"String": {
"base": null,
"refs": {
@@ -537,7 +652,7 @@
"AssociateFleetRequest$FleetName": "<p>The name of the fleet to associate.</p>",
"AssociateFleetRequest$StackName": "<p>The name of the stack to which the fleet is associated.</p>",
"CreateFleetRequest$ImageName": "<p>Unique name of the image used by the fleet.</p>",
"CreateFleetRequest$InstanceType": "<p>The instance type of compute resources for the fleet. Fleet instances are launched from this instance type.</p>",
"CreateFleetRequest$InstanceType": "<p>The instance type of compute resources for the fleet. Fleet instances are launched from this instance type. Available instance types are:</p> <ul> <li> <p>stream.standard.medium</p> </li> <li> <p>stream.standard.large</p> </li> <li> <p>stream.compute.large</p> </li> <li> <p>stream.compute.xlarge</p> </li> <li> <p>stream.compute.2xlarge</p> </li> <li> <p>stream.compute.4xlarge</p> </li> <li> <p>stream.compute.8xlarge</p> </li> <li> <p>stream.memory.large</p> </li> <li> <p>stream.memory.xlarge</p> </li> <li> <p>stream.memory.2xlarge</p> </li> <li> <p>stream.memory.4xlarge</p> </li> <li> <p>stream.memory.8xlarge</p> </li> </ul>",
"CreateStackRequest$Name": "<p>The unique identifier for this stack.</p>",
"CreateStreamingURLRequest$StackName": "<p>The stack for which the URL is generated.</p>",
"CreateStreamingURLRequest$FleetName": "<p>The fleet for which the URL is generated.</p>",
@@ -546,6 +661,8 @@
"CreateStreamingURLResult$StreamingURL": "<p>The URL to start the AppStream 2.0 streaming session.</p>",
"DeleteFleetRequest$Name": "<p>The name of the fleet to be deleted.</p>",
"DeleteStackRequest$Name": "<p>The name of the stack to delete.</p>",
"DescribeDirectoryConfigsRequest$NextToken": "<p>The DescribeDirectoryConfigsResult.NextToken from a previous call to DescribeDirectoryConfigs. If this is the first call, pass null.</p>",
"DescribeDirectoryConfigsResult$NextToken": "<p>If not null, more results are available. To retrieve the next set of items, pass this value for the NextToken parameter in a subsequent call to DescribeDirectoryConfigs.</p>",
"DescribeFleetsRequest$NextToken": "<p>The pagination token to use to retrieve the next page of results for this operation. If this value is null, it retrieves the first page.</p>",
"DescribeFleetsResult$NextToken": "<p>The pagination token to use to retrieve the next page of results for this operation. If there are no more pages, this value is null.</p>",
"DescribeSessionsRequest$StackName": "<p>The name of the stack for which to list sessions.</p>",
@@ -589,7 +706,7 @@
"SubnetIdList$member": null,
"UpdateFleetRequest$ImageName": "<p>The image name from which a fleet is created.</p>",
"UpdateFleetRequest$Name": "<p>The name of the fleet.</p>",
"UpdateFleetRequest$InstanceType": "<p>The instance type of compute resources for the fleet. Fleet instances are launched from this instance type.</p>",
"UpdateFleetRequest$InstanceType": "<p>The instance type of compute resources for the fleet. Fleet instances are launched from this instance type. Available instance types are:</p> <ul> <li> <p>stream.standard.medium</p> </li> <li> <p>stream.standard.large</p> </li> <li> <p>stream.compute.large</p> </li> <li> <p>stream.compute.xlarge</p> </li> <li> <p>stream.compute.2xlarge</p> </li> <li> <p>stream.compute.4xlarge</p> </li> <li> <p>stream.compute.8xlarge</p> </li> <li> <p>stream.memory.large</p> </li> <li> <p>stream.memory.xlarge</p> </li> <li> <p>stream.memory.2xlarge</p> </li> <li> <p>stream.memory.4xlarge</p> </li> <li> <p>stream.memory.8xlarge</p> </li> </ul>",
"UpdateStackRequest$Name": "<p>The name of the stack to update.</p>"
}
},
@@ -612,11 +729,22 @@
"Timestamp": {
"base": null,
"refs": {
"CreateStreamingURLResult$Expires": "<p>Elapsed seconds after the Unix epoch, at which time this URL expires.</p>",
"CreateStreamingURLResult$Expires": "<p>Elapsed seconds after the Unix epoch, when this URL expires.</p>",
"DirectoryConfig$CreatedTime": "<p>The time stamp when the directory configuration was created within AppStream 2.0.</p>",
"Fleet$CreatedTime": "<p>The time at which the fleet was created.</p>",
"Image$CreatedTime": "<p>The timestamp when the image was created.</p>",
"Image$CreatedTime": "<p>The time stamp when the image was created.</p>",
"Image$PublicBaseImageReleasedDate": "<p>The AWS release date of the public base image. For private images, this date is the release date of the base image from which the image was created.</p>",
"Stack$CreatedTime": "<p>The timestamp when the stack was created.</p>"
"Stack$CreatedTime": "<p>The time stamp when the stack was created.</p>"
}
},
"UpdateDirectoryConfigRequest": {
"base": null,
"refs": {
}
},
"UpdateDirectoryConfigResult": {
"base": null,
"refs": {
}
},
"UpdateFleetRequest": {
@@ -642,7 +770,6 @@
"UserId": {
"base": null,
"refs": {
"CreateStreamingURLRequest$UserId": "<p>A unique user ID for whom the URL is generated.</p>",
"DescribeSessionsRequest$UserId": "<p>The user for whom to list sessions. Use null to describe all the sessions for the stack and fleet.</p>",
"Session$UserId": "<p>The identifier of the user for whom the session was created.</p>"
}

View File

@@ -9,19 +9,19 @@
{
"state": "success",
"matcher": "pathAll",
"argument": "fleets[].state",
"argument": "Fleets[].State",
"expected": "ACTIVE"
},
{
"state": "failure",
"matcher": "pathAny",
"argument": "fleets[].state",
"argument": "Fleets[].State",
"expected": "PENDING_DEACTIVATE"
},
{
"state": "failure",
"matcher": "pathAny",
"argument": "fleets[].state",
"argument": "Fleets[].State",
"expected": "INACTIVE"
}
]
@@ -34,19 +34,19 @@
{
"state": "success",
"matcher": "pathAll",
"argument": "fleets[].state",
"argument": "Fleets[].State",
"expected": "INACTIVE"
},
{
"state": "failure",
"matcher": "pathAny",
"argument": "fleets[].state",
"argument": "Fleets[].State",
"expected": "PENDING_ACTIVATE"
},
{
"state": "failure",
"matcher": "pathAny",
"argument": "fleets[].state",
"argument": "Fleets[].State",
"expected": "ACTIVE"
}
]

View File

@@ -136,6 +136,7 @@
{"shape":"ValidationException"},
{"shape":"LimitExceededException"},
{"shape":"AccessDeniedException"},
{"shape":"DirectoryNotEnabledException"},
{"shape":"ResourceNotFoundException"},
{"shape":"InvalidAttachmentException"},
{"shape":"ValidationException"},
@@ -495,6 +496,7 @@
{"shape":"ValidationException"},
{"shape":"LimitExceededException"},
{"shape":"AccessDeniedException"},
{"shape":"DirectoryNotEnabledException"},
{"shape":"ResourceNotFoundException"},
{"shape":"FacetValidationException"}
]
@@ -774,6 +776,7 @@
{"shape":"ValidationException"},
{"shape":"LimitExceededException"},
{"shape":"AccessDeniedException"},
{"shape":"DirectoryNotEnabledException"},
{"shape":"ResourceNotFoundException"},
{"shape":"InvalidNextTokenException"},
{"shape":"FacetValidationException"}
@@ -927,6 +930,7 @@
{"shape":"ValidationException"},
{"shape":"LimitExceededException"},
{"shape":"AccessDeniedException"},
{"shape":"DirectoryNotEnabledException"},
{"shape":"ResourceNotFoundException"},
{"shape":"InvalidNextTokenException"},
{"shape":"FacetValidationException"}
@@ -1494,6 +1498,80 @@
"attachedObjectIdentifier":{"shape":"ObjectIdentifier"}
}
},
"BatchAttachPolicy":{
"type":"structure",
"required":[
"PolicyReference",
"ObjectReference"
],
"members":{
"PolicyReference":{"shape":"ObjectReference"},
"ObjectReference":{"shape":"ObjectReference"}
}
},
"BatchAttachPolicyResponse":{
"type":"structure",
"members":{
}
},
"BatchAttachToIndex":{
"type":"structure",
"required":[
"IndexReference",
"TargetReference"
],
"members":{
"IndexReference":{"shape":"ObjectReference"},
"TargetReference":{"shape":"ObjectReference"}
}
},
"BatchAttachToIndexResponse":{
"type":"structure",
"members":{
"AttachedObjectIdentifier":{"shape":"ObjectIdentifier"}
}
},
"BatchAttachTypedLink":{
"type":"structure",
"required":[
"SourceObjectReference",
"TargetObjectReference",
"TypedLinkFacet",
"Attributes"
],
"members":{
"SourceObjectReference":{"shape":"ObjectReference"},
"TargetObjectReference":{"shape":"ObjectReference"},
"TypedLinkFacet":{"shape":"TypedLinkSchemaAndFacetName"},
"Attributes":{"shape":"AttributeNameAndValueList"}
}
},
"BatchAttachTypedLinkResponse":{
"type":"structure",
"members":{
"TypedLinkSpecifier":{"shape":"TypedLinkSpecifier"}
}
},
"BatchCreateIndex":{
"type":"structure",
"required":[
"OrderedIndexedAttributeList",
"IsUnique"
],
"members":{
"OrderedIndexedAttributeList":{"shape":"AttributeKeyList"},
"IsUnique":{"shape":"Bool"},
"ParentReference":{"shape":"ObjectReference"},
"LinkName":{"shape":"LinkName"},
"BatchReferenceName":{"shape":"BatchReferenceName"}
}
},
"BatchCreateIndexResponse":{
"type":"structure",
"members":{
"ObjectIdentifier":{"shape":"ObjectIdentifier"}
}
},
"BatchCreateObject":{
"type":"structure",
"required":[
@@ -1529,6 +1607,23 @@
"members":{
}
},
"BatchDetachFromIndex":{
"type":"structure",
"required":[
"IndexReference",
"TargetReference"
],
"members":{
"IndexReference":{"shape":"ObjectReference"},
"TargetReference":{"shape":"ObjectReference"}
}
},
"BatchDetachFromIndexResponse":{
"type":"structure",
"members":{
"DetachedObjectIdentifier":{"shape":"ObjectIdentifier"}
}
},
"BatchDetachObject":{
"type":"structure",
"required":[
@@ -1548,6 +1643,83 @@
"detachedObjectIdentifier":{"shape":"ObjectIdentifier"}
}
},
"BatchDetachTypedLink":{
"type":"structure",
"required":["TypedLinkSpecifier"],
"members":{
"TypedLinkSpecifier":{"shape":"TypedLinkSpecifier"}
}
},
"BatchDetachTypedLinkResponse":{
"type":"structure",
"members":{
}
},
"BatchGetObjectInformation":{
"type":"structure",
"required":["ObjectReference"],
"members":{
"ObjectReference":{"shape":"ObjectReference"}
}
},
"BatchGetObjectInformationResponse":{
"type":"structure",
"members":{
"SchemaFacets":{"shape":"SchemaFacetList"},
"ObjectIdentifier":{"shape":"ObjectIdentifier"}
}
},
"BatchListAttachedIndices":{
"type":"structure",
"required":["TargetReference"],
"members":{
"TargetReference":{"shape":"ObjectReference"},
"NextToken":{"shape":"NextToken"},
"MaxResults":{"shape":"NumberResults"}
}
},
"BatchListAttachedIndicesResponse":{
"type":"structure",
"members":{
"IndexAttachments":{"shape":"IndexAttachmentList"},
"NextToken":{"shape":"NextToken"}
}
},
"BatchListIncomingTypedLinks":{
"type":"structure",
"required":["ObjectReference"],
"members":{
"ObjectReference":{"shape":"ObjectReference"},
"FilterAttributeRanges":{"shape":"TypedLinkAttributeRangeList"},
"FilterTypedLink":{"shape":"TypedLinkSchemaAndFacetName"},
"NextToken":{"shape":"NextToken"},
"MaxResults":{"shape":"NumberResults"}
}
},
"BatchListIncomingTypedLinksResponse":{
"type":"structure",
"members":{
"LinkSpecifiers":{"shape":"TypedLinkSpecifierList"},
"NextToken":{"shape":"NextToken"}
}
},
"BatchListIndex":{
"type":"structure",
"required":["IndexReference"],
"members":{
"RangesOnIndexedValues":{"shape":"ObjectAttributeRangeList"},
"IndexReference":{"shape":"ObjectReference"},
"MaxResults":{"shape":"NumberResults"},
"NextToken":{"shape":"NextToken"}
}
},
"BatchListIndexResponse":{
"type":"structure",
"members":{
"IndexAttachments":{"shape":"IndexAttachmentList"},
"NextToken":{"shape":"NextToken"}
}
},
"BatchListObjectAttributes":{
"type":"structure",
"required":["ObjectReference"],
@@ -1581,6 +1753,88 @@
"NextToken":{"shape":"NextToken"}
}
},
"BatchListObjectParentPaths":{
"type":"structure",
"required":["ObjectReference"],
"members":{
"ObjectReference":{"shape":"ObjectReference"},
"NextToken":{"shape":"NextToken"},
"MaxResults":{"shape":"NumberResults"}
}
},
"BatchListObjectParentPathsResponse":{
"type":"structure",
"members":{
"PathToObjectIdentifiersList":{"shape":"PathToObjectIdentifiersList"},
"NextToken":{"shape":"NextToken"}
}
},
"BatchListObjectPolicies":{
"type":"structure",
"required":["ObjectReference"],
"members":{
"ObjectReference":{"shape":"ObjectReference"},
"NextToken":{"shape":"NextToken"},
"MaxResults":{"shape":"NumberResults"}
}
},
"BatchListObjectPoliciesResponse":{
"type":"structure",
"members":{
"AttachedPolicyIds":{"shape":"ObjectIdentifierList"},
"NextToken":{"shape":"NextToken"}
}
},
"BatchListOutgoingTypedLinks":{
"type":"structure",
"required":["ObjectReference"],
"members":{
"ObjectReference":{"shape":"ObjectReference"},
"FilterAttributeRanges":{"shape":"TypedLinkAttributeRangeList"},
"FilterTypedLink":{"shape":"TypedLinkSchemaAndFacetName"},
"NextToken":{"shape":"NextToken"},
"MaxResults":{"shape":"NumberResults"}
}
},
"BatchListOutgoingTypedLinksResponse":{
"type":"structure",
"members":{
"TypedLinkSpecifiers":{"shape":"TypedLinkSpecifierList"},
"NextToken":{"shape":"NextToken"}
}
},
"BatchListPolicyAttachments":{
"type":"structure",
"required":["PolicyReference"],
"members":{
"PolicyReference":{"shape":"ObjectReference"},
"NextToken":{"shape":"NextToken"},
"MaxResults":{"shape":"NumberResults"}
}
},
"BatchListPolicyAttachmentsResponse":{
"type":"structure",
"members":{
"ObjectIdentifiers":{"shape":"ObjectIdentifierList"},
"NextToken":{"shape":"NextToken"}
}
},
"BatchLookupPolicy":{
"type":"structure",
"required":["ObjectReference"],
"members":{
"ObjectReference":{"shape":"ObjectReference"},
"NextToken":{"shape":"NextToken"},
"MaxResults":{"shape":"NumberResults"}
}
},
"BatchLookupPolicyResponse":{
"type":"structure",
"members":{
"PolicyToPathList":{"shape":"PolicyToPathList"},
"NextToken":{"shape":"NextToken"}
}
},
"BatchOperationIndex":{"type":"integer"},
"BatchReadException":{
"type":"structure",
@@ -1597,14 +1851,30 @@
"ResourceNotFoundException",
"InvalidNextTokenException",
"AccessDeniedException",
"NotNodeException"
"NotNodeException",
"FacetValidationException",
"CannotListParentOfRootException",
"NotIndexException",
"NotPolicyException",
"DirectoryNotEnabledException",
"LimitExceededException",
"InternalServiceException"
]
},
"BatchReadOperation":{
"type":"structure",
"members":{
"ListObjectAttributes":{"shape":"BatchListObjectAttributes"},
"ListObjectChildren":{"shape":"BatchListObjectChildren"}
"ListObjectChildren":{"shape":"BatchListObjectChildren"},
"ListAttachedIndices":{"shape":"BatchListAttachedIndices"},
"ListObjectParentPaths":{"shape":"BatchListObjectParentPaths"},
"GetObjectInformation":{"shape":"BatchGetObjectInformation"},
"ListObjectPolicies":{"shape":"BatchListObjectPolicies"},
"ListPolicyAttachments":{"shape":"BatchListPolicyAttachments"},
"LookupPolicy":{"shape":"BatchLookupPolicy"},
"ListIndex":{"shape":"BatchListIndex"},
"ListOutgoingTypedLinks":{"shape":"BatchListOutgoingTypedLinks"},
"ListIncomingTypedLinks":{"shape":"BatchListIncomingTypedLinks"}
}
},
"BatchReadOperationList":{
@@ -1652,7 +1922,16 @@
"type":"structure",
"members":{
"ListObjectAttributes":{"shape":"BatchListObjectAttributesResponse"},
"ListObjectChildren":{"shape":"BatchListObjectChildrenResponse"}
"ListObjectChildren":{"shape":"BatchListObjectChildrenResponse"},
"GetObjectInformation":{"shape":"BatchGetObjectInformationResponse"},
"ListAttachedIndices":{"shape":"BatchListAttachedIndicesResponse"},
"ListObjectParentPaths":{"shape":"BatchListObjectParentPathsResponse"},
"ListObjectPolicies":{"shape":"BatchListObjectPoliciesResponse"},
"ListPolicyAttachments":{"shape":"BatchListPolicyAttachmentsResponse"},
"LookupPolicy":{"shape":"BatchLookupPolicyResponse"},
"ListIndex":{"shape":"BatchListIndexResponse"},
"ListOutgoingTypedLinks":{"shape":"BatchListOutgoingTypedLinksResponse"},
"ListIncomingTypedLinks":{"shape":"BatchListIncomingTypedLinksResponse"}
}
},
"BatchReferenceName":{"type":"string"},
@@ -1709,7 +1988,15 @@
"FacetValidationException",
"ObjectNotDetachedException",
"ResourceNotFoundException",
"AccessDeniedException"
"AccessDeniedException",
"InvalidAttachmentException",
"NotIndexException",
"IndexedAttributeMissingException",
"ObjectAlreadyDetachedException",
"NotPolicyException",
"DirectoryNotEnabledException",
"LimitExceededException",
"UnsupportedIndexTypeException"
]
},
"BatchWriteOperation":{
@@ -1721,7 +2008,13 @@
"UpdateObjectAttributes":{"shape":"BatchUpdateObjectAttributes"},
"DeleteObject":{"shape":"BatchDeleteObject"},
"AddFacetToObject":{"shape":"BatchAddFacetToObject"},
"RemoveFacetFromObject":{"shape":"BatchRemoveFacetFromObject"}
"RemoveFacetFromObject":{"shape":"BatchRemoveFacetFromObject"},
"AttachPolicy":{"shape":"BatchAttachPolicy"},
"CreateIndex":{"shape":"BatchCreateIndex"},
"AttachToIndex":{"shape":"BatchAttachToIndex"},
"DetachFromIndex":{"shape":"BatchDetachFromIndex"},
"AttachTypedLink":{"shape":"BatchAttachTypedLink"},
"DetachTypedLink":{"shape":"BatchDetachTypedLink"}
}
},
"BatchWriteOperationList":{
@@ -1737,7 +2030,13 @@
"UpdateObjectAttributes":{"shape":"BatchUpdateObjectAttributesResponse"},
"DeleteObject":{"shape":"BatchDeleteObjectResponse"},
"AddFacetToObject":{"shape":"BatchAddFacetToObjectResponse"},
"RemoveFacetFromObject":{"shape":"BatchRemoveFacetFromObjectResponse"}
"RemoveFacetFromObject":{"shape":"BatchRemoveFacetFromObjectResponse"},
"AttachPolicy":{"shape":"BatchAttachPolicyResponse"},
"CreateIndex":{"shape":"BatchCreateIndexResponse"},
"AttachToIndex":{"shape":"BatchAttachToIndexResponse"},
"DetachFromIndex":{"shape":"BatchDetachFromIndexResponse"},
"AttachTypedLink":{"shape":"BatchAttachTypedLinkResponse"},
"DetachTypedLink":{"shape":"BatchDetachTypedLinkResponse"}
}
},
"BatchWriteOperationResponseList":{

View File

@@ -241,6 +241,7 @@
"AttributeKeyList": {
"base": null,
"refs": {
"BatchCreateIndex$OrderedIndexedAttributeList": "<p>Specifies the attributes that should be indexed on. Currently only a single attribute is supported.</p>",
"CreateIndexRequest$OrderedIndexedAttributeList": "<p>Specifies the attributes that should be indexed on. Currently only a single attribute is supported.</p>"
}
},
@@ -266,6 +267,7 @@
"base": null,
"refs": {
"AttachTypedLinkRequest$Attributes": "<p>A set of attributes that are associated with the typed link.</p>",
"BatchAttachTypedLink$Attributes": "<p>A set of attributes that are associated with the typed link.</p>",
"TypedLinkSpecifier$IdentityAttributeValues": "<p>Identifies the attribute value to update.</p>"
}
},
@@ -273,7 +275,7 @@
"base": null,
"refs": {
"GetTypedLinkFacetInformationResponse$IdentityAttributeOrder": "<p>The order of identity attributes for the facet, from most significant to least significant. The ability to filter typed links considers the order that the attributes are defined on the typed link facet. When providing ranges to typed link selection, any inexact ranges must be specified at the end. Any attributes that do not have a range specified are presumed to match the entire range. Filters are interpreted in the order of the attributes on the typed link facet, not the order in which they are supplied to any API calls. For more information about identity attributes, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/objectsandlinks.html#typedlink\">Typed link</a>.</p>",
"TypedLinkFacet$IdentityAttributeOrder": "<p>The set of attributes that distinguish links made from this facet from each other, in the order of significance. Listing typed links can filter on the values of these attributes. See <a>ListOutgoingTypedLinks</a> and <a>ListIncomingTypeLinks</a> for details.</p>",
"TypedLinkFacet$IdentityAttributeOrder": "<p>The set of attributes that distinguish links made from this facet from each other, in the order of significance. Listing typed links can filter on the values of these attributes. See <a>ListOutgoingTypedLinks</a> and <a>ListIncomingTypedLinks</a> for details.</p>",
"UpdateTypedLinkFacetRequest$IdentityAttributeOrder": "<p>The order of identity attributes for the facet, from most significant to least significant. The ability to filter typed links considers the order that the attributes are defined on the typed link facet. When providing ranges to a typed link selection, any inexact ranges must be specified at the end. Any attributes that do not have a range specified are presumed to match the entire range. Filters are interpreted in the order of the attributes on the typed link facet, not the order in which they are supplied to any API calls. For more information about identity attributes, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/objectsandlinks.html#typedlink\">Typed link</a>.</p>"
}
},
@@ -290,77 +292,257 @@
}
},
"BatchAttachObject": {
"base": "<p>Represents the output of an <code>AttachObject</code> operation.</p>",
"base": "<p>Represents the output of an <a>AttachObject</a> operation.</p>",
"refs": {
"BatchWriteOperation$AttachObject": "<p>Attaches an object to a <a>Directory</a>.</p>"
}
},
"BatchAttachObjectResponse": {
"base": "<p>Represents the output batch <code>AttachObject</code> response operation.</p>",
"base": "<p>Represents the output batch <a>AttachObject</a> response operation.</p>",
"refs": {
"BatchWriteOperationResponse$AttachObject": "<p>Attaches an object to a <a>Directory</a>.</p>"
}
},
"BatchAttachPolicy": {
"base": "<p>Attaches a policy object to a regular object inside a <a>BatchRead</a> operation. For more information, see <a>AttachPolicy</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchWriteOperation$AttachPolicy": "<p>Attaches a policy object to a regular object. An object can have a limited number of attached policies.</p>"
}
},
"BatchAttachPolicyResponse": {
"base": "<p>Represents the output of an <a>AttachPolicy</a> response operation.</p>",
"refs": {
"BatchWriteOperationResponse$AttachPolicy": "<p>Attaches a policy object to a regular object. An object can have a limited number of attached policies.</p>"
}
},
"BatchAttachToIndex": {
"base": "<p>Attaches the specified object to the specified index inside a <a>BatchRead</a> operation. For more information, see <a>AttachToIndex</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchWriteOperation$AttachToIndex": "<p>Attaches the specified object to the specified index.</p>"
}
},
"BatchAttachToIndexResponse": {
"base": "<p>Represents the output of a <a>AttachToIndex</a> response operation.</p>",
"refs": {
"BatchWriteOperationResponse$AttachToIndex": "<p>Attaches the specified object to the specified index.</p>"
}
},
"BatchAttachTypedLink": {
"base": "<p>Attaches a typed link to a specified source and target object inside a <a>BatchRead</a> operation. For more information, see <a>AttachTypedLink</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchWriteOperation$AttachTypedLink": "<p>Attaches a typed link to a specified source and target object. For more information, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/objectsandlinks.html#typedlink\">Typed link</a>.</p>"
}
},
"BatchAttachTypedLinkResponse": {
"base": "<p>Represents the output of a <a>AttachTypedLink</a> response operation.</p>",
"refs": {
"BatchWriteOperationResponse$AttachTypedLink": "<p>Attaches a typed link to a specified source and target object. For more information, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/objectsandlinks.html#typedlink\">Typed link</a>.</p>"
}
},
"BatchCreateIndex": {
"base": "<p>Creates an index object inside of a <a>BatchRead</a> operation. For more information, see <a>CreateIndex</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchWriteOperation$CreateIndex": "<p>Creates an index object. See <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/cd_indexing.html\">Indexing</a> for more information.</p>"
}
},
"BatchCreateIndexResponse": {
"base": "<p>Represents the output of a <a>CreateIndex</a> response operation.</p>",
"refs": {
"BatchWriteOperationResponse$CreateIndex": "<p>Creates an index object. See <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/cd_indexing.html\">Indexing</a> for more information.</p>"
}
},
"BatchCreateObject": {
"base": "<p>Represents the output of a <code>CreateObject</code> operation.</p>",
"base": "<p>Represents the output of a <a>CreateObject</a> operation.</p>",
"refs": {
"BatchWriteOperation$CreateObject": "<p>Creates an object.</p>"
}
},
"BatchCreateObjectResponse": {
"base": "<p>Represents the output of a <code>CreateObject</code> response operation.</p>",
"base": "<p>Represents the output of a <a>CreateObject</a> response operation.</p>",
"refs": {
"BatchWriteOperationResponse$CreateObject": "<p>Creates an object in a <a>Directory</a>.</p>"
}
},
"BatchDeleteObject": {
"base": "<p>Represents the output of a <code>DeleteObject</code> operation.</p>",
"base": "<p>Represents the output of a <a>DeleteObject</a> operation.</p>",
"refs": {
"BatchWriteOperation$DeleteObject": "<p>Deletes an object in a <a>Directory</a>.</p>"
}
},
"BatchDeleteObjectResponse": {
"base": "<p>Represents the output of a <code>DeleteObject</code> response operation.</p>",
"base": "<p>Represents the output of a <a>DeleteObject</a> response operation.</p>",
"refs": {
"BatchWriteOperationResponse$DeleteObject": "<p>Deletes an object in a <a>Directory</a>.</p>"
}
},
"BatchDetachFromIndex": {
"base": "<p>Detaches the specified object from the specified index inside a <a>BatchRead</a> operation. For more information, see <a>DetachFromIndex</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchWriteOperation$DetachFromIndex": "<p>Detaches the specified object from the specified index.</p>"
}
},
"BatchDetachFromIndexResponse": {
"base": "<p>Represents the output of a <a>DetachFromIndex</a> response operation.</p>",
"refs": {
"BatchWriteOperationResponse$DetachFromIndex": "<p>Detaches the specified object from the specified index.</p>"
}
},
"BatchDetachObject": {
"base": "<p>Represents the output of a <code>DetachObject</code> operation.</p>",
"base": "<p>Represents the output of a <a>DetachObject</a> operation.</p>",
"refs": {
"BatchWriteOperation$DetachObject": "<p>Detaches an object from a <a>Directory</a>.</p>"
}
},
"BatchDetachObjectResponse": {
"base": "<p>Represents the output of a <code>DetachObject</code> response operation.</p>",
"base": "<p>Represents the output of a <a>DetachObject</a> response operation.</p>",
"refs": {
"BatchWriteOperationResponse$DetachObject": "<p>Detaches an object from a <a>Directory</a>.</p>"
}
},
"BatchDetachTypedLink": {
"base": "<p>Detaches a typed link from a specified source and target object inside a <a>BatchRead</a> operation. For more information, see <a>DetachTypedLink</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchWriteOperation$DetachTypedLink": "<p>Detaches a typed link from a specified source and target object. For more information, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/objectsandlinks.html#typedlink\">Typed link</a>.</p>"
}
},
"BatchDetachTypedLinkResponse": {
"base": "<p>Represents the output of a <a>DetachTypedLink</a> response operation.</p>",
"refs": {
"BatchWriteOperationResponse$DetachTypedLink": "<p>Detaches a typed link from a specified source and target object. For more information, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/objectsandlinks.html#typedlink\">Typed link</a>.</p>"
}
},
"BatchGetObjectInformation": {
"base": "<p>Retrieves metadata about an object inside a <a>BatchRead</a> operation. For more information, see <a>GetObjectInformation</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchReadOperation$GetObjectInformation": "<p>Retrieves metadata about an object.</p>"
}
},
"BatchGetObjectInformationResponse": {
"base": "<p>Represents the output of a <a>GetObjectInformation</a> response operation.</p>",
"refs": {
"BatchReadSuccessfulResponse$GetObjectInformation": "<p>Retrieves metadata about an object.</p>"
}
},
"BatchListAttachedIndices": {
"base": "<p>Lists indices attached to an object inside a <a>BatchRead</a> operation. For more information, see <a>ListAttachedIndices</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchReadOperation$ListAttachedIndices": "<p>Lists indices attached to an object.</p>"
}
},
"BatchListAttachedIndicesResponse": {
"base": "<p>Represents the output of a <a>ListAttachedIndices</a> response operation.</p>",
"refs": {
"BatchReadSuccessfulResponse$ListAttachedIndices": "<p>Lists indices attached to an object.</p>"
}
},
"BatchListIncomingTypedLinks": {
"base": "<p>Returns a paginated list of all the incoming <a>TypedLinkSpecifier</a> information for an object inside a <a>BatchRead</a> operation. For more information, see <a>ListIncomingTypedLinks</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchReadOperation$ListIncomingTypedLinks": "<p>Returns a paginated list of all the incoming <a>TypedLinkSpecifier</a> information for an object. It also supports filtering by typed link facet and identity attributes. For more information, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/objectsandlinks.html#typedlink\">Typed link</a>.</p>"
}
},
"BatchListIncomingTypedLinksResponse": {
"base": "<p>Represents the output of a <a>ListIncomingTypedLinks</a> response operation.</p>",
"refs": {
"BatchReadSuccessfulResponse$ListIncomingTypedLinks": "<p>Returns a paginated list of all the incoming <a>TypedLinkSpecifier</a> information for an object. It also supports filtering by typed link facet and identity attributes. For more information, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/objectsandlinks.html#typedlink\">Typed link</a>.</p>"
}
},
"BatchListIndex": {
"base": "<p>Lists objects attached to the specified index inside a <a>BatchRead</a> operation. For more information, see <a>ListIndex</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchReadOperation$ListIndex": "<p>Lists objects attached to the specified index.</p>"
}
},
"BatchListIndexResponse": {
"base": "<p>Represents the output of a <a>ListIndex</a> response operation.</p>",
"refs": {
"BatchReadSuccessfulResponse$ListIndex": "<p>Lists objects attached to the specified index.</p>"
}
},
"BatchListObjectAttributes": {
"base": "<p>Represents the output of a <code>ListObjectAttributes</code> operation.</p>",
"base": "<p>Represents the output of a <a>ListObjectAttributes</a> operation.</p>",
"refs": {
"BatchReadOperation$ListObjectAttributes": "<p>Lists all attributes that are associated with an object.</p>"
}
},
"BatchListObjectAttributesResponse": {
"base": "<p>Represents the output of a <code>ListObjectAttributes</code> response operation.</p>",
"base": "<p>Represents the output of a <a>ListObjectAttributes</a> response operation.</p>",
"refs": {
"BatchReadSuccessfulResponse$ListObjectAttributes": "<p>Lists all attributes that are associated with an object.</p>"
}
},
"BatchListObjectChildren": {
"base": "<p>Represents the output of a <code>ListObjectChildren</code> operation.</p>",
"base": "<p>Represents the output of a <a>ListObjectChildren</a> operation.</p>",
"refs": {
"BatchReadOperation$ListObjectChildren": "<p>Returns a paginated list of child objects that are associated with a given object.</p>"
}
},
"BatchListObjectChildrenResponse": {
"base": "<p>Represents the output of a <code>ListObjectChildren</code> response operation.</p>",
"base": "<p>Represents the output of a <a>ListObjectChildren</a> response operation.</p>",
"refs": {
"BatchReadSuccessfulResponse$ListObjectChildren": "<p>Returns a paginated list of child objects that are associated with a given object.</p>"
}
},
"BatchListObjectParentPaths": {
"base": "<p>Retrieves all available parent paths for any object type such as node, leaf node, policy node, and index node objects inside a <a>BatchRead</a> operation. For more information, see <a>ListObjectParentPaths</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchReadOperation$ListObjectParentPaths": "<p>Retrieves all available parent paths for any object type such as node, leaf node, policy node, and index node objects. For more information about objects, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/cd_key_concepts.html#dirstructure\">Directory Structure</a>.</p>"
}
},
"BatchListObjectParentPathsResponse": {
"base": "<p>Represents the output of a <a>ListObjectParentPaths</a> response operation.</p>",
"refs": {
"BatchReadSuccessfulResponse$ListObjectParentPaths": "<p>Retrieves all available parent paths for any object type such as node, leaf node, policy node, and index node objects. For more information about objects, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/cd_key_concepts.html#dirstructure\">Directory Structure</a>.</p>"
}
},
"BatchListObjectPolicies": {
"base": "<p>Returns policies attached to an object in pagination fashion inside a <a>BatchRead</a> operation. For more information, see <a>ListObjectPolicies</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchReadOperation$ListObjectPolicies": "<p>Returns policies attached to an object in pagination fashion.</p>"
}
},
"BatchListObjectPoliciesResponse": {
"base": "<p>Represents the output of a <a>ListObjectPolicies</a> response operation.</p>",
"refs": {
"BatchReadSuccessfulResponse$ListObjectPolicies": "<p>Returns policies attached to an object in pagination fashion.</p>"
}
},
"BatchListOutgoingTypedLinks": {
"base": "<p>Returns a paginated list of all the outgoing <a>TypedLinkSpecifier</a> information for an object inside a <a>BatchRead</a> operation. For more information, see <a>ListOutgoingTypedLinks</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchReadOperation$ListOutgoingTypedLinks": "<p>Returns a paginated list of all the outgoing <a>TypedLinkSpecifier</a> information for an object. It also supports filtering by typed link facet and identity attributes. For more information, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/objectsandlinks.html#typedlink\">Typed link</a>.</p>"
}
},
"BatchListOutgoingTypedLinksResponse": {
"base": "<p>Represents the output of a <a>ListOutgoingTypedLinks</a> response operation.</p>",
"refs": {
"BatchReadSuccessfulResponse$ListOutgoingTypedLinks": "<p>Returns a paginated list of all the outgoing <a>TypedLinkSpecifier</a> information for an object. It also supports filtering by typed link facet and identity attributes. For more information, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/objectsandlinks.html#typedlink\">Typed link</a>.</p>"
}
},
"BatchListPolicyAttachments": {
"base": "<p>Returns all of the <code>ObjectIdentifiers</code> to which a given policy is attached inside a <a>BatchRead</a> operation. For more information, see <a>ListPolicyAttachments</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchReadOperation$ListPolicyAttachments": "<p>Returns all of the <code>ObjectIdentifiers</code> to which a given policy is attached.</p>"
}
},
"BatchListPolicyAttachmentsResponse": {
"base": "<p>Represents the output of a <a>ListPolicyAttachments</a> response operation.</p>",
"refs": {
"BatchReadSuccessfulResponse$ListPolicyAttachments": "<p>Returns all of the <code>ObjectIdentifiers</code> to which a given policy is attached.</p>"
}
},
"BatchLookupPolicy": {
"base": "<p>Lists all policies from the root of the Directory to the object specified inside a <a>BatchRead</a> operation. For more information, see <a>LookupPolicy</a> and <a>BatchReadRequest$Operations</a>.</p>",
"refs": {
"BatchReadOperation$LookupPolicy": "<p>Lists all policies from the root of the <a>Directory</a> to the object specified. If there are no policies present, an empty list is returned. If policies are present, and if some objects don't have the policies attached, it returns the <code>ObjectIdentifier</code> for such objects. If policies are present, it returns <code>ObjectIdentifier</code>, <code>policyId</code>, and <code>policyType</code>. Paths that don't lead to the root from the target object are ignored. For more information, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/cd_key_concepts.html#policies\">Policies</a>.</p>"
}
},
"BatchLookupPolicyResponse": {
"base": "<p>Represents the output of a <a>LookupPolicy</a> response operation.</p>",
"refs": {
"BatchReadSuccessfulResponse$LookupPolicy": "<p>Lists all policies from the root of the <a>Directory</a> to the object specified. If there are no policies present, an empty list is returned. If policies are present, and if some objects don't have the policies attached, it returns the <code>ObjectIdentifier</code> for such objects. If policies are present, it returns <code>ObjectIdentifier</code>, <code>policyId</code>, and <code>policyType</code>. Paths that don't lead to the root from the target object are ignored. For more information, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/cd_key_concepts.html#policies\">Policies</a>.</p>"
}
},
"BatchOperationIndex": {
"base": null,
"refs": {
@@ -422,6 +604,7 @@
"BatchReferenceName": {
"base": null,
"refs": {
"BatchCreateIndex$BatchReferenceName": "<p>The batch reference name. See <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/cd_advanced.html#batches\">Batches</a> for more information.</p>",
"BatchCreateObject$BatchReferenceName": "<p>The batch reference name. See <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/cd_advanced.html#batches\">Batches</a> for more information.</p>",
"BatchDetachObject$BatchReferenceName": "<p>The batch reference name. See <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/cd_advanced.html#batches\">Batches</a> for more information.</p>"
}
@@ -504,6 +687,7 @@
"Bool": {
"base": null,
"refs": {
"BatchCreateIndex$IsUnique": "<p>Indicates whether the attribute that is being indexed has unique values or not.</p>",
"CreateIndexRequest$IsUnique": "<p>Indicates whether the attribute that is being indexed has unique values or not.</p>",
"FacetAttributeDefinition$IsImmutable": "<p>Whether the attribute is mutable or not.</p>",
"TypedLinkAttributeDefinition$IsImmutable": "<p>Whether the attribute is mutable or not.</p>"
@@ -960,6 +1144,8 @@
"IndexAttachmentList": {
"base": null,
"refs": {
"BatchListAttachedIndicesResponse$IndexAttachments": "<p>The indices attached to the specified object.</p>",
"BatchListIndexResponse$IndexAttachments": "<p>The objects and indexed values attached to the index.</p>",
"ListAttachedIndicesResponse$IndexAttachments": "<p>The indices attached to the specified object.</p>",
"ListIndexResponse$IndexAttachments": "<p>The objects and indexed values attached to the index.</p>"
}
@@ -1019,6 +1205,7 @@
"refs": {
"AttachObjectRequest$LinkName": "<p>The link name with which the child object is attached to the parent.</p>",
"BatchAttachObject$LinkName": "<p>The name of the link.</p>",
"BatchCreateIndex$LinkName": "<p>The name of the link between the parent object and the index object.</p>",
"BatchCreateObject$LinkName": "<p>The name of the link.</p>",
"BatchDetachObject$LinkName": "<p>The name of the link.</p>",
"CreateIndexRequest$LinkName": "<p>The name of the link between the parent object and the index object.</p>",
@@ -1243,10 +1430,26 @@
"NextToken": {
"base": null,
"refs": {
"BatchListAttachedIndices$NextToken": "<p>The pagination token.</p>",
"BatchListAttachedIndicesResponse$NextToken": "<p>The pagination token.</p>",
"BatchListIncomingTypedLinks$NextToken": "<p>The pagination token.</p>",
"BatchListIncomingTypedLinksResponse$NextToken": "<p>The pagination token.</p>",
"BatchListIndex$NextToken": "<p>The pagination token.</p>",
"BatchListIndexResponse$NextToken": "<p>The pagination token.</p>",
"BatchListObjectAttributes$NextToken": "<p>The pagination token.</p>",
"BatchListObjectAttributesResponse$NextToken": "<p>The pagination token.</p>",
"BatchListObjectChildren$NextToken": "<p>The pagination token.</p>",
"BatchListObjectChildrenResponse$NextToken": "<p>The pagination token.</p>",
"BatchListObjectParentPaths$NextToken": "<p>The pagination token.</p>",
"BatchListObjectParentPathsResponse$NextToken": "<p>The pagination token.</p>",
"BatchListObjectPolicies$NextToken": "<p>The pagination token.</p>",
"BatchListObjectPoliciesResponse$NextToken": "<p>The pagination token.</p>",
"BatchListOutgoingTypedLinks$NextToken": "<p>The pagination token.</p>",
"BatchListOutgoingTypedLinksResponse$NextToken": "<p>The pagination token.</p>",
"BatchListPolicyAttachments$NextToken": "<p>The pagination token.</p>",
"BatchListPolicyAttachmentsResponse$NextToken": "<p>The pagination token.</p>",
"BatchLookupPolicy$NextToken": "<p>The pagination token.</p>",
"BatchLookupPolicyResponse$NextToken": "<p>The pagination token.</p>",
"ListAppliedSchemaArnsRequest$NextToken": "<p>The pagination token.</p>",
"ListAppliedSchemaArnsResponse$NextToken": "<p>The pagination token.</p>",
"ListAttachedIndicesRequest$NextToken": "<p>The pagination token.</p>",
@@ -1313,8 +1516,16 @@
"NumberResults": {
"base": null,
"refs": {
"BatchListAttachedIndices$MaxResults": "<p>The maximum number of results to retrieve.</p>",
"BatchListIncomingTypedLinks$MaxResults": "<p>The maximum number of results to retrieve.</p>",
"BatchListIndex$MaxResults": "<p>The maximum number of results to retrieve.</p>",
"BatchListObjectAttributes$MaxResults": "<p>The maximum number of items to be retrieved in a single call. This is an approximate number.</p>",
"BatchListObjectChildren$MaxResults": "<p>Maximum number of items to be retrieved in a single call. This is an approximate number.</p>",
"BatchListObjectParentPaths$MaxResults": "<p>The maximum number of results to retrieve.</p>",
"BatchListObjectPolicies$MaxResults": "<p>The maximum number of results to retrieve.</p>",
"BatchListOutgoingTypedLinks$MaxResults": "<p>The maximum number of results to retrieve.</p>",
"BatchListPolicyAttachments$MaxResults": "<p>The maximum number of results to retrieve.</p>",
"BatchLookupPolicy$MaxResults": "<p>The maximum number of results to retrieve.</p>",
"ListAppliedSchemaArnsRequest$MaxResults": "<p>The maximum number of results to retrieve.</p>",
"ListAttachedIndicesRequest$MaxResults": "<p>The maximum number of results to retrieve.</p>",
"ListDevelopmentSchemaArnsRequest$MaxResults": "<p>The maximum number of results to retrieve.</p>",
@@ -1356,6 +1567,7 @@
"ObjectAttributeRangeList": {
"base": null,
"refs": {
"BatchListIndex$RangesOnIndexedValues": "<p>Specifies the ranges of indexed values that you want to query.</p>",
"ListIndexRequest$RangesOnIndexedValues": "<p>Specifies the ranges of indexed values that you want to query.</p>"
}
},
@@ -1378,8 +1590,12 @@
"AttachObjectResponse$AttachedObjectIdentifier": "<p>The attached <code>ObjectIdentifier</code>, which is the child <code>ObjectIdentifier</code>.</p>",
"AttachToIndexResponse$AttachedObjectIdentifier": "<p>The <code>ObjectIdentifier</code> of the object that was attached to the index.</p>",
"BatchAttachObjectResponse$attachedObjectIdentifier": "<p>The <code>ObjectIdentifier</code> of the object that has been attached.</p>",
"BatchAttachToIndexResponse$AttachedObjectIdentifier": "<p>The <code>ObjectIdentifier</code> of the object that was attached to the index.</p>",
"BatchCreateIndexResponse$ObjectIdentifier": "<p>The <code>ObjectIdentifier</code> of the index created by this operation.</p>",
"BatchCreateObjectResponse$ObjectIdentifier": "<p>The ID that is associated with the object.</p>",
"BatchDetachFromIndexResponse$DetachedObjectIdentifier": "<p>The <code>ObjectIdentifier</code> of the object that was detached from the index.</p>",
"BatchDetachObjectResponse$detachedObjectIdentifier": "<p>The <code>ObjectIdentifier</code> of the detached object.</p>",
"BatchGetObjectInformationResponse$ObjectIdentifier": "<p>The <code>ObjectIdentifier</code> of the specified object.</p>",
"BatchUpdateObjectAttributesResponse$ObjectIdentifier": "<p>ID that is associated with the object.</p>",
"CreateDirectoryResponse$ObjectIdentifier": "<p>The root object node of the created directory.</p>",
"CreateIndexResponse$ObjectIdentifier": "<p>The <code>ObjectIdentifier</code> of the index created by this operation.</p>",
@@ -1399,6 +1615,8 @@
"ObjectIdentifierList": {
"base": null,
"refs": {
"BatchListObjectPoliciesResponse$AttachedPolicyIds": "<p>A list of policy <code>ObjectIdentifiers</code>, that are attached to the object.</p>",
"BatchListPolicyAttachmentsResponse$ObjectIdentifiers": "<p>A list of <code>ObjectIdentifiers</code> to which the policy is attached.</p>",
"ListObjectPoliciesResponse$AttachedPolicyIds": "<p>A list of policy <code>ObjectIdentifiers</code>, that are attached to the object.</p>",
"ListPolicyAttachmentsResponse$ObjectIdentifiers": "<p>A list of <code>ObjectIdentifiers</code> to which the policy is attached.</p>",
"PathToObjectIdentifiers$ObjectIdentifiers": "<p>Lists <code>ObjectIdentifiers</code> starting from directory root to the object in the request.</p>"
@@ -1430,11 +1648,29 @@
"BatchAddFacetToObject$ObjectReference": "<p>A reference to the object being mutated.</p>",
"BatchAttachObject$ParentReference": "<p>The parent object reference.</p>",
"BatchAttachObject$ChildReference": "<p>The child object reference that is to be attached to the object.</p>",
"BatchAttachPolicy$PolicyReference": "<p>The reference that is associated with the policy object.</p>",
"BatchAttachPolicy$ObjectReference": "<p>The reference that identifies the object to which the policy will be attached.</p>",
"BatchAttachToIndex$IndexReference": "<p>A reference to the index that you are attaching the object to.</p>",
"BatchAttachToIndex$TargetReference": "<p>A reference to the object that you are attaching to the index.</p>",
"BatchAttachTypedLink$SourceObjectReference": "<p>Identifies the source object that the typed link will attach to.</p>",
"BatchAttachTypedLink$TargetObjectReference": "<p>Identifies the target object that the typed link will attach to.</p>",
"BatchCreateIndex$ParentReference": "<p>A reference to the parent object that contains the index object.</p>",
"BatchCreateObject$ParentReference": "<p>If specified, the parent reference to which this object will be attached.</p>",
"BatchDeleteObject$ObjectReference": "<p>The reference that identifies the object.</p>",
"BatchDetachFromIndex$IndexReference": "<p>A reference to the index object.</p>",
"BatchDetachFromIndex$TargetReference": "<p>A reference to the object being detached from the index.</p>",
"BatchDetachObject$ParentReference": "<p>Parent reference from which the object with the specified link name is detached.</p>",
"BatchGetObjectInformation$ObjectReference": "<p>A reference to the object.</p>",
"BatchListAttachedIndices$TargetReference": "<p>A reference to the object that has indices attached.</p>",
"BatchListIncomingTypedLinks$ObjectReference": "<p>The reference that identifies the object whose attributes will be listed.</p>",
"BatchListIndex$IndexReference": "<p>The reference to the index to list.</p>",
"BatchListObjectAttributes$ObjectReference": "<p>Reference of the object whose attributes need to be listed.</p>",
"BatchListObjectChildren$ObjectReference": "<p>Reference of the object for which child objects are being listed.</p>",
"BatchListObjectParentPaths$ObjectReference": "<p>The reference that identifies the object whose attributes will be listed.</p>",
"BatchListObjectPolicies$ObjectReference": "<p>The reference that identifies the object whose attributes will be listed.</p>",
"BatchListOutgoingTypedLinks$ObjectReference": "<p>The reference that identifies the object whose attributes will be listed.</p>",
"BatchListPolicyAttachments$PolicyReference": "<p>The reference that identifies the policy object.</p>",
"BatchLookupPolicy$ObjectReference": "<p>Reference that identifies the object whose policies will be looked up.</p>",
"BatchRemoveFacetFromObject$ObjectReference": "<p>A reference to the object whose facet will be removed.</p>",
"BatchUpdateObjectAttributes$ObjectReference": "<p>Reference that identifies the object.</p>",
"CreateIndexRequest$ParentReference": "<p>A reference to the parent object that contains the index object.</p>",
@@ -1446,7 +1682,7 @@
"DetachPolicyRequest$PolicyReference": "<p>Reference that identifies the policy object.</p>",
"DetachPolicyRequest$ObjectReference": "<p>Reference that identifies the object whose policy object will be detached.</p>",
"GetObjectInformationRequest$ObjectReference": "<p>A reference to the object.</p>",
"ListAttachedIndicesRequest$TargetReference": "<p>A reference to the object to that has indices attached.</p>",
"ListAttachedIndicesRequest$TargetReference": "<p>A reference to the object that has indices attached.</p>",
"ListIncomingTypedLinksRequest$ObjectReference": "<p>Reference that identifies the object whose attributes will be listed.</p>",
"ListIndexRequest$IndexReference": "<p>The reference to the index to list.</p>",
"ListObjectAttributesRequest$ObjectReference": "<p>The reference that identifies the object whose attributes will be listed.</p>",
@@ -1487,6 +1723,7 @@
"PathToObjectIdentifiersList": {
"base": null,
"refs": {
"BatchListObjectParentPathsResponse$PathToObjectIdentifiersList": "<p>Returns the path to the <code>ObjectIdentifiers</code> that are associated with the directory.</p>",
"ListObjectParentPathsResponse$PathToObjectIdentifiersList": "<p>Returns the path to the <code>ObjectIdentifiers</code> that are associated with the directory.</p>"
}
},
@@ -1511,6 +1748,7 @@
"PolicyToPathList": {
"base": null,
"refs": {
"BatchLookupPolicyResponse$PolicyToPathList": "<p>Provides list of path to policies. Policies contain <code>PolicyId</code>, <code>ObjectIdentifier</code>, and <code>PolicyType</code>. For more information, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/cd_key_concepts.html#policies\">Policies</a>.</p>",
"LookupPolicyResponse$PolicyToPathList": "<p>Provides list of path to policies. Policies contain <code>PolicyId</code>, <code>ObjectIdentifier</code>, and <code>PolicyType</code>. For more information, see <a href=\"http://docs.aws.amazon.com/directoryservice/latest/admin-guide/cd_key_concepts.html#policies\">Policies</a>.</p>"
}
},
@@ -1643,6 +1881,7 @@
"base": null,
"refs": {
"BatchCreateObject$SchemaFacet": "<p>A list of <code>FacetArns</code> that will be associated with the object. For more information, see <a>arns</a>.</p>",
"BatchGetObjectInformationResponse$SchemaFacets": "<p>The facets attached to the specified object.</p>",
"CreateObjectRequest$SchemaFacets": "<p>A list of schema facets to be associated with the object that contains <code>SchemaArn</code> and facet name. For more information, see <a>arns</a>.</p>",
"GetObjectInformationResponse$SchemaFacets": "<p>The facets attached to the specified object.</p>"
}
@@ -1770,6 +2009,8 @@
"TypedLinkAttributeRangeList": {
"base": null,
"refs": {
"BatchListIncomingTypedLinks$FilterAttributeRanges": "<p>Provides range filters for multiple attributes. When providing ranges to typed link selection, any inexact ranges must be specified at the end. Any attributes that do not have a range specified are presumed to match the entire range.</p>",
"BatchListOutgoingTypedLinks$FilterAttributeRanges": "<p>Provides range filters for multiple attributes. When providing ranges to typed link selection, any inexact ranges must be specified at the end. Any attributes that do not have a range specified are presumed to match the entire range.</p>",
"ListIncomingTypedLinksRequest$FilterAttributeRanges": "<p>Provides range filters for multiple attributes. When providing ranges to typed link selection, any inexact ranges must be specified at the end. Any attributes that do not have a range specified are presumed to match the entire range.</p>",
"ListOutgoingTypedLinksRequest$FilterAttributeRanges": "<p>Provides range filters for multiple attributes. When providing ranges to typed link selection, any inexact ranges must be specified at the end. Any attributes that do not have a range specified are presumed to match the entire range.</p>"
}
@@ -1814,6 +2055,9 @@
"base": "<p>Identifies the schema Amazon Resource Name (ARN) and facet name for the typed link.</p>",
"refs": {
"AttachTypedLinkRequest$TypedLinkFacet": "<p>Identifies the typed link facet that is associated with the typed link.</p>",
"BatchAttachTypedLink$TypedLinkFacet": "<p>Identifies the typed link facet that is associated with the typed link.</p>",
"BatchListIncomingTypedLinks$FilterTypedLink": "<p>Filters are interpreted in the order of the attributes on the typed link facet, not the order in which they are supplied to any API calls.</p>",
"BatchListOutgoingTypedLinks$FilterTypedLink": "<p>Filters are interpreted in the order of the attributes defined on the typed link facet, not the order they are supplied to any API calls.</p>",
"ListIncomingTypedLinksRequest$FilterTypedLink": "<p>Filters are interpreted in the order of the attributes on the typed link facet, not the order in which they are supplied to any API calls.</p>",
"ListOutgoingTypedLinksRequest$FilterTypedLink": "<p>Filters are interpreted in the order of the attributes defined on the typed link facet, not the order they are supplied to any API calls.</p>",
"TypedLinkSpecifier$TypedLinkFacet": "<p>Identifies the typed link facet that is associated with the typed link.</p>"
@@ -1823,6 +2067,8 @@
"base": "<p>Contains all the information that is used to uniquely identify a typed link. The parameters discussed in this topic are used to uniquely specify the typed link being operated on. The <a>AttachTypedLink</a> API returns a typed link specifier while the <a>DetachTypedLink</a> API accepts one as input. Similarly, the <a>ListIncomingTypedLinks</a> and <a>ListOutgoingTypedLinks</a> API operations provide typed link specifiers as output. You can also construct a typed link specifier from scratch.</p>",
"refs": {
"AttachTypedLinkResponse$TypedLinkSpecifier": "<p>Returns a typed link specifier as output.</p>",
"BatchAttachTypedLinkResponse$TypedLinkSpecifier": "<p>Returns a typed link specifier as output.</p>",
"BatchDetachTypedLink$TypedLinkSpecifier": "<p>Used to accept a typed link specifier as input.</p>",
"DetachTypedLinkRequest$TypedLinkSpecifier": "<p>Used to accept a typed link specifier as input.</p>",
"TypedLinkSpecifierList$member": null
}
@@ -1830,6 +2076,8 @@
"TypedLinkSpecifierList": {
"base": null,
"refs": {
"BatchListIncomingTypedLinksResponse$LinkSpecifiers": "<p>Returns one or more typed link specifiers as output.</p>",
"BatchListOutgoingTypedLinksResponse$TypedLinkSpecifiers": "<p>Returns a typed link specifier as output.</p>",
"ListIncomingTypedLinksResponse$LinkSpecifiers": "<p>Returns one or more typed link specifiers as output.</p>",
"ListOutgoingTypedLinksResponse$TypedLinkSpecifiers": "<p>Returns a typed link specifier as output.</p>"
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -13894,6 +13894,10 @@
"WeightedCapacity":{
"shape":"Double",
"locationName":"weightedCapacity"
},
"TagSpecifications":{
"shape":"SpotFleetTagSpecificationList",
"locationName":"tagSpecificationSet"
}
}
},
@@ -14007,6 +14011,26 @@
"locationName":"item"
}
},
"SpotFleetTagSpecification":{
"type":"structure",
"members":{
"ResourceType":{
"shape":"ResourceType",
"locationName":"resourceType"
},
"Tags":{
"shape":"TagList",
"locationName":"tag"
}
}
},
"SpotFleetTagSpecificationList":{
"type":"list",
"member":{
"shape":"SpotFleetTagSpecification",
"locationName":"item"
}
},
"SpotInstanceRequest":{
"type":"structure",
"members":{

View File

@@ -1309,12 +1309,12 @@
}
},
"CreateNetworkInterfacePermissionRequest": {
"base": null,
"base": "<p>Contains the parameters for CreateNetworkInterfacePermission.</p>",
"refs": {
}
},
"CreateNetworkInterfacePermissionResult": {
"base": null,
"base": "<p>Contains the output of CreateNetworkInterfacePermission.</p>",
"refs": {
}
},
@@ -1660,12 +1660,12 @@
}
},
"DeleteNetworkInterfacePermissionRequest": {
"base": null,
"base": "<p>Contains the parameters for DeleteNetworkInterfacePermission.</p>",
"refs": {
}
},
"DeleteNetworkInterfacePermissionResult": {
"base": null,
"base": "<p>Contains the output for DeleteNetworkInterfacePermission.</p>",
"refs": {
}
},
@@ -2071,12 +2071,12 @@
}
},
"DescribeNetworkInterfacePermissionsRequest": {
"base": null,
"base": "<p>Contains the parameters for DescribeNetworkInterfacePermissions.</p>",
"refs": {
}
},
"DescribeNetworkInterfacePermissionsResult": {
"base": null,
"base": "<p>Contains the output for DescribeNetworkInterfacePermissions.</p>",
"refs": {
}
},
@@ -5063,6 +5063,7 @@
"ResourceType": {
"base": null,
"refs": {
"SpotFleetTagSpecification$ResourceType": "<p>The type of resource. Currently, the only resource type that is supported is <code>instance</code>.</p>",
"TagDescription$ResourceType": "<p>The resource type.</p>",
"TagSpecification$ResourceType": "<p>The type of resource to tag. Currently, the resource types that support tagging on creation are <code>instance</code> and <code>volume</code>. </p>"
}
@@ -5473,6 +5474,18 @@
"DescribeSpotFleetRequestsResponse$SpotFleetRequestConfigs": "<p>Information about the configuration of your Spot fleet.</p>"
}
},
"SpotFleetTagSpecification": {
"base": "<p>The tags for a Spot fleet resource.</p>",
"refs": {
"SpotFleetTagSpecificationList$member": null
}
},
"SpotFleetTagSpecificationList": {
"base": null,
"refs": {
"SpotFleetLaunchSpecification$TagSpecifications": "<p>The tags to apply during creation.</p>"
}
},
"SpotInstanceRequest": {
"base": "<p>Describes a Spot instance request.</p>",
"refs": {
@@ -6739,6 +6752,7 @@
"RouteTable$Tags": "<p>Any tags assigned to the route table.</p>",
"SecurityGroup$Tags": "<p>Any tags assigned to the security group.</p>",
"Snapshot$Tags": "<p>Any tags assigned to the snapshot.</p>",
"SpotFleetTagSpecification$Tags": "<p>The tags.</p>",
"SpotInstanceRequest$Tags": "<p>Any tags assigned to the resource.</p>",
"Subnet$Tags": "<p>Any tags assigned to the subnet.</p>",
"TagSpecification$Tags": "<p>The tags to apply to the resource.</p>",

View File

@@ -599,7 +599,10 @@
"Configurations":{"shape":"ConfigurationList"},
"SecurityConfiguration":{"shape":"XmlString"},
"AutoScalingRole":{"shape":"XmlString"},
"ScaleDownBehavior":{"shape":"ScaleDownBehavior"}
"ScaleDownBehavior":{"shape":"ScaleDownBehavior"},
"CustomAmiId":{"shape":"XmlStringMaxLen256"},
"EbsRootVolumeSize":{"shape":"Integer"},
"RepoUpgradeOnBoot":{"shape":"RepoUpgradeOnBoot"}
}
},
"ClusterId":{"type":"string"},
@@ -628,6 +631,7 @@
"INTERNAL_ERROR",
"VALIDATION_ERROR",
"INSTANCE_FAILURE",
"INSTANCE_FLEET_TIMEOUT",
"BOOTSTRAP_FAILURE",
"USER_REQUEST",
"STEP_FAILURE",
@@ -1639,6 +1643,13 @@
"members":{
}
},
"RepoUpgradeOnBoot":{
"type":"string",
"enum":[
"SECURITY",
"NONE"
]
},
"ResourceId":{"type":"string"},
"RunJobFlowInput":{
"type":"structure",
@@ -1665,7 +1676,10 @@
"Tags":{"shape":"TagList"},
"SecurityConfiguration":{"shape":"XmlString"},
"AutoScalingRole":{"shape":"XmlString"},
"ScaleDownBehavior":{"shape":"ScaleDownBehavior"}
"ScaleDownBehavior":{"shape":"ScaleDownBehavior"},
"CustomAmiId":{"shape":"XmlStringMaxLen256"},
"EbsRootVolumeSize":{"shape":"Integer"},
"RepoUpgradeOnBoot":{"shape":"RepoUpgradeOnBoot"}
}
},
"RunJobFlowOutput":{

View File

@@ -17,7 +17,7 @@
"ListClusters": "<p>Provides the status of all clusters visible to this AWS account. Allows you to filter the list of clusters based on certain criteria; for example, filtering by cluster creation date and time or by status. This call returns a maximum of 50 clusters per call, but returns a marker to track the paging of the cluster list across multiple ListClusters calls.</p>",
"ListInstanceFleets": "<p>Lists all available details about the instance fleets in a cluster.</p> <note> <p>The instance fleet configuration is available only in Amazon EMR versions 4.8.0 and later, excluding 5.0.x versions.</p> </note>",
"ListInstanceGroups": "<p>Provides all available details about the instance groups in a cluster.</p>",
"ListInstances": "<p>Provides information about the cluster instances that Amazon EMR provisions on behalf of a user when it creates the cluster. For example, this operation indicates when the EC2 instances reach the Ready state, when instances become available to Amazon EMR to use for jobs, and the IP addresses for cluster instances, etc.</p>",
"ListInstances": "<p>Provides information for all active EC2 instances and EC2 instances terminated in the last 30 days, up to a maximum of 2,000. EC2 instances in any of the following states are considered active: AWAITING_FULFILLMENT, PROVISIONING, BOOTSTRAPPING, RUNNING.</p>",
"ListSecurityConfigurations": "<p>Lists all the security configurations visible to this account, providing their creation dates and times, and their names. This call returns a maximum of 50 clusters per call, but returns a marker to track the paging of the cluster list across multiple ListSecurityConfigurations calls.</p>",
"ListSteps": "<p>Provides a list of steps for the cluster in reverse order unless you specify stepIds with the request.</p>",
"ModifyInstanceFleet": "<p>Modifies the target On-Demand and target Spot capacities for the instance fleet with the specified InstanceFleetID within the cluster specified using ClusterID. The call either succeeds or fails atomically.</p> <note> <p>The instance fleet configuration is available only in Amazon EMR versions 4.8.0 and later, excluding 5.0.x versions.</p> </note>",
@@ -86,7 +86,7 @@
}
},
"Application": {
"base": "<p>An application is any Amazon or third-party software that you can add to the cluster. This structure contains a list of strings that indicates the software to use with the cluster and accepts a user argument list. Amazon EMR accepts and forwards the argument list to the corresponding installation script as bootstrap action argument. For more information, see <a href=\"http://docs.aws.amazon.com/ElasticMapReduce/latest/ManagementGuide/emr-mapr.html\">Using the MapR Distribution for Hadoop</a>. Currently supported values are:</p> <ul> <li> <p>\"mapr-m3\" - launch the cluster using MapR M3 Edition.</p> </li> <li> <p>\"mapr-m5\" - launch the cluster using MapR M5 Edition.</p> </li> <li> <p>\"mapr\" with the user arguments specifying \"--edition,m3\" or \"--edition,m5\" - launch the cluster using MapR M3 or M5 Edition, respectively.</p> </li> </ul> <note> <p>In Amazon EMR releases 4.0 and greater, the only accepted parameter is the application name. To pass arguments to applications, you supply a configuration for each application.</p> </note>",
"base": "<p>An application is any Amazon or third-party software that you can add to the cluster. This structure contains a list of strings that indicates the software to use with the cluster and accepts a user argument list. Amazon EMR accepts and forwards the argument list to the corresponding installation script as bootstrap action argument. For more information, see <a href=\"http://docs.aws.amazon.com/ElasticMapReduce/latest/ManagementGuide/emr-mapr.html\">Using the MapR Distribution for Hadoop</a>. Currently supported values are:</p> <ul> <li> <p>\"mapr-m3\" - launch the cluster using MapR M3 Edition.</p> </li> <li> <p>\"mapr-m5\" - launch the cluster using MapR M5 Edition.</p> </li> <li> <p>\"mapr\" with the user arguments specifying \"--edition,m3\" or \"--edition,m5\" - launch the cluster using MapR M3 or M5 Edition, respectively.</p> </li> </ul> <note> <p>In Amazon EMR releases 4.x and later, the only accepted parameter is the application name. To pass arguments to applications, you supply a configuration for each application.</p> </note>",
"refs": {
"ApplicationList$member": null
}
@@ -95,7 +95,7 @@
"base": null,
"refs": {
"Cluster$Applications": "<p>The applications installed on this cluster.</p>",
"RunJobFlowInput$Applications": "<note> <p>Amazon EMR releases 4.x or later.</p> </note> <p>A list of applications for the cluster. Valid values are: \"Hadoop\", \"Hive\", \"Mahout\", \"Pig\", and \"Spark.\" They are case insensitive.</p>"
"RunJobFlowInput$Applications": "<p>For Amazon EMR releases 4.0 and later. A list of applications for the cluster. Valid values are: \"Hadoop\", \"Hive\", \"Mahout\", \"Pig\", and \"Spark.\" They are case insensitive.</p>"
}
},
"AutoScalingPolicy": {
@@ -321,13 +321,13 @@
"ConfigurationList": {
"base": null,
"refs": {
"Cluster$Configurations": "<note> <p>Amazon EMR releases 4.x or later.</p> </note> <p>The list of Configurations supplied to the EMR cluster.</p>",
"Cluster$Configurations": "<p>Applies only to Amazon EMR releases 4.x and later. The list of Configurations supplied to the EMR cluster.</p>",
"Configuration$Configurations": "<p>A list of additional configurations to apply within a configuration object.</p>",
"InstanceGroup$Configurations": "<note> <p>Amazon EMR releases 4.x or later.</p> </note> <p>The list of configurations supplied for an EMR cluster instance group. You can specify a separate configuration for each instance group (master, core, and task).</p>",
"InstanceGroupConfig$Configurations": "<note> <p>Amazon EMR releases 4.x or later.</p> </note> <p>The list of configurations supplied for an EMR cluster instance group. You can specify a separate configuration for each instance group (master, core, and task).</p>",
"InstanceTypeConfig$Configurations": "<p>A configuration classification that applies when provisioning cluster instances, which can include configurations for applications and software that run on the cluster.</p>",
"InstanceTypeSpecification$Configurations": "<p>A configuration classification that applies when provisioning cluster instances, which can include configurations for applications and software bundled with Amazon EMR.</p>",
"RunJobFlowInput$Configurations": "<note> <p>Amazon EMR releases 4.x or later.</p> </note> <p>The list of configurations supplied for the EMR cluster you are creating.</p>"
"RunJobFlowInput$Configurations": "<p>For Amazon EMR releases 4.0 and later. The list of configurations supplied for the EMR cluster you are creating.</p>"
}
},
"CreateSecurityConfigurationInput": {
@@ -840,6 +840,7 @@
"CloudWatchAlarmDefinition$EvaluationPeriods": "<p>The number of periods, expressed in seconds using <code>Period</code>, during which the alarm condition must exist before the alarm triggers automatic scaling activity. The default value is <code>1</code>.</p>",
"CloudWatchAlarmDefinition$Period": "<p>The period, in seconds, over which the statistic is applied. EMR CloudWatch metrics are emitted every five minutes (300 seconds), so if an EMR CloudWatch metric is specified, specify <code>300</code>.</p>",
"Cluster$NormalizedInstanceHours": "<p>An approximation of the cost of the cluster, represented in m1.small/hours. This value is incremented one time for every hour an m1.small instance runs. Larger instances are weighted more, so an EC2 instance that is roughly four times more expensive would result in the normalized instance hours being incremented by four. This result is only an approximation and does not reflect the actual billing rate.</p>",
"Cluster$EbsRootVolumeSize": "<p>The size, in GiB, of the EBS root device volume of the Linux AMI that is used for each EC2 instance. Available in Amazon EMR version 4.x and later.</p>",
"ClusterSummary$NormalizedInstanceHours": "<p>An approximation of the cost of the cluster, represented in m1.small/hours. This value is incremented one time for every hour an m1.small instance runs. Larger instances are weighted more, so an EC2 instance that is roughly four times more expensive would result in the normalized instance hours being incremented by four. This result is only an approximation and does not reflect the actual billing rate.</p>",
"EbsBlockDeviceConfig$VolumesPerInstance": "<p>Number of EBS volumes with a specific volume configuration that will be associated with every instance in the instance group</p>",
"InstanceGroup$RequestedInstanceCount": "<p>The target number of instances for the instance group.</p>",
@@ -852,6 +853,7 @@
"JobFlowInstancesConfig$InstanceCount": "<p>The number of EC2 instances in the cluster.</p>",
"JobFlowInstancesDetail$InstanceCount": "<p>The number of Amazon EC2 instances in the cluster. If the value is 1, the same instance serves as both the master and slave node. If the value is greater than 1, one instance is the master node and all others are slave nodes.</p>",
"JobFlowInstancesDetail$NormalizedInstanceHours": "<p>An approximation of the cost of the cluster, represented in m1.small/hours. This value is incremented one time for every hour that an m1.small runs. Larger instances are weighted more, so an Amazon EC2 instance that is roughly four times more expensive would result in the normalized instance hours being incremented by four. This result is only an approximation and does not reflect the actual billing rate.</p>",
"RunJobFlowInput$EbsRootVolumeSize": "<p>The size, in GiB, of the EBS root device volume of the Linux AMI that is used for each EC2 instance. Available in Amazon EMR version 4.x and later.</p>",
"ScalingConstraints$MinCapacity": "<p>The lower boundary of EC2 instances in an instance group below which scaling activities are not allowed to shrink. Scale-in activities will not terminate instances below this boundary.</p>",
"ScalingConstraints$MaxCapacity": "<p>The upper boundary of EC2 instances in an instance group beyond which scaling activities are not allowed to grow. Scale-out activities will not add instances beyond this boundary.</p>",
"ShrinkPolicy$DecommissionTimeout": "<p>The desired timeout for decommissioning an instance. Overrides the default YARN decommissioning timeout.</p>",
@@ -1055,14 +1057,14 @@
"NewSupportedProductsList": {
"base": null,
"refs": {
"RunJobFlowInput$NewSupportedProducts": "<note> <p>For Amazon EMR releases 3.x and 2.x. For Amazon EMR releases 4.x and greater, use Applications.</p> </note> <p>A list of strings that indicates third-party software to use with the job flow that accepts a user argument list. EMR accepts and forwards the argument list to the corresponding installation script as bootstrap action arguments. For more information, see \"Launch a Job Flow on the MapR Distribution for Hadoop\" in the <a href=\"http://docs.aws.amazon.com/http:/docs.aws.amazon.com/emr/latest/DeveloperGuide/emr-dg.pdf\">Amazon EMR Developer Guide</a>. Supported values are:</p> <ul> <li> <p>\"mapr-m3\" - launch the cluster using MapR M3 Edition.</p> </li> <li> <p>\"mapr-m5\" - launch the cluster using MapR M5 Edition.</p> </li> <li> <p>\"mapr\" with the user arguments specifying \"--edition,m3\" or \"--edition,m5\" - launch the job flow using MapR M3 or M5 Edition respectively.</p> </li> <li> <p>\"mapr-m7\" - launch the cluster using MapR M7 Edition.</p> </li> <li> <p>\"hunk\" - launch the cluster with the Hunk Big Data Analtics Platform.</p> </li> <li> <p>\"hue\"- launch the cluster with Hue installed.</p> </li> <li> <p>\"spark\" - launch the cluster with Apache Spark installed.</p> </li> <li> <p>\"ganglia\" - launch the cluster with the Ganglia Monitoring System installed.</p> </li> </ul>"
"RunJobFlowInput$NewSupportedProducts": "<note> <p>For Amazon EMR releases 3.x and 2.x. For Amazon EMR releases 4.x and later, use Applications.</p> </note> <p>A list of strings that indicates third-party software to use with the job flow that accepts a user argument list. EMR accepts and forwards the argument list to the corresponding installation script as bootstrap action arguments. For more information, see \"Launch a Job Flow on the MapR Distribution for Hadoop\" in the <a href=\"http://docs.aws.amazon.com/http:/docs.aws.amazon.com/emr/latest/DeveloperGuide/emr-dg.pdf\">Amazon EMR Developer Guide</a>. Supported values are:</p> <ul> <li> <p>\"mapr-m3\" - launch the cluster using MapR M3 Edition.</p> </li> <li> <p>\"mapr-m5\" - launch the cluster using MapR M5 Edition.</p> </li> <li> <p>\"mapr\" with the user arguments specifying \"--edition,m3\" or \"--edition,m5\" - launch the job flow using MapR M3 or M5 Edition respectively.</p> </li> <li> <p>\"mapr-m7\" - launch the cluster using MapR M7 Edition.</p> </li> <li> <p>\"hunk\" - launch the cluster with the Hunk Big Data Analtics Platform.</p> </li> <li> <p>\"hue\"- launch the cluster with Hue installed.</p> </li> <li> <p>\"spark\" - launch the cluster with Apache Spark installed.</p> </li> <li> <p>\"ganglia\" - launch the cluster with the Ganglia Monitoring System installed.</p> </li> </ul>"
}
},
"NonNegativeDouble": {
"base": null,
"refs": {
"CloudWatchAlarmDefinition$Threshold": "<p>The value against which the specified statistic is compared.</p>",
"InstanceTypeConfig$BidPriceAsPercentageOfOnDemandPrice": "<p>The bid price, as a percentage of On-Demand price, for each EC2 Spot instance as defined by <code>InstanceType</code>. Expressed as a number between 0 and 1000 (for example, 20 specifies 20%). If neither <code>BidPrice</code> nor <code>BidPriceAsPercentageOfOnDemandPrice</code> is provided, <code>BidPriceAsPercentageOfOnDemandPrice</code> defaults to 100%.</p>",
"InstanceTypeConfig$BidPriceAsPercentageOfOnDemandPrice": "<p>The bid price, as a percentage of On-Demand price, for each EC2 Spot instance as defined by <code>InstanceType</code>. Expressed as a number (for example, 20 specifies 20%). If neither <code>BidPrice</code> nor <code>BidPriceAsPercentageOfOnDemandPrice</code> is provided, <code>BidPriceAsPercentageOfOnDemandPrice</code> defaults to 100%.</p>",
"InstanceTypeSpecification$BidPriceAsPercentageOfOnDemandPrice": "<p>The bid price, as a percentage of On-Demand price, for each EC2 Spot instance as defined by <code>InstanceType</code>. Expressed as a number (for example, 20 specifies 20%).</p>"
}
},
@@ -1103,6 +1105,13 @@
"refs": {
}
},
"RepoUpgradeOnBoot": {
"base": null,
"refs": {
"Cluster$RepoUpgradeOnBoot": "<p>Applies only when <code>CustomAmiID</code> is used. Specifies the type of updates that are applied from the Amazon Linux AMI package repositories when an instance boots using the AMI.</p>",
"RunJobFlowInput$RepoUpgradeOnBoot": "<p>Applies only when <code>CustomAmiID</code> is used. Specifies which updates from the Amazon Linux AMI package repositories to apply automatically when the instance boots using the AMI. If omitted, the default is <code>SECURITY</code>, which indicates that only security updates are applied. If <code>NONE</code> is specified, no updates are applied, and all updates must be applied manually.</p>"
}
},
"ResourceId": {
"base": null,
"refs": {
@@ -1217,7 +1226,7 @@
"SpotProvisioningTimeoutAction": {
"base": null,
"refs": {
"SpotProvisioningSpecification$TimeoutAction": "<p>The action to take when <code>TargetSpotCapacity</code> has not been fulfilled when the <code>TimeoutDurationMinutes</code> has expired. Spot instances are not uprovisioned within the Spot provisioining timeout. Valid values are <code>TERMINATE_CLUSTER</code> and <code>SWITCH_TO_ON_DEMAND</code> to fulfill the remaining capacity.</p>"
"SpotProvisioningSpecification$TimeoutAction": "<p>The action to take when <code>TargetSpotCapacity</code> has not been fulfilled when the <code>TimeoutDurationMinutes</code> has expired. Spot instances are not uprovisioned within the Spot provisioining timeout. Valid values are <code>TERMINATE_CLUSTER</code> and <code>SWITCH_TO_ON_DEMAND</code>. SWITCH_TO_ON_DEMAND specifies that if no Spot instances are available, On-Demand Instances should be provisioned to fulfill any remaining Spot capacity.</p>"
}
},
"Statistic": {
@@ -1349,7 +1358,7 @@
"Cluster$LogUri": "<p>The path to the Amazon S3 location where logs for this cluster are stored.</p>",
"Cluster$RequestedAmiVersion": "<p>The AMI version requested for this cluster.</p>",
"Cluster$RunningAmiVersion": "<p>The AMI version running on this cluster.</p>",
"Cluster$ReleaseLabel": "<p>The release label for the Amazon EMR release. For Amazon EMR 3.x and 2.x AMIs, use amiVersion instead instead of ReleaseLabel.</p>",
"Cluster$ReleaseLabel": "<p>The release label for the Amazon EMR release.</p>",
"Cluster$ServiceRole": "<p>The IAM role that will be assumed by the Amazon EMR service to access AWS resources on your behalf.</p>",
"Cluster$MasterPublicDnsName": "<p>The public DNS name of the master EC2 instance.</p>",
"ClusterStateChangeReason$Message": "<p>The descriptive message for the state change reason.</p>",
@@ -1428,7 +1437,7 @@
"base": null,
"refs": {
"JobFlowDetail$SupportedProducts": "<p>A list of strings set by third party software when the job flow is launched. If you are not using third party software to manage the job flow this value is empty.</p>",
"RunJobFlowInput$SupportedProducts": "<note> <p>For Amazon EMR releases 3.x and 2.x. For Amazon EMR releases 4.x and greater, use Applications.</p> </note> <p>A list of strings that indicates third-party software to use. For more information, see <a href=\"http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/emr-supported-products.html\">Use Third Party Applications with Amazon EMR</a>. Currently supported values are:</p> <ul> <li> <p>\"mapr-m3\" - launch the job flow using MapR M3 Edition.</p> </li> <li> <p>\"mapr-m5\" - launch the job flow using MapR M5 Edition.</p> </li> </ul>"
"RunJobFlowInput$SupportedProducts": "<note> <p>For Amazon EMR releases 3.x and 2.x. For Amazon EMR releases 4.x and later, use Applications.</p> </note> <p>A list of strings that indicates third-party software to use. For more information, see <a href=\"http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/emr-supported-products.html\">Use Third Party Applications with Amazon EMR</a>. Currently supported values are:</p> <ul> <li> <p>\"mapr-m3\" - launch the job flow using MapR M3 Edition.</p> </li> <li> <p>\"mapr-m5\" - launch the job flow using MapR M5 Edition.</p> </li> </ul>"
}
},
"Tag": {
@@ -1474,7 +1483,7 @@
"InstanceFleetConfig$TargetSpotCapacity": "<p>The target capacity of Spot units for the instance fleet, which determines how many Spot instances to provision. When the instance fleet launches, Amazon EMR tries to provision Spot instances as specified by <a>InstanceTypeConfig</a>. Each instance configuration has a specified <code>WeightedCapacity</code>. When a Spot instance is provisioned, the <code>WeightedCapacity</code> units count toward the target capacity. Amazon EMR provisions instances until the target capacity is totally fulfilled, even if this results in an overage. For example, if there are 2 units remaining to fulfill capacity, and Amazon EMR can only provision an instance with a <code>WeightedCapacity</code> of 5 units, the instance is provisioned, and the target capacity is exceeded by 3 units.</p> <note> <p>If not specified or set to 0, only On-Demand instances are provisioned for the instance fleet. At least one of <code>TargetSpotCapacity</code> and <code>TargetOnDemandCapacity</code> should be greater than 0. For a master instance fleet, only one of <code>TargetSpotCapacity</code> and <code>TargetOnDemandCapacity</code> can be specified, and its value must be 1.</p> </note>",
"InstanceFleetModifyConfig$TargetOnDemandCapacity": "<p>The target capacity of On-Demand units for the instance fleet. For more information see <a>InstanceFleetConfig$TargetOnDemandCapacity</a>.</p>",
"InstanceFleetModifyConfig$TargetSpotCapacity": "<p>The target capacity of Spot units for the instance fleet. For more information, see <a>InstanceFleetConfig$TargetSpotCapacity</a>.</p>",
"InstanceTypeConfig$WeightedCapacity": "<p>The number of units that a provisioned instance of this type provides toward fulfilling the target capacities defined in <a>InstanceFleetConfig</a>. This value is 1 for a master instance fleet, and must be greater than 0 for core and task instance fleets. </p>",
"InstanceTypeConfig$WeightedCapacity": "<p>The number of units that a provisioned instance of this type provides toward fulfilling the target capacities defined in <a>InstanceFleetConfig</a>. This value is 1 for a master instance fleet, and must be 1 or greater for core and task instance fleets. Defaults to 1 if not specified. </p>",
"InstanceTypeSpecification$WeightedCapacity": "<p>The number of units that a provisioned instance of this type provides toward fulfilling the target capacities defined in <a>InstanceFleetConfig</a>. Capacity values represent performance characteristics such as vCPUs, memory, or I/O. If not specified, the default value is 1.</p>",
"SpotProvisioningSpecification$TimeoutDurationMinutes": "<p>The spot provisioning timeout period in minutes. If Spot instances are not provisioned within this time period, the <code>TimeOutAction</code> is taken. Minimum value is 5 and maximum value is 1440. The timeout applies only during initial provisioning, when the cluster is first created.</p>",
"SpotProvisioningSpecification$BlockDurationMinutes": "<p>The defined duration for Spot instances (also known as Spot blocks) in minutes. When specified, the Spot instance does not terminate before the defined duration expires, and defined duration pricing for Spot instances applies. Valid values are 60, 120, 180, 240, 300, or 360. The duration period starts as soon as a Spot instance receives its instance ID. At the end of the duration, Amazon EC2 marks the Spot instance for termination and provides a Spot instance termination notice, which gives the instance a two-minute warning before it terminates. </p>"
@@ -1538,6 +1547,7 @@
"AddJobFlowStepsInput$JobFlowId": "<p>A string that uniquely identifies the job flow. This identifier is returned by <a>RunJobFlow</a> and can also be obtained from <a>ListClusters</a>. </p>",
"BootstrapActionConfig$Name": "<p>The name of the bootstrap action.</p>",
"CancelStepsInput$ClusterId": "<p>The <code>ClusterID</code> for which specified steps will be canceled. Use <a>RunJobFlow</a> and <a>ListClusters</a> to get ClusterIDs. </p>",
"Cluster$CustomAmiId": "<p>Available only in Amazon EMR version 5.7.0 and later. The ID of a custom Amazon EBS-backed Linux AMI if the cluster uses a custom AMI.</p>",
"InstanceFleet$Name": "<p>A friendly name for the instance fleet.</p>",
"InstanceFleetConfig$Name": "<p>The friendly name of the instance fleet.</p>",
"InstanceGroupConfig$Name": "<p>Friendly name given to the instance group.</p>",
@@ -1551,7 +1561,7 @@
"InstanceTypeSpecification$BidPrice": "<p>The bid price for each EC2 Spot instance type as defined by <code>InstanceType</code>. Expressed in USD.</p>",
"JobFlowDetail$JobFlowId": "<p>The job flow identifier.</p>",
"JobFlowDetail$Name": "<p>The name of the job flow.</p>",
"JobFlowDetail$AmiVersion": "<p>The version of the AMI used to initialize Amazon EC2 instances in the job flow. For a list of AMI versions currently supported by Amazon EMR, see <a href=\"http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/EnvironmentConfig_AMIVersion.html#ami-versions-supported\">AMI Versions Supported in EMR</a> in the <i>Amazon EMR Developer Guide.</i> </p>",
"JobFlowDetail$AmiVersion": "<p>Used only for version 2.x and 3.x of Amazon EMR. The version of the AMI used to initialize Amazon EC2 instances in the job flow. For a list of AMI versions supported by Amazon EMR, see <a href=\"http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/EnvironmentConfig_AMIVersion.html#ami-versions-supported\">AMI Versions Supported in EMR</a> in the <i>Amazon EMR Developer Guide.</i> </p>",
"JobFlowInstancesConfig$Ec2KeyName": "<p>The name of the EC2 key pair that can be used to ssh to the master node as the user called \"hadoop.\"</p>",
"JobFlowInstancesConfig$HadoopVersion": "<p>The Hadoop version for the cluster. Valid inputs are \"0.18\" (deprecated), \"0.20\" (deprecated), \"0.20.205\" (deprecated), \"1.0.3\", \"2.2.0\", or \"2.4.0\". If you do not set this value, the default of 0.18 is used, unless the AmiVersion parameter is set in the RunJobFlow call, in which case the default version of Hadoop for that AMI version is used.</p>",
"JobFlowInstancesConfig$Ec2SubnetId": "<p>Applies to clusters that use the uniform instance group configuration. To launch the cluster in Amazon Virtual Private Cloud (Amazon VPC), set this parameter to the identifier of the Amazon VPC subnet where you want the cluster to launch. If you do not specify this value, the cluster launches in the normal Amazon Web Services cloud, outside of an Amazon VPC, if the account launching the cluster supports EC2 Classic networks in the region where the cluster launches.</p> <p>Amazon VPC currently does not support cluster compute quadruple extra large (cc1.4xlarge) instances. Thus you cannot specify the cc1.4xlarge instance type for clusters launched in an Amazon VPC.</p>",
@@ -1562,8 +1572,9 @@
"JobFlowInstancesDetail$Ec2SubnetId": "<p>For clusters launched within Amazon Virtual Private Cloud, this is the identifier of the subnet where the cluster was launched.</p>",
"JobFlowInstancesDetail$HadoopVersion": "<p>The Hadoop version for the cluster.</p>",
"RunJobFlowInput$Name": "<p>The name of the job flow.</p>",
"RunJobFlowInput$AmiVersion": "<note> <p>For Amazon EMR releases 3.x and 2.x. For Amazon EMR releases 4.x and greater, use ReleaseLabel.</p> </note> <p>The version of the Amazon Machine Image (AMI) to use when launching Amazon EC2 instances in the job flow. The following values are valid:</p> <ul> <li> <p>The version number of the AMI to use, for example, \"2.0.\"</p> </li> </ul> <p>If the AMI supports multiple versions of Hadoop (for example, AMI 1.0 supports both Hadoop 0.18 and 0.20) you can use the <a>JobFlowInstancesConfig</a> <code>HadoopVersion</code> parameter to modify the version of Hadoop from the defaults shown above.</p> <p>For details about the AMI versions currently supported by Amazon Elastic MapReduce, see <a href=\"http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/EnvironmentConfig_AMIVersion.html#ami-versions-supported\">AMI Versions Supported in Elastic MapReduce</a> in the <i>Amazon Elastic MapReduce Developer Guide.</i> </p> <note> <p>Previously, the EMR AMI version API parameter options allowed you to use latest for the latest AMI version rather than specify a numerical value. Some regions no longer support this deprecated option as they only have a newer release label version of EMR, which requires you to specify an EMR release label release (EMR 4.x or later).</p> </note>",
"RunJobFlowInput$ReleaseLabel": "<note> <p>Amazon EMR releases 4.x or later.</p> </note> <p>The release label for the Amazon EMR release. For Amazon EMR 3.x and 2.x AMIs, use amiVersion instead instead of ReleaseLabel.</p>",
"RunJobFlowInput$AmiVersion": "<p>For Amazon EMR AMI versions 3.x and 2.x. For Amazon EMR releases 4.0 and later, the Linux AMI is determined by the <code>ReleaseLabel</code> specified or by <code>CustomAmiID</code>. The version of the Amazon Machine Image (AMI) to use when launching Amazon EC2 instances in the job flow. For details about the AMI versions currently supported in EMR version 3.x and 2.x, see <a href=\"ElasticMapReduce/latest/DeveloperGuide/emr-dg.pdf#nameddest=ami-versions-supported\">AMI Versions Supported in EMR</a> in the <i>Amazon EMR Developer Guide</i>. </p> <p>If the AMI supports multiple versions of Hadoop (for example, AMI 1.0 supports both Hadoop 0.18 and 0.20), you can use the <a>JobFlowInstancesConfig</a> <code>HadoopVersion</code> parameter to modify the version of Hadoop from the defaults shown above.</p> <note> <p>Previously, the EMR AMI version API parameter options allowed you to use latest for the latest AMI version rather than specify a numerical value. Some regions no longer support this deprecated option as they only have a newer release label version of EMR, which requires you to specify an EMR release label release (EMR 4.x or later).</p> </note>",
"RunJobFlowInput$ReleaseLabel": "<p> The release label for the Amazon EMR release. For Amazon EMR 3.x and 2.x AMIs, use <code>AmiVersion</code> instead.</p>",
"RunJobFlowInput$CustomAmiId": "<p>Available only in Amazon EMR version 5.7.0 and later. The ID of a custom Amazon EBS-backed Linux AMI. If specified, Amazon EMR uses this AMI when it launches cluster EC2 instances. For more information about custom AMIs in Amazon EMR, see <a href=\"http://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-custom-ami.html\">Using a Custom AMI</a> in the <i>Amazon EMR Management Guide</i>. If omitted, the cluster uses the base Linux AMI for the <code>ReleaseLabel</code> specified. For Amazon EMR versions 2.x and 3.x, use <code>AmiVersion</code> instead.</p> <p>For information about creating a custom AMI, see <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami-ebs.html\">Creating an Amazon EBS-Backed Linux AMI</a> in the <i>Amazon Elastic Compute Cloud User Guide for Linux Instances</i>. For information about finding an AMI ID, see <a href=\"http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/finding-an-ami.html\">Finding a Linux AMI</a>. </p>",
"RunJobFlowOutput$JobFlowId": "<p>An unique identifier for the job flow.</p>",
"SecurityGroupsList$member": null,
"StepConfig$Name": "<p>The name of the step.</p>",
@@ -1576,8 +1587,8 @@
"XmlStringMaxLen256List": {
"base": null,
"refs": {
"Ec2InstanceAttributes$RequestedEc2SubnetIds": "<p>Applies to clusters configured with the instance fleets option. Specifies the unique identifier of one or more Amazon EC2 subnets in which to launch EC2 cluster instances. Amazon EMR chooses the EC2 subnet with the best performance and cost characteristics from among the list of RequestedEc2SubnetIds and launches all cluster instances within that subnet. If this value is not specified, and the account supports EC2-Classic networks, the cluster launches instances in the EC2-Classic network and uses Requested</p>",
"Ec2InstanceAttributes$RequestedEc2AvailabilityZones": "<p>Applies to clusters configured with the The list of availability zones to choose from. The service will choose the availability zone with the best mix of available capacity and lowest cost to launch the cluster. If you do not specify this value, the cluster is launched in any availability zone that the customer account has access to.</p>",
"Ec2InstanceAttributes$RequestedEc2SubnetIds": "<p>Applies to clusters configured with the instance fleets option. Specifies the unique identifier of one or more Amazon EC2 subnets in which to launch EC2 cluster instances. Subnets must exist within the same VPC. Amazon EMR chooses the EC2 subnet with the best fit from among the list of <code>RequestedEc2SubnetIds</code>, and then launches all cluster instances within that Subnet. If this value is not specified, and the account and region support EC2-Classic networks, the cluster launches instances in the EC2-Classic network and uses <code>RequestedEc2AvailabilityZones</code> instead of this setting. If EC2-Classic is not supported, and no Subnet is specified, Amazon EMR chooses the subnet for you. <code>RequestedEc2SubnetIDs</code> and <code>RequestedEc2AvailabilityZones</code> cannot be specified together.</p>",
"Ec2InstanceAttributes$RequestedEc2AvailabilityZones": "<p>Applies to clusters configured with the instance fleets option. Specifies one or more Availability Zones in which to launch EC2 cluster instances when the EC2-Classic network configuration is supported. Amazon EMR chooses the Availability Zone with the best fit from among the list of <code>RequestedEc2AvailabilityZones</code>, and then launches all cluster instances within that Availability Zone. If you do not specify this value, Amazon EMR chooses the Availability Zone for you. <code>RequestedEc2SubnetIDs</code> and <code>RequestedEc2AvailabilityZones</code> cannot be specified together.</p>",
"JobFlowInstancesConfig$Ec2SubnetIds": "<p>Applies to clusters that use the instance fleet configuration. When multiple EC2 subnet IDs are specified, Amazon EMR evaluates them and launches instances in the optimal subnet.</p> <note> <p>The instance fleet configuration is available only in Amazon EMR versions 4.8.0 and later, excluding 5.0.x versions.</p> </note>",
"PlacementType$AvailabilityZones": "<p>When multiple Availability Zones are specified, Amazon EMR evaluates them and launches instances in the optimal Availability Zone. <code>AvailabilityZones</code> is used for instance fleets, while <code>AvailabilityZone</code> (singular) is used for uniform instance groups.</p> <note> <p>The instance fleet configuration is available only in Amazon EMR versions 4.8.0 and later, excluding 5.0.x versions.</p> </note>"
}

View File

@@ -3,47 +3,115 @@
package restxml_test
import (
"net/http"
"net/http/httptest"
"os"
"testing"
"bytes"
"encoding/xml"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/awstesting"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/private/protocol/restxml"
"github.com/aws/aws-sdk-go/service/cloudfront"
"github.com/aws/aws-sdk-go/service/s3"
)
func BenchmarkRESTXMLBuild_Complex_cloudfrontCreateDistribution(b *testing.B) {
params := restxmlBuildCreateDistroParms
var (
cloudfrontSvc *cloudfront.CloudFront
s3Svc *s3.S3
)
op := &request.Operation{
Name: "CreateDistribution",
HTTPMethod: "POST",
HTTPPath: "/2015-04-17/distribution/{DistributionId}/invalidation",
}
func TestMain(m *testing.M) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
benchRESTXMLBuild(b, op, params)
sess := session.Must(session.NewSession(&aws.Config{
Credentials: credentials.NewStaticCredentials("Key", "Secret", "Token"),
Endpoint: aws.String(server.URL),
S3ForcePathStyle: aws.Bool(true),
DisableSSL: aws.Bool(true),
Region: aws.String(endpoints.UsWest2RegionID),
}))
cloudfrontSvc = cloudfront.New(sess)
s3Svc = s3.New(sess)
c := m.Run()
server.Close()
os.Exit(c)
}
func BenchmarkRESTXMLBuild_Simple_cloudfrontDeleteStreamingDistribution(b *testing.B) {
params := &cloudfront.DeleteDistributionInput{
Id: aws.String("string"), // Required
IfMatch: aws.String("string"),
}
op := &request.Operation{
Name: "DeleteStreamingDistribution",
HTTPMethod: "DELETE",
HTTPPath: "/2015-04-17/streaming-distribution/{Id}",
}
benchRESTXMLBuild(b, op, params)
func BenchmarkRESTXMLBuild_Complex_CFCreateDistro(b *testing.B) {
params := cloudfrontCreateDistributionInput()
benchRESTXMLBuild(b, func() *request.Request {
req, _ := cloudfrontSvc.CreateDistributionRequest(params)
return req
})
}
func BenchmarkEncodingXMLMarshal_Simple_cloudfrontDeleteStreamingDistribution(b *testing.B) {
params := &cloudfront.DeleteDistributionInput{
Id: aws.String("string"), // Required
IfMatch: aws.String("string"),
}
func BenchmarkRESTXMLRequest_Complex_CFCreateDistro(b *testing.B) {
benchRESTXMLRequest(b, func() *request.Request {
req, _ := cloudfrontSvc.CreateDistributionRequest(cloudfrontCreateDistributionInput())
return req
})
}
func BenchmarkRESTXMLBuild_Simple_CFDeleteDistro(b *testing.B) {
params := cloudfrontDeleteDistributionInput()
benchRESTXMLBuild(b, func() *request.Request {
req, _ := cloudfrontSvc.DeleteDistributionRequest(params)
return req
})
}
func BenchmarkRESTXMLRequest_Simple_CFDeleteDistro(b *testing.B) {
benchRESTXMLRequest(b, func() *request.Request {
req, _ := cloudfrontSvc.DeleteDistributionRequest(cloudfrontDeleteDistributionInput())
return req
})
}
func BenchmarkRESTXMLBuild_REST_S3HeadObject(b *testing.B) {
params := s3HeadObjectInput()
benchRESTXMLBuild(b, func() *request.Request {
req, _ := s3Svc.HeadObjectRequest(params)
return req
})
}
func BenchmarkRESTXMLRequest_REST_S3HeadObject(b *testing.B) {
benchRESTXMLRequest(b, func() *request.Request {
req, _ := s3Svc.HeadObjectRequest(s3HeadObjectInput())
return req
})
}
func BenchmarkRESTXMLBuild_XML_S3PutObjectAcl(b *testing.B) {
params := s3PutObjectAclInput()
benchRESTXMLBuild(b, func() *request.Request {
req, _ := s3Svc.PutObjectAclRequest(params)
return req
})
}
func BenchmarkRESTXMLRequest_XML_S3PutObjectAcl(b *testing.B) {
benchRESTXMLRequest(b, func() *request.Request {
req, _ := s3Svc.PutObjectAclRequest(s3PutObjectAclInput())
return req
})
}
func BenchmarkEncodingXML_Simple(b *testing.B) {
params := cloudfrontDeleteDistributionInput()
for i := 0; i < b.N; i++ {
buf := &bytes.Buffer{}
@@ -54,118 +122,39 @@ func BenchmarkEncodingXMLMarshal_Simple_cloudfrontDeleteStreamingDistribution(b
}
}
func benchRESTXMLBuild(b *testing.B, op *request.Operation, params interface{}) {
svc := awstesting.NewClient()
svc.ServiceName = "cloudfront"
svc.APIVersion = "2015-04-17"
func benchRESTXMLBuild(b *testing.B, reqFn func() *request.Request) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
r := svc.NewRequest(op, params, nil)
restxml.Build(r)
if r.Error != nil {
b.Fatal("Unexpected error", r.Error)
req := reqFn()
restxml.Build(req)
if req.Error != nil {
b.Fatal("Unexpected error", req.Error)
}
}
}
var restxmlBuildCreateDistroParms = &cloudfront.CreateDistributionInput{
DistributionConfig: &cloudfront.DistributionConfig{ // Required
CallerReference: aws.String("string"), // Required
Comment: aws.String("string"), // Required
DefaultCacheBehavior: &cloudfront.DefaultCacheBehavior{ // Required
ForwardedValues: &cloudfront.ForwardedValues{ // Required
Cookies: &cloudfront.CookiePreference{ // Required
Forward: aws.String("ItemSelection"), // Required
WhitelistedNames: &cloudfront.CookieNames{
Quantity: aws.Int64(1), // Required
Items: []*string{
aws.String("string"), // Required
// More values...
},
},
},
QueryString: aws.Bool(true), // Required
Headers: &cloudfront.Headers{
Quantity: aws.Int64(1), // Required
Items: []*string{
aws.String("string"), // Required
// More values...
},
},
},
MinTTL: aws.Int64(1), // Required
TargetOriginId: aws.String("string"), // Required
TrustedSigners: &cloudfront.TrustedSigners{ // Required
Enabled: aws.Bool(true), // Required
Quantity: aws.Int64(1), // Required
Items: []*string{
aws.String("string"), // Required
// More values...
},
},
ViewerProtocolPolicy: aws.String("ViewerProtocolPolicy"), // Required
AllowedMethods: &cloudfront.AllowedMethods{
Items: []*string{ // Required
aws.String("Method"), // Required
// More values...
},
Quantity: aws.Int64(1), // Required
CachedMethods: &cloudfront.CachedMethods{
Items: []*string{ // Required
aws.String("Method"), // Required
// More values...
},
Quantity: aws.Int64(1), // Required
},
},
DefaultTTL: aws.Int64(1),
MaxTTL: aws.Int64(1),
SmoothStreaming: aws.Bool(true),
},
Enabled: aws.Bool(true), // Required
Origins: &cloudfront.Origins{ // Required
Quantity: aws.Int64(1), // Required
Items: []*cloudfront.Origin{
{ // Required
DomainName: aws.String("string"), // Required
Id: aws.String("string"), // Required
CustomOriginConfig: &cloudfront.CustomOriginConfig{
HTTPPort: aws.Int64(1), // Required
HTTPSPort: aws.Int64(1), // Required
OriginProtocolPolicy: aws.String("OriginProtocolPolicy"), // Required
},
OriginPath: aws.String("string"),
S3OriginConfig: &cloudfront.S3OriginConfig{
OriginAccessIdentity: aws.String("string"), // Required
},
},
// More values...
},
},
Aliases: &cloudfront.Aliases{
Quantity: aws.Int64(1), // Required
Items: []*string{
aws.String("string"), // Required
// More values...
},
},
CacheBehaviors: &cloudfront.CacheBehaviors{
Quantity: aws.Int64(1), // Required
Items: []*cloudfront.CacheBehavior{
{ // Required
ForwardedValues: &cloudfront.ForwardedValues{ // Required
Cookies: &cloudfront.CookiePreference{ // Required
Forward: aws.String("ItemSelection"), // Required
WhitelistedNames: &cloudfront.CookieNames{
Quantity: aws.Int64(1), // Required
Items: []*string{
aws.String("string"), // Required
// More values...
},
},
},
QueryString: aws.Bool(true), // Required
Headers: &cloudfront.Headers{
func benchRESTXMLRequest(b *testing.B, reqFn func() *request.Request) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
err := reqFn().Send()
if err != nil {
b.Fatal("Unexpected error", err)
}
}
}
func cloudfrontCreateDistributionInput() *cloudfront.CreateDistributionInput {
return &cloudfront.CreateDistributionInput{
DistributionConfig: &cloudfront.DistributionConfig{ // Required
CallerReference: aws.String("string"), // Required
Comment: aws.String("string"), // Required
DefaultCacheBehavior: &cloudfront.DefaultCacheBehavior{ // Required
ForwardedValues: &cloudfront.ForwardedValues{ // Required
Cookies: &cloudfront.CookiePreference{ // Required
Forward: aws.String("ItemSelection"), // Required
WhitelistedNames: &cloudfront.CookieNames{
Quantity: aws.Int64(1), // Required
Items: []*string{
aws.String("string"), // Required
@@ -173,74 +162,205 @@ var restxmlBuildCreateDistroParms = &cloudfront.CreateDistributionInput{
},
},
},
MinTTL: aws.Int64(1), // Required
PathPattern: aws.String("string"), // Required
TargetOriginId: aws.String("string"), // Required
TrustedSigners: &cloudfront.TrustedSigners{ // Required
Enabled: aws.Bool(true), // Required
Quantity: aws.Int64(1), // Required
QueryString: aws.Bool(true), // Required
Headers: &cloudfront.Headers{
Quantity: aws.Int64(1), // Required
Items: []*string{
aws.String("string"), // Required
// More values...
},
},
ViewerProtocolPolicy: aws.String("ViewerProtocolPolicy"), // Required
AllowedMethods: &cloudfront.AllowedMethods{
},
MinTTL: aws.Int64(1), // Required
TargetOriginId: aws.String("string"), // Required
TrustedSigners: &cloudfront.TrustedSigners{ // Required
Enabled: aws.Bool(true), // Required
Quantity: aws.Int64(1), // Required
Items: []*string{
aws.String("string"), // Required
// More values...
},
},
ViewerProtocolPolicy: aws.String("ViewerProtocolPolicy"), // Required
AllowedMethods: &cloudfront.AllowedMethods{
Items: []*string{ // Required
aws.String("Method"), // Required
// More values...
},
Quantity: aws.Int64(1), // Required
CachedMethods: &cloudfront.CachedMethods{
Items: []*string{ // Required
aws.String("Method"), // Required
// More values...
},
Quantity: aws.Int64(1), // Required
CachedMethods: &cloudfront.CachedMethods{
Items: []*string{ // Required
aws.String("Method"), // Required
// More values...
},
Quantity: aws.Int64(1), // Required
},
},
DefaultTTL: aws.Int64(1),
MaxTTL: aws.Int64(1),
SmoothStreaming: aws.Bool(true),
},
Enabled: aws.Bool(true), // Required
Origins: &cloudfront.Origins{ // Required
Quantity: aws.Int64(1), // Required
Items: []*cloudfront.Origin{
{ // Required
DomainName: aws.String("string"), // Required
Id: aws.String("string"), // Required
CustomOriginConfig: &cloudfront.CustomOriginConfig{
HTTPPort: aws.Int64(1), // Required
HTTPSPort: aws.Int64(1), // Required
OriginProtocolPolicy: aws.String("OriginProtocolPolicy"), // Required
},
OriginPath: aws.String("string"),
S3OriginConfig: &cloudfront.S3OriginConfig{
OriginAccessIdentity: aws.String("string"), // Required
},
},
DefaultTTL: aws.Int64(1),
MaxTTL: aws.Int64(1),
SmoothStreaming: aws.Bool(true),
// More values...
},
// More values...
},
},
CustomErrorResponses: &cloudfront.CustomErrorResponses{
Quantity: aws.Int64(1), // Required
Items: []*cloudfront.CustomErrorResponse{
{ // Required
ErrorCode: aws.Int64(1), // Required
ErrorCachingMinTTL: aws.Int64(1),
ResponseCode: aws.String("string"),
ResponsePagePath: aws.String("string"),
},
// More values...
},
},
DefaultRootObject: aws.String("string"),
Logging: &cloudfront.LoggingConfig{
Bucket: aws.String("string"), // Required
Enabled: aws.Bool(true), // Required
IncludeCookies: aws.Bool(true), // Required
Prefix: aws.String("string"), // Required
},
PriceClass: aws.String("PriceClass"),
Restrictions: &cloudfront.Restrictions{
GeoRestriction: &cloudfront.GeoRestriction{ // Required
Quantity: aws.Int64(1), // Required
RestrictionType: aws.String("GeoRestrictionType"), // Required
Aliases: &cloudfront.Aliases{
Quantity: aws.Int64(1), // Required
Items: []*string{
aws.String("string"), // Required
// More values...
},
},
CacheBehaviors: &cloudfront.CacheBehaviors{
Quantity: aws.Int64(1), // Required
Items: []*cloudfront.CacheBehavior{
{ // Required
ForwardedValues: &cloudfront.ForwardedValues{ // Required
Cookies: &cloudfront.CookiePreference{ // Required
Forward: aws.String("ItemSelection"), // Required
WhitelistedNames: &cloudfront.CookieNames{
Quantity: aws.Int64(1), // Required
Items: []*string{
aws.String("string"), // Required
// More values...
},
},
},
QueryString: aws.Bool(true), // Required
Headers: &cloudfront.Headers{
Quantity: aws.Int64(1), // Required
Items: []*string{
aws.String("string"), // Required
// More values...
},
},
},
MinTTL: aws.Int64(1), // Required
PathPattern: aws.String("string"), // Required
TargetOriginId: aws.String("string"), // Required
TrustedSigners: &cloudfront.TrustedSigners{ // Required
Enabled: aws.Bool(true), // Required
Quantity: aws.Int64(1), // Required
Items: []*string{
aws.String("string"), // Required
// More values...
},
},
ViewerProtocolPolicy: aws.String("ViewerProtocolPolicy"), // Required
AllowedMethods: &cloudfront.AllowedMethods{
Items: []*string{ // Required
aws.String("Method"), // Required
// More values...
},
Quantity: aws.Int64(1), // Required
CachedMethods: &cloudfront.CachedMethods{
Items: []*string{ // Required
aws.String("Method"), // Required
// More values...
},
Quantity: aws.Int64(1), // Required
},
},
DefaultTTL: aws.Int64(1),
MaxTTL: aws.Int64(1),
SmoothStreaming: aws.Bool(true),
},
// More values...
},
},
CustomErrorResponses: &cloudfront.CustomErrorResponses{
Quantity: aws.Int64(1), // Required
Items: []*cloudfront.CustomErrorResponse{
{ // Required
ErrorCode: aws.Int64(1), // Required
ErrorCachingMinTTL: aws.Int64(1),
ResponseCode: aws.String("string"),
ResponsePagePath: aws.String("string"),
},
// More values...
},
},
DefaultRootObject: aws.String("string"),
Logging: &cloudfront.LoggingConfig{
Bucket: aws.String("string"), // Required
Enabled: aws.Bool(true), // Required
IncludeCookies: aws.Bool(true), // Required
Prefix: aws.String("string"), // Required
},
PriceClass: aws.String("PriceClass"),
Restrictions: &cloudfront.Restrictions{
GeoRestriction: &cloudfront.GeoRestriction{ // Required
Quantity: aws.Int64(1), // Required
RestrictionType: aws.String("GeoRestrictionType"), // Required
Items: []*string{
aws.String("string"), // Required
// More values...
},
},
},
ViewerCertificate: &cloudfront.ViewerCertificate{
CloudFrontDefaultCertificate: aws.Bool(true),
IAMCertificateId: aws.String("string"),
MinimumProtocolVersion: aws.String("MinimumProtocolVersion"),
SSLSupportMethod: aws.String("SSLSupportMethod"),
},
},
ViewerCertificate: &cloudfront.ViewerCertificate{
CloudFrontDefaultCertificate: aws.Bool(true),
IAMCertificateId: aws.String("string"),
MinimumProtocolVersion: aws.String("MinimumProtocolVersion"),
SSLSupportMethod: aws.String("SSLSupportMethod"),
},
},
}
}
func cloudfrontDeleteDistributionInput() *cloudfront.DeleteDistributionInput {
return &cloudfront.DeleteDistributionInput{
Id: aws.String("string"), // Required
IfMatch: aws.String("string"),
}
}
func s3HeadObjectInput() *s3.HeadObjectInput {
return &s3.HeadObjectInput{
Bucket: aws.String("somebucketname"),
Key: aws.String("keyname"),
VersionId: aws.String("someVersion"),
IfMatch: aws.String("IfMatch"),
}
}
func s3PutObjectAclInput() *s3.PutObjectAclInput {
return &s3.PutObjectAclInput{
Bucket: aws.String("somebucketname"),
Key: aws.String("keyname"),
AccessControlPolicy: &s3.AccessControlPolicy{
Grants: []*s3.Grant{
{
Grantee: &s3.Grantee{
DisplayName: aws.String("someName"),
EmailAddress: aws.String("someAddr"),
ID: aws.String("someID"),
Type: aws.String(s3.TypeCanonicalUser),
URI: aws.String("someURI"),
},
Permission: aws.String(s3.PermissionWrite),
},
},
Owner: &s3.Owner{
DisplayName: aws.String("howdy"),
ID: aws.String("someID"),
},
},
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -64,6 +64,10 @@ type AppStreamAPI interface {
AssociateFleetWithContext(aws.Context, *appstream.AssociateFleetInput, ...request.Option) (*appstream.AssociateFleetOutput, error)
AssociateFleetRequest(*appstream.AssociateFleetInput) (*request.Request, *appstream.AssociateFleetOutput)
CreateDirectoryConfig(*appstream.CreateDirectoryConfigInput) (*appstream.CreateDirectoryConfigOutput, error)
CreateDirectoryConfigWithContext(aws.Context, *appstream.CreateDirectoryConfigInput, ...request.Option) (*appstream.CreateDirectoryConfigOutput, error)
CreateDirectoryConfigRequest(*appstream.CreateDirectoryConfigInput) (*request.Request, *appstream.CreateDirectoryConfigOutput)
CreateFleet(*appstream.CreateFleetInput) (*appstream.CreateFleetOutput, error)
CreateFleetWithContext(aws.Context, *appstream.CreateFleetInput, ...request.Option) (*appstream.CreateFleetOutput, error)
CreateFleetRequest(*appstream.CreateFleetInput) (*request.Request, *appstream.CreateFleetOutput)
@@ -76,6 +80,10 @@ type AppStreamAPI interface {
CreateStreamingURLWithContext(aws.Context, *appstream.CreateStreamingURLInput, ...request.Option) (*appstream.CreateStreamingURLOutput, error)
CreateStreamingURLRequest(*appstream.CreateStreamingURLInput) (*request.Request, *appstream.CreateStreamingURLOutput)
DeleteDirectoryConfig(*appstream.DeleteDirectoryConfigInput) (*appstream.DeleteDirectoryConfigOutput, error)
DeleteDirectoryConfigWithContext(aws.Context, *appstream.DeleteDirectoryConfigInput, ...request.Option) (*appstream.DeleteDirectoryConfigOutput, error)
DeleteDirectoryConfigRequest(*appstream.DeleteDirectoryConfigInput) (*request.Request, *appstream.DeleteDirectoryConfigOutput)
DeleteFleet(*appstream.DeleteFleetInput) (*appstream.DeleteFleetOutput, error)
DeleteFleetWithContext(aws.Context, *appstream.DeleteFleetInput, ...request.Option) (*appstream.DeleteFleetOutput, error)
DeleteFleetRequest(*appstream.DeleteFleetInput) (*request.Request, *appstream.DeleteFleetOutput)
@@ -84,6 +92,10 @@ type AppStreamAPI interface {
DeleteStackWithContext(aws.Context, *appstream.DeleteStackInput, ...request.Option) (*appstream.DeleteStackOutput, error)
DeleteStackRequest(*appstream.DeleteStackInput) (*request.Request, *appstream.DeleteStackOutput)
DescribeDirectoryConfigs(*appstream.DescribeDirectoryConfigsInput) (*appstream.DescribeDirectoryConfigsOutput, error)
DescribeDirectoryConfigsWithContext(aws.Context, *appstream.DescribeDirectoryConfigsInput, ...request.Option) (*appstream.DescribeDirectoryConfigsOutput, error)
DescribeDirectoryConfigsRequest(*appstream.DescribeDirectoryConfigsInput) (*request.Request, *appstream.DescribeDirectoryConfigsOutput)
DescribeFleets(*appstream.DescribeFleetsInput) (*appstream.DescribeFleetsOutput, error)
DescribeFleetsWithContext(aws.Context, *appstream.DescribeFleetsInput, ...request.Option) (*appstream.DescribeFleetsOutput, error)
DescribeFleetsRequest(*appstream.DescribeFleetsInput) (*request.Request, *appstream.DescribeFleetsOutput)
@@ -124,6 +136,10 @@ type AppStreamAPI interface {
StopFleetWithContext(aws.Context, *appstream.StopFleetInput, ...request.Option) (*appstream.StopFleetOutput, error)
StopFleetRequest(*appstream.StopFleetInput) (*request.Request, *appstream.StopFleetOutput)
UpdateDirectoryConfig(*appstream.UpdateDirectoryConfigInput) (*appstream.UpdateDirectoryConfigOutput, error)
UpdateDirectoryConfigWithContext(aws.Context, *appstream.UpdateDirectoryConfigInput, ...request.Option) (*appstream.UpdateDirectoryConfigOutput, error)
UpdateDirectoryConfigRequest(*appstream.UpdateDirectoryConfigInput) (*request.Request, *appstream.UpdateDirectoryConfigOutput)
UpdateFleet(*appstream.UpdateFleetInput) (*appstream.UpdateFleetOutput, error)
UpdateFleetWithContext(aws.Context, *appstream.UpdateFleetInput, ...request.Option) (*appstream.UpdateFleetOutput, error)
UpdateFleetRequest(*appstream.UpdateFleetInput) (*request.Request, *appstream.UpdateFleetOutput)

View File

@@ -33,17 +33,17 @@ func (c *AppStream) WaitUntilFleetStartedWithContext(ctx aws.Context, input *Des
Acceptors: []request.WaiterAcceptor{
{
State: request.SuccessWaiterState,
Matcher: request.PathAllWaiterMatch, Argument: "fleets[].state",
Matcher: request.PathAllWaiterMatch, Argument: "Fleets[].State",
Expected: "ACTIVE",
},
{
State: request.FailureWaiterState,
Matcher: request.PathAnyWaiterMatch, Argument: "fleets[].state",
Matcher: request.PathAnyWaiterMatch, Argument: "Fleets[].State",
Expected: "PENDING_DEACTIVATE",
},
{
State: request.FailureWaiterState,
Matcher: request.PathAnyWaiterMatch, Argument: "fleets[].state",
Matcher: request.PathAnyWaiterMatch, Argument: "Fleets[].State",
Expected: "INACTIVE",
},
},
@@ -89,17 +89,17 @@ func (c *AppStream) WaitUntilFleetStoppedWithContext(ctx aws.Context, input *Des
Acceptors: []request.WaiterAcceptor{
{
State: request.SuccessWaiterState,
Matcher: request.PathAllWaiterMatch, Argument: "fleets[].state",
Matcher: request.PathAllWaiterMatch, Argument: "Fleets[].State",
Expected: "INACTIVE",
},
{
State: request.FailureWaiterState,
Matcher: request.PathAnyWaiterMatch, Argument: "fleets[].state",
Matcher: request.PathAnyWaiterMatch, Argument: "Fleets[].State",
Expected: "PENDING_ACTIVATE",
},
{
State: request.FailureWaiterState,
Matcher: request.PathAnyWaiterMatch, Argument: "fleets[].state",
Matcher: request.PathAnyWaiterMatch, Argument: "Fleets[].State",
Expected: "ACTIVE",
},
},

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -76,6 +76,14 @@ type CloudFormationAPI interface {
CreateStackWithContext(aws.Context, *cloudformation.CreateStackInput, ...request.Option) (*cloudformation.CreateStackOutput, error)
CreateStackRequest(*cloudformation.CreateStackInput) (*request.Request, *cloudformation.CreateStackOutput)
CreateStackInstances(*cloudformation.CreateStackInstancesInput) (*cloudformation.CreateStackInstancesOutput, error)
CreateStackInstancesWithContext(aws.Context, *cloudformation.CreateStackInstancesInput, ...request.Option) (*cloudformation.CreateStackInstancesOutput, error)
CreateStackInstancesRequest(*cloudformation.CreateStackInstancesInput) (*request.Request, *cloudformation.CreateStackInstancesOutput)
CreateStackSet(*cloudformation.CreateStackSetInput) (*cloudformation.CreateStackSetOutput, error)
CreateStackSetWithContext(aws.Context, *cloudformation.CreateStackSetInput, ...request.Option) (*cloudformation.CreateStackSetOutput, error)
CreateStackSetRequest(*cloudformation.CreateStackSetInput) (*request.Request, *cloudformation.CreateStackSetOutput)
DeleteChangeSet(*cloudformation.DeleteChangeSetInput) (*cloudformation.DeleteChangeSetOutput, error)
DeleteChangeSetWithContext(aws.Context, *cloudformation.DeleteChangeSetInput, ...request.Option) (*cloudformation.DeleteChangeSetOutput, error)
DeleteChangeSetRequest(*cloudformation.DeleteChangeSetInput) (*request.Request, *cloudformation.DeleteChangeSetOutput)
@@ -84,6 +92,14 @@ type CloudFormationAPI interface {
DeleteStackWithContext(aws.Context, *cloudformation.DeleteStackInput, ...request.Option) (*cloudformation.DeleteStackOutput, error)
DeleteStackRequest(*cloudformation.DeleteStackInput) (*request.Request, *cloudformation.DeleteStackOutput)
DeleteStackInstances(*cloudformation.DeleteStackInstancesInput) (*cloudformation.DeleteStackInstancesOutput, error)
DeleteStackInstancesWithContext(aws.Context, *cloudformation.DeleteStackInstancesInput, ...request.Option) (*cloudformation.DeleteStackInstancesOutput, error)
DeleteStackInstancesRequest(*cloudformation.DeleteStackInstancesInput) (*request.Request, *cloudformation.DeleteStackInstancesOutput)
DeleteStackSet(*cloudformation.DeleteStackSetInput) (*cloudformation.DeleteStackSetOutput, error)
DeleteStackSetWithContext(aws.Context, *cloudformation.DeleteStackSetInput, ...request.Option) (*cloudformation.DeleteStackSetOutput, error)
DeleteStackSetRequest(*cloudformation.DeleteStackSetInput) (*request.Request, *cloudformation.DeleteStackSetOutput)
DescribeAccountLimits(*cloudformation.DescribeAccountLimitsInput) (*cloudformation.DescribeAccountLimitsOutput, error)
DescribeAccountLimitsWithContext(aws.Context, *cloudformation.DescribeAccountLimitsInput, ...request.Option) (*cloudformation.DescribeAccountLimitsOutput, error)
DescribeAccountLimitsRequest(*cloudformation.DescribeAccountLimitsInput) (*request.Request, *cloudformation.DescribeAccountLimitsOutput)
@@ -99,6 +115,10 @@ type CloudFormationAPI interface {
DescribeStackEventsPages(*cloudformation.DescribeStackEventsInput, func(*cloudformation.DescribeStackEventsOutput, bool) bool) error
DescribeStackEventsPagesWithContext(aws.Context, *cloudformation.DescribeStackEventsInput, func(*cloudformation.DescribeStackEventsOutput, bool) bool, ...request.Option) error
DescribeStackInstance(*cloudformation.DescribeStackInstanceInput) (*cloudformation.DescribeStackInstanceOutput, error)
DescribeStackInstanceWithContext(aws.Context, *cloudformation.DescribeStackInstanceInput, ...request.Option) (*cloudformation.DescribeStackInstanceOutput, error)
DescribeStackInstanceRequest(*cloudformation.DescribeStackInstanceInput) (*request.Request, *cloudformation.DescribeStackInstanceOutput)
DescribeStackResource(*cloudformation.DescribeStackResourceInput) (*cloudformation.DescribeStackResourceOutput, error)
DescribeStackResourceWithContext(aws.Context, *cloudformation.DescribeStackResourceInput, ...request.Option) (*cloudformation.DescribeStackResourceOutput, error)
DescribeStackResourceRequest(*cloudformation.DescribeStackResourceInput) (*request.Request, *cloudformation.DescribeStackResourceOutput)
@@ -107,6 +127,14 @@ type CloudFormationAPI interface {
DescribeStackResourcesWithContext(aws.Context, *cloudformation.DescribeStackResourcesInput, ...request.Option) (*cloudformation.DescribeStackResourcesOutput, error)
DescribeStackResourcesRequest(*cloudformation.DescribeStackResourcesInput) (*request.Request, *cloudformation.DescribeStackResourcesOutput)
DescribeStackSet(*cloudformation.DescribeStackSetInput) (*cloudformation.DescribeStackSetOutput, error)
DescribeStackSetWithContext(aws.Context, *cloudformation.DescribeStackSetInput, ...request.Option) (*cloudformation.DescribeStackSetOutput, error)
DescribeStackSetRequest(*cloudformation.DescribeStackSetInput) (*request.Request, *cloudformation.DescribeStackSetOutput)
DescribeStackSetOperation(*cloudformation.DescribeStackSetOperationInput) (*cloudformation.DescribeStackSetOperationOutput, error)
DescribeStackSetOperationWithContext(aws.Context, *cloudformation.DescribeStackSetOperationInput, ...request.Option) (*cloudformation.DescribeStackSetOperationOutput, error)
DescribeStackSetOperationRequest(*cloudformation.DescribeStackSetOperationInput) (*request.Request, *cloudformation.DescribeStackSetOperationOutput)
DescribeStacks(*cloudformation.DescribeStacksInput) (*cloudformation.DescribeStacksOutput, error)
DescribeStacksWithContext(aws.Context, *cloudformation.DescribeStacksInput, ...request.Option) (*cloudformation.DescribeStacksOutput, error)
DescribeStacksRequest(*cloudformation.DescribeStacksInput) (*request.Request, *cloudformation.DescribeStacksOutput)
@@ -152,6 +180,10 @@ type CloudFormationAPI interface {
ListImportsPages(*cloudformation.ListImportsInput, func(*cloudformation.ListImportsOutput, bool) bool) error
ListImportsPagesWithContext(aws.Context, *cloudformation.ListImportsInput, func(*cloudformation.ListImportsOutput, bool) bool, ...request.Option) error
ListStackInstances(*cloudformation.ListStackInstancesInput) (*cloudformation.ListStackInstancesOutput, error)
ListStackInstancesWithContext(aws.Context, *cloudformation.ListStackInstancesInput, ...request.Option) (*cloudformation.ListStackInstancesOutput, error)
ListStackInstancesRequest(*cloudformation.ListStackInstancesInput) (*request.Request, *cloudformation.ListStackInstancesOutput)
ListStackResources(*cloudformation.ListStackResourcesInput) (*cloudformation.ListStackResourcesOutput, error)
ListStackResourcesWithContext(aws.Context, *cloudformation.ListStackResourcesInput, ...request.Option) (*cloudformation.ListStackResourcesOutput, error)
ListStackResourcesRequest(*cloudformation.ListStackResourcesInput) (*request.Request, *cloudformation.ListStackResourcesOutput)
@@ -159,6 +191,18 @@ type CloudFormationAPI interface {
ListStackResourcesPages(*cloudformation.ListStackResourcesInput, func(*cloudformation.ListStackResourcesOutput, bool) bool) error
ListStackResourcesPagesWithContext(aws.Context, *cloudformation.ListStackResourcesInput, func(*cloudformation.ListStackResourcesOutput, bool) bool, ...request.Option) error
ListStackSetOperationResults(*cloudformation.ListStackSetOperationResultsInput) (*cloudformation.ListStackSetOperationResultsOutput, error)
ListStackSetOperationResultsWithContext(aws.Context, *cloudformation.ListStackSetOperationResultsInput, ...request.Option) (*cloudformation.ListStackSetOperationResultsOutput, error)
ListStackSetOperationResultsRequest(*cloudformation.ListStackSetOperationResultsInput) (*request.Request, *cloudformation.ListStackSetOperationResultsOutput)
ListStackSetOperations(*cloudformation.ListStackSetOperationsInput) (*cloudformation.ListStackSetOperationsOutput, error)
ListStackSetOperationsWithContext(aws.Context, *cloudformation.ListStackSetOperationsInput, ...request.Option) (*cloudformation.ListStackSetOperationsOutput, error)
ListStackSetOperationsRequest(*cloudformation.ListStackSetOperationsInput) (*request.Request, *cloudformation.ListStackSetOperationsOutput)
ListStackSets(*cloudformation.ListStackSetsInput) (*cloudformation.ListStackSetsOutput, error)
ListStackSetsWithContext(aws.Context, *cloudformation.ListStackSetsInput, ...request.Option) (*cloudformation.ListStackSetsOutput, error)
ListStackSetsRequest(*cloudformation.ListStackSetsInput) (*request.Request, *cloudformation.ListStackSetsOutput)
ListStacks(*cloudformation.ListStacksInput) (*cloudformation.ListStacksOutput, error)
ListStacksWithContext(aws.Context, *cloudformation.ListStacksInput, ...request.Option) (*cloudformation.ListStacksOutput, error)
ListStacksRequest(*cloudformation.ListStacksInput) (*request.Request, *cloudformation.ListStacksOutput)
@@ -174,10 +218,18 @@ type CloudFormationAPI interface {
SignalResourceWithContext(aws.Context, *cloudformation.SignalResourceInput, ...request.Option) (*cloudformation.SignalResourceOutput, error)
SignalResourceRequest(*cloudformation.SignalResourceInput) (*request.Request, *cloudformation.SignalResourceOutput)
StopStackSetOperation(*cloudformation.StopStackSetOperationInput) (*cloudformation.StopStackSetOperationOutput, error)
StopStackSetOperationWithContext(aws.Context, *cloudformation.StopStackSetOperationInput, ...request.Option) (*cloudformation.StopStackSetOperationOutput, error)
StopStackSetOperationRequest(*cloudformation.StopStackSetOperationInput) (*request.Request, *cloudformation.StopStackSetOperationOutput)
UpdateStack(*cloudformation.UpdateStackInput) (*cloudformation.UpdateStackOutput, error)
UpdateStackWithContext(aws.Context, *cloudformation.UpdateStackInput, ...request.Option) (*cloudformation.UpdateStackOutput, error)
UpdateStackRequest(*cloudformation.UpdateStackInput) (*request.Request, *cloudformation.UpdateStackOutput)
UpdateStackSet(*cloudformation.UpdateStackSetInput) (*cloudformation.UpdateStackSetOutput, error)
UpdateStackSetWithContext(aws.Context, *cloudformation.UpdateStackSetInput, ...request.Option) (*cloudformation.UpdateStackSetOutput, error)
UpdateStackSetRequest(*cloudformation.UpdateStackSetInput) (*request.Request, *cloudformation.UpdateStackSetOutput)
ValidateTemplate(*cloudformation.ValidateTemplateInput) (*cloudformation.ValidateTemplateOutput, error)
ValidateTemplateWithContext(aws.Context, *cloudformation.ValidateTemplateInput, ...request.Option) (*cloudformation.ValidateTemplateOutput, error)
ValidateTemplateRequest(*cloudformation.ValidateTemplateInput) (*request.Request, *cloudformation.ValidateTemplateOutput)

View File

@@ -23,6 +23,172 @@
// technical information about a specific AWS product, you can find the product's
// technical documentation at docs.aws.amazon.com (http://docs.aws.amazon.com/).
//
// APIs for stacks
//
// When you use AWS CloudFormation, you manage related resources as a single
// unit called a stack. You create, update, and delete a collection of resources
// by creating, updating, and deleting stacks. All the resources in a stack
// are defined by the stack's AWS CloudFormation template.
//
// Actions
//
// * CancelUpdateStack (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CancelUpdateStack.html)
//
// * ContinueUpdateRollback (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ContinueUpdateRollback.html)
//
// * CreateStack (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html)
//
// * DeleteStack (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DeleteStack.html)
//
// * DescribeStackEvents (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeStackEvents.html)
//
// * DescribeStackResource (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeStackResource.html)
//
// * DescribeStackResources (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeStackResources.html)
//
// * DescribeStacks (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeStacks.html)
//
// * EstimateTemplateCost (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_EstimateTemplateCost.html)
//
// * GetStackPolicy (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_GetStackPolicy.html)
//
// * GetTemplate (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_GetTemplate.html)
//
// * GetTemplateSummary (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_GetTemplateSummary.html)
//
// * ListExports (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ListExports.html)
//
// * ListImports (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ListImports.html)
//
// * ListStackResources (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ListStackResources.html)
//
// * ListStacks (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ListStacks.html)
//
// * SetStackPolicy (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_SetStackPolicy.html)
//
// * UpdateStack (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_UpdateStack.html)
//
// * ValidateTemplate (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ValidateTemplate.html)
//
// Data Types
//
// * Export (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Export.html)
//
// * Parameter (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Parameter.html)
//
// * ParameterConstraints (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ParameterConstraints.html)
//
// * ParameterDeclaration (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ParameterDeclaration.html)
//
// * Stack (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Stack.html)
//
// * StackEvent (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackEvent.html)
//
// * StackResource (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackResource.html)
//
// * StackResourceDetail (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackResourceDetail.html)
//
// * StackResourceSummary (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackResourceSummary.html)
//
// * StackSummary (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackSummary.html)
//
// * Tag (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Tag.html)
//
// * TemplateParameter (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_TemplateParameter.html)
//
// APIs for change sets
//
// If you need to make changes to the running resources in a stack, you update
// the stack. Before making changes to your resources, you can generate a change
// set, which is summary of your proposed changes. Change sets allow you to
// see how your changes might impact your running resources, especially for
// critical resources, before implementing them.
//
// Actions
//
// * CreateChangeSet (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateChangeSet.html)
//
// * DeleteChangeSet (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DeleteChangeSet.html)
//
// * DescribeChangeSet (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeChangeSet.html)
//
// * ExecuteChangeSet (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ExecuteChangeSet.html)
//
// * ListChangeSets (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ListChangeSets.html)
//
// Data Types
//
// * Change (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Change.html)
//
// * ChangeSetSummary (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ChangeSetSummary.html)
//
// * ResourceChange (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ResourceChange.html)
//
// * ResourceChangeDetail (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ResourceChangeDetail.html)
//
// * ResourceTargetDefinition (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ResourceTargetDefinition.html)
//
// APIs for stack sets
//
// AWS CloudFormation StackSets lets you create a collection, or stack set,
// of stacks that can automatically and safely provision a common set of AWS
// resources across multiple AWS accounts and multiple AWS regions from a single
// AWS CloudFormation template. When you create a stack set, AWS CloudFormation
// provisions a stack in each of the specified accounts and regions by using
// the supplied AWS CloudFormation template and parameters. Stack sets let you
// manage a common set of AWS resources in a selection of accounts and regions
// in a single operation.
//
// Actions
//
// * CreateStackInstances (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStackInstances.html)
//
// * CreateStackSet (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStackSet.html)
//
// * DeleteStackInstances (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DeleteStackInstances.html)
//
// * DeleteStackSet (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DeleteStackSet.html)
//
// * DescribeStackInstance (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeStackInstance.html)
//
// * DescribeStackSet (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeStackSet.html)
//
// * DescribeStackSetOperation (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_DescribeStackSetOperation.html)
//
// * ListStackInstances (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ListStackInstances.html)
//
// * ListStackSetOperationResults (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ListStackSetOperationResults)
//
// * ListStackSetOperations (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ListStackSetOperations)
//
// * ListStackSets (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_ListStackSets)
//
// * StopStackSetOperation (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StopStackSetOperation.html)
//
// * UpdateStackSet (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_UpdateStackSet.html)
//
// Data Types
//
// * Parameter (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Parameter.html)
//
// * StackInstance (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackInstance.html.html)
//
// * StackInstanceSummary (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackInstanceSummary.html.html)
//
// * StackSet (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackSet.html)
//
// * StackSetOperation (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackSetOperation.html.html)
//
// * StackSetOperationPreferences (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackSetOperationPreferences.html.html)
//
// * StackSetOperationResultSummary (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackSetOperationResultSummary.html.html)
//
// * StackSetOperationSummary (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackSetOperationSummary.html.html)
//
// * StackSetSummary (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_StackSetSummary.html)
//
// * Tag (http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Tag.html)
//
// See https://docs.aws.amazon.com/goto/WebAPI/cloudformation-2010-05-15 for more information on this service.
//
// See cloudformation package documentation for more information.

View File

@@ -7,7 +7,7 @@ const (
// ErrCodeAlreadyExistsException for service response error code
// "AlreadyExistsException".
//
// Resource with the name requested already exists.
// The resource with the name requested already exists.
ErrCodeAlreadyExistsException = "AlreadyExistsException"
// ErrCodeChangeSetNotFoundException for service response error code
@@ -17,27 +17,91 @@ const (
// for a stack, use the ListChangeSets action.
ErrCodeChangeSetNotFoundException = "ChangeSetNotFound"
// ErrCodeCreatedButModifiedException for service response error code
// "CreatedButModifiedException".
//
// The specified resource exists, but has been changed.
ErrCodeCreatedButModifiedException = "CreatedButModifiedException"
// ErrCodeInsufficientCapabilitiesException for service response error code
// "InsufficientCapabilitiesException".
//
// The template contains resources with capabilities that were not specified
// The template contains resources with capabilities that weren't specified
// in the Capabilities parameter.
ErrCodeInsufficientCapabilitiesException = "InsufficientCapabilitiesException"
// ErrCodeInvalidChangeSetStatusException for service response error code
// "InvalidChangeSetStatus".
//
// The specified change set cannot be used to update the stack. For example,
// the change set status might be CREATE_IN_PROGRESS or the stack status might
// The specified change set can't be used to update the stack. For example,
// the change set status might be CREATE_IN_PROGRESS, or the stack status might
// be UPDATE_IN_PROGRESS.
ErrCodeInvalidChangeSetStatusException = "InvalidChangeSetStatus"
// ErrCodeInvalidOperationException for service response error code
// "InvalidOperationException".
//
// The specified operation isn't valid.
ErrCodeInvalidOperationException = "InvalidOperationException"
// ErrCodeLimitExceededException for service response error code
// "LimitExceededException".
//
// Quota for the resource has already been reached.
// The quota for the resource has already been reached.
ErrCodeLimitExceededException = "LimitExceededException"
// ErrCodeNameAlreadyExistsException for service response error code
// "NameAlreadyExistsException".
//
// The specified name is already in use.
ErrCodeNameAlreadyExistsException = "NameAlreadyExistsException"
// ErrCodeOperationIdAlreadyExistsException for service response error code
// "OperationIdAlreadyExistsException".
//
// The specified operation ID already exists.
ErrCodeOperationIdAlreadyExistsException = "OperationIdAlreadyExistsException"
// ErrCodeOperationInProgressException for service response error code
// "OperationInProgressException".
//
// Another operation is currently in progress for this stack set. Only one operation
// can be performed for a stack set at a given time.
ErrCodeOperationInProgressException = "OperationInProgressException"
// ErrCodeOperationNotFoundException for service response error code
// "OperationNotFoundException".
//
// The specified ID refers to an operation that doesn't exist.
ErrCodeOperationNotFoundException = "OperationNotFoundException"
// ErrCodeStackInstanceNotFoundException for service response error code
// "StackInstanceNotFoundException".
//
// The specified stack instance doesn't exist.
ErrCodeStackInstanceNotFoundException = "StackInstanceNotFoundException"
// ErrCodeStackSetNotEmptyException for service response error code
// "StackSetNotEmptyException".
//
// You can't yet delete this stack set, because it still contains one or more
// stack instances. Delete all stack instances from the stack set before deleting
// the stack set.
ErrCodeStackSetNotEmptyException = "StackSetNotEmptyException"
// ErrCodeStackSetNotFoundException for service response error code
// "StackSetNotFoundException".
//
// The specified stack set doesn't exist.
ErrCodeStackSetNotFoundException = "StackSetNotFoundException"
// ErrCodeStaleRequestException for service response error code
// "StaleRequestException".
//
// Another operation has been performed on this stack set since the specified
// operation was performed.
ErrCodeStaleRequestException = "StaleRequestException"
// ErrCodeTokenAlreadyExistsException for service response error code
// "TokenAlreadyExistsException".
//

View File

@@ -25094,6 +25094,7 @@ func (s *CreateNetworkInterfaceOutput) SetNetworkInterface(v *NetworkInterface)
return s
}
// Contains the parameters for CreateNetworkInterfacePermission.
// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermissionRequest
type CreateNetworkInterfacePermissionInput struct {
_ struct{} `type:"structure"`
@@ -25177,6 +25178,7 @@ func (s *CreateNetworkInterfacePermissionInput) SetPermission(v string) *CreateN
return s
}
// Contains the output of CreateNetworkInterfacePermission.
// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/CreateNetworkInterfacePermissionResult
type CreateNetworkInterfacePermissionOutput struct {
_ struct{} `type:"structure"`
@@ -27665,6 +27667,7 @@ func (s DeleteNetworkInterfaceOutput) GoString() string {
return s.String()
}
// Contains the parameters for DeleteNetworkInterfacePermission.
// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermissionRequest
type DeleteNetworkInterfacePermissionInput struct {
_ struct{} `type:"structure"`
@@ -27726,6 +27729,7 @@ func (s *DeleteNetworkInterfacePermissionInput) SetNetworkInterfacePermissionId(
return s
}
// Contains the output for DeleteNetworkInterfacePermission.
// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DeleteNetworkInterfacePermissionResult
type DeleteNetworkInterfacePermissionOutput struct {
_ struct{} `type:"structure"`
@@ -32411,6 +32415,7 @@ func (s *DescribeNetworkInterfaceAttributeOutput) SetSourceDestCheck(v *Attribut
return s
}
// Contains the parameters for DescribeNetworkInterfacePermissions.
// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissionsRequest
type DescribeNetworkInterfacePermissionsInput struct {
_ struct{} `type:"structure"`
@@ -32477,6 +32482,7 @@ func (s *DescribeNetworkInterfacePermissionsInput) SetNextToken(v string) *Descr
return s
}
// Contains the output for DescribeNetworkInterfacePermissions.
// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/DescribeNetworkInterfacePermissionsResult
type DescribeNetworkInterfacePermissionsOutput struct {
_ struct{} `type:"structure"`
@@ -54039,6 +54045,9 @@ type SpotFleetLaunchSpecification struct {
// subnets, separate them using commas; for example, "subnet-a61dafcf, subnet-65ea5f08".
SubnetId *string `locationName:"subnetId" type:"string"`
// The tags to apply during creation.
TagSpecifications []*SpotFleetTagSpecification `locationName:"tagSpecificationSet" locationNameList:"item" type:"list"`
// The user data to make available to the instances. If you are using an AWS
// SDK or command line tool, Base64-encoding is performed for you, and you can
// load the text from a file. Otherwise, you must provide Base64-encoded text.
@@ -54174,6 +54183,12 @@ func (s *SpotFleetLaunchSpecification) SetSubnetId(v string) *SpotFleetLaunchSpe
return s
}
// SetTagSpecifications sets the TagSpecifications field's value.
func (s *SpotFleetLaunchSpecification) SetTagSpecifications(v []*SpotFleetTagSpecification) *SpotFleetLaunchSpecification {
s.TagSpecifications = v
return s
}
// SetUserData sets the UserData field's value.
func (s *SpotFleetLaunchSpecification) SetUserData(v string) *SpotFleetLaunchSpecification {
s.UserData = &v
@@ -54483,6 +54498,41 @@ func (s *SpotFleetRequestConfigData) SetValidUntil(v time.Time) *SpotFleetReques
return s
}
// The tags for a Spot fleet resource.
// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotFleetTagSpecification
type SpotFleetTagSpecification struct {
_ struct{} `type:"structure"`
// The type of resource. Currently, the only resource type that is supported
// is instance.
ResourceType *string `locationName:"resourceType" type:"string" enum:"ResourceType"`
// The tags.
Tags []*Tag `locationName:"tag" locationNameList:"item" type:"list"`
}
// String returns the string representation
func (s SpotFleetTagSpecification) String() string {
return awsutil.Prettify(s)
}
// GoString returns the string representation
func (s SpotFleetTagSpecification) GoString() string {
return s.String()
}
// SetResourceType sets the ResourceType field's value.
func (s *SpotFleetTagSpecification) SetResourceType(v string) *SpotFleetTagSpecification {
s.ResourceType = &v
return s
}
// SetTags sets the Tags field's value.
func (s *SpotFleetTagSpecification) SetTags(v []*Tag) *SpotFleetTagSpecification {
s.Tags = v
return s
}
// Describes a Spot instance request.
// Please also see https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15/SpotInstanceRequest
type SpotInstanceRequest struct {

View File

@@ -1592,11 +1592,10 @@ func (c *EMR) ListInstancesRequest(input *ListInstancesInput) (req *request.Requ
// ListInstances API operation for Amazon Elastic MapReduce.
//
// Provides information about the cluster instances that Amazon EMR provisions
// on behalf of a user when it creates the cluster. For example, this operation
// indicates when the EC2 instances reach the Ready state, when instances become
// available to Amazon EMR to use for jobs, and the IP addresses for cluster
// instances, etc.
// Provides information for all active EC2 instances and EC2 instances terminated
// in the last 30 days, up to a maximum of 2,000. EC2 instances in any of the
// following states are considered active: AWAITING_FULFILLMENT, PROVISIONING,
// BOOTSTRAPPING, RUNNING.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
@@ -3082,7 +3081,7 @@ func (s AddTagsOutput) GoString() string {
// * "mapr" with the user arguments specifying "--edition,m3" or "--edition,m5"
// - launch the cluster using MapR M3 or M5 Edition, respectively.
//
// In Amazon EMR releases 4.0 and greater, the only accepted parameter is the
// In Amazon EMR releases 4.x and later, the only accepted parameter is the
// application name. To pass arguments to applications, you supply a configuration
// for each application.
// Please also see https://docs.aws.amazon.com/goto/WebAPI/elasticmapreduce-2009-03-31/Application
@@ -3674,11 +3673,18 @@ type Cluster struct {
// Specifies whether the cluster should terminate after completing all steps.
AutoTerminate *bool `type:"boolean"`
// Amazon EMR releases 4.x or later.
//
// The list of Configurations supplied to the EMR cluster.
// Applies only to Amazon EMR releases 4.x and later. The list of Configurations
// supplied to the EMR cluster.
Configurations []*Configuration `type:"list"`
// Available only in Amazon EMR version 5.7.0 and later. The ID of a custom
// Amazon EBS-backed Linux AMI if the cluster uses a custom AMI.
CustomAmiId *string `type:"string"`
// The size, in GiB, of the EBS root device volume of the Linux AMI that is
// used for each EC2 instance. Available in Amazon EMR version 4.x and later.
EbsRootVolumeSize *int64 `type:"integer"`
// Provides information about the EC2 instances in a cluster grouped by category.
// For example, key name, subnet ID, IAM instance profile, and so on.
Ec2InstanceAttributes *Ec2InstanceAttributes `type:"structure"`
@@ -3711,10 +3717,14 @@ type Cluster struct {
// the actual billing rate.
NormalizedInstanceHours *int64 `type:"integer"`
// The release label for the Amazon EMR release. For Amazon EMR 3.x and 2.x
// AMIs, use amiVersion instead instead of ReleaseLabel.
// The release label for the Amazon EMR release.
ReleaseLabel *string `type:"string"`
// Applies only when CustomAmiID is used. Specifies the type of updates that
// are applied from the Amazon Linux AMI package repositories when an instance
// boots using the AMI.
RepoUpgradeOnBoot *string `type:"string" enum:"RepoUpgradeOnBoot"`
// The AMI version requested for this cluster.
RequestedAmiVersion *string `type:"string"`
@@ -3796,6 +3806,18 @@ func (s *Cluster) SetConfigurations(v []*Configuration) *Cluster {
return s
}
// SetCustomAmiId sets the CustomAmiId field's value.
func (s *Cluster) SetCustomAmiId(v string) *Cluster {
s.CustomAmiId = &v
return s
}
// SetEbsRootVolumeSize sets the EbsRootVolumeSize field's value.
func (s *Cluster) SetEbsRootVolumeSize(v int64) *Cluster {
s.EbsRootVolumeSize = &v
return s
}
// SetEc2InstanceAttributes sets the Ec2InstanceAttributes field's value.
func (s *Cluster) SetEc2InstanceAttributes(v *Ec2InstanceAttributes) *Cluster {
s.Ec2InstanceAttributes = v
@@ -3844,6 +3866,12 @@ func (s *Cluster) SetReleaseLabel(v string) *Cluster {
return s
}
// SetRepoUpgradeOnBoot sets the RepoUpgradeOnBoot field's value.
func (s *Cluster) SetRepoUpgradeOnBoot(v string) *Cluster {
s.RepoUpgradeOnBoot = &v
return s
}
// SetRequestedAmiVersion sets the RequestedAmiVersion field's value.
func (s *Cluster) SetRequestedAmiVersion(v string) *Cluster {
s.RequestedAmiVersion = &v
@@ -4835,20 +4863,26 @@ type Ec2InstanceAttributes struct {
// of the cluster assume this role.
IamInstanceProfile *string `type:"string"`
// Applies to clusters configured with the The list of availability zones to
// choose from. The service will choose the availability zone with the best
// mix of available capacity and lowest cost to launch the cluster. If you do
// not specify this value, the cluster is launched in any availability zone
// that the customer account has access to.
// Applies to clusters configured with the instance fleets option. Specifies
// one or more Availability Zones in which to launch EC2 cluster instances when
// the EC2-Classic network configuration is supported. Amazon EMR chooses the
// Availability Zone with the best fit from among the list of RequestedEc2AvailabilityZones,
// and then launches all cluster instances within that Availability Zone. If
// you do not specify this value, Amazon EMR chooses the Availability Zone for
// you. RequestedEc2SubnetIDs and RequestedEc2AvailabilityZones cannot be specified
// together.
RequestedEc2AvailabilityZones []*string `type:"list"`
// Applies to clusters configured with the instance fleets option. Specifies
// the unique identifier of one or more Amazon EC2 subnets in which to launch
// EC2 cluster instances. Amazon EMR chooses the EC2 subnet with the best performance
// and cost characteristics from among the list of RequestedEc2SubnetIds and
// launches all cluster instances within that subnet. If this value is not specified,
// and the account supports EC2-Classic networks, the cluster launches instances
// in the EC2-Classic network and uses Requested
// EC2 cluster instances. Subnets must exist within the same VPC. Amazon EMR
// chooses the EC2 subnet with the best fit from among the list of RequestedEc2SubnetIds,
// and then launches all cluster instances within that Subnet. If this value
// is not specified, and the account and region support EC2-Classic networks,
// the cluster launches instances in the EC2-Classic network and uses RequestedEc2AvailabilityZones
// instead of this setting. If EC2-Classic is not supported, and no Subnet is
// specified, Amazon EMR chooses the subnet for you. RequestedEc2SubnetIDs and
// RequestedEc2AvailabilityZones cannot be specified together.
RequestedEc2SubnetIds []*string `type:"list"`
// The identifier of the Amazon EC2 security group for the Amazon EMR service
@@ -6590,9 +6624,9 @@ type InstanceTypeConfig struct {
BidPrice *string `type:"string"`
// The bid price, as a percentage of On-Demand price, for each EC2 Spot instance
// as defined by InstanceType. Expressed as a number between 0 and 1000 (for
// example, 20 specifies 20%). If neither BidPrice nor BidPriceAsPercentageOfOnDemandPrice
// is provided, BidPriceAsPercentageOfOnDemandPrice defaults to 100%.
// as defined by InstanceType. Expressed as a number (for example, 20 specifies
// 20%). If neither BidPrice nor BidPriceAsPercentageOfOnDemandPrice is provided,
// BidPriceAsPercentageOfOnDemandPrice defaults to 100%.
BidPriceAsPercentageOfOnDemandPrice *float64 `type:"double"`
// A configuration classification that applies when provisioning cluster instances,
@@ -6611,8 +6645,8 @@ type InstanceTypeConfig struct {
// The number of units that a provisioned instance of this type provides toward
// fulfilling the target capacities defined in InstanceFleetConfig. This value
// is 1 for a master instance fleet, and must be greater than 0 for core and
// task instance fleets.
// is 1 for a master instance fleet, and must be 1 or greater for core and task
// instance fleets. Defaults to 1 if not specified.
WeightedCapacity *int64 `type:"integer"`
}
@@ -6779,9 +6813,9 @@ func (s *InstanceTypeSpecification) SetWeightedCapacity(v int64) *InstanceTypeSp
type JobFlowDetail struct {
_ struct{} `type:"structure"`
// The version of the AMI used to initialize Amazon EC2 instances in the job
// flow. For a list of AMI versions currently supported by Amazon EMR, see AMI
// Versions Supported in EMR (http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/EnvironmentConfig_AMIVersion.html#ami-versions-supported)
// Used only for version 2.x and 3.x of Amazon EMR. The version of the AMI used
// to initialize Amazon EC2 instances in the job flow. For a list of AMI versions
// supported by Amazon EMR, see AMI Versions Supported in EMR (http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/EnvironmentConfig_AMIVersion.html#ami-versions-supported)
// in the Amazon EMR Developer Guide.
AmiVersion *string `type:"string"`
@@ -8560,22 +8594,17 @@ type RunJobFlowInput struct {
// A JSON string for selecting additional features.
AdditionalInfo *string `type:"string"`
// For Amazon EMR releases 3.x and 2.x. For Amazon EMR releases 4.x and greater,
// use ReleaseLabel.
//
// For Amazon EMR AMI versions 3.x and 2.x. For Amazon EMR releases 4.0 and
// later, the Linux AMI is determined by the ReleaseLabel specified or by CustomAmiID.
// The version of the Amazon Machine Image (AMI) to use when launching Amazon
// EC2 instances in the job flow. The following values are valid:
//
// * The version number of the AMI to use, for example, "2.0."
// EC2 instances in the job flow. For details about the AMI versions currently
// supported in EMR version 3.x and 2.x, see AMI Versions Supported in EMR (ElasticMapReduce/latest/DeveloperGuide/emr-dg.pdf#nameddest=ami-versions-supported)
// in the Amazon EMR Developer Guide.
//
// If the AMI supports multiple versions of Hadoop (for example, AMI 1.0 supports
// both Hadoop 0.18 and 0.20) you can use the JobFlowInstancesConfigHadoopVersion
// both Hadoop 0.18 and 0.20), you can use the JobFlowInstancesConfigHadoopVersion
// parameter to modify the version of Hadoop from the defaults shown above.
//
// For details about the AMI versions currently supported by Amazon Elastic
// MapReduce, see AMI Versions Supported in Elastic MapReduce (http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/EnvironmentConfig_AMIVersion.html#ami-versions-supported)
// in the Amazon Elastic MapReduce Developer Guide.
//
// Previously, the EMR AMI version API parameter options allowed you to use
// latest for the latest AMI version rather than specify a numerical value.
// Some regions no longer support this deprecated option as they only have a
@@ -8583,10 +8612,9 @@ type RunJobFlowInput struct {
// release label release (EMR 4.x or later).
AmiVersion *string `type:"string"`
// Amazon EMR releases 4.x or later.
//
// A list of applications for the cluster. Valid values are: "Hadoop", "Hive",
// "Mahout", "Pig", and "Spark." They are case insensitive.
// For Amazon EMR releases 4.0 and later. A list of applications for the cluster.
// Valid values are: "Hadoop", "Hive", "Mahout", "Pig", and "Spark." They are
// case insensitive.
Applications []*Application `type:"list"`
// An IAM role for automatic scaling policies. The default role is EMR_AutoScaling_DefaultRole.
@@ -8597,11 +8625,28 @@ type RunJobFlowInput struct {
// A list of bootstrap actions to run before Hadoop starts on the cluster nodes.
BootstrapActions []*BootstrapActionConfig `type:"list"`
// Amazon EMR releases 4.x or later.
//
// The list of configurations supplied for the EMR cluster you are creating.
// For Amazon EMR releases 4.0 and later. The list of configurations supplied
// for the EMR cluster you are creating.
Configurations []*Configuration `type:"list"`
// Available only in Amazon EMR version 5.7.0 and later. The ID of a custom
// Amazon EBS-backed Linux AMI. If specified, Amazon EMR uses this AMI when
// it launches cluster EC2 instances. For more information about custom AMIs
// in Amazon EMR, see Using a Custom AMI (http://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-custom-ami.html)
// in the Amazon EMR Management Guide. If omitted, the cluster uses the base
// Linux AMI for the ReleaseLabel specified. For Amazon EMR versions 2.x and
// 3.x, use AmiVersion instead.
//
// For information about creating a custom AMI, see Creating an Amazon EBS-Backed
// Linux AMI (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami-ebs.html)
// in the Amazon Elastic Compute Cloud User Guide for Linux Instances. For information
// about finding an AMI ID, see Finding a Linux AMI (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/finding-an-ami.html).
CustomAmiId *string `type:"string"`
// The size, in GiB, of the EBS root device volume of the Linux AMI that is
// used for each EC2 instance. Available in Amazon EMR version 4.x and later.
EbsRootVolumeSize *int64 `type:"integer"`
// A specification of the number and type of Amazon EC2 instances.
//
// Instances is a required field
@@ -8622,7 +8667,7 @@ type RunJobFlowInput struct {
// Name is a required field
Name *string `type:"string" required:"true"`
// For Amazon EMR releases 3.x and 2.x. For Amazon EMR releases 4.x and greater,
// For Amazon EMR releases 3.x and 2.x. For Amazon EMR releases 4.x and later,
// use Applications.
//
// A list of strings that indicates third-party software to use with the job
@@ -8650,12 +8695,17 @@ type RunJobFlowInput struct {
// * "ganglia" - launch the cluster with the Ganglia Monitoring System installed.
NewSupportedProducts []*SupportedProductConfig `type:"list"`
// Amazon EMR releases 4.x or later.
//
// The release label for the Amazon EMR release. For Amazon EMR 3.x and 2.x
// AMIs, use amiVersion instead instead of ReleaseLabel.
// AMIs, use AmiVersion instead.
ReleaseLabel *string `type:"string"`
// Applies only when CustomAmiID is used. Specifies which updates from the Amazon
// Linux AMI package repositories to apply automatically when the instance boots
// using the AMI. If omitted, the default is SECURITY, which indicates that
// only security updates are applied. If NONE is specified, no updates are applied,
// and all updates must be applied manually.
RepoUpgradeOnBoot *string `type:"string" enum:"RepoUpgradeOnBoot"`
// Specifies the way that individual Amazon EC2 instances terminate when an
// automatic scale-in activity occurs or an instance group is resized. TERMINATE_AT_INSTANCE_HOUR
// indicates that Amazon EMR terminates nodes at the instance-hour boundary,
@@ -8680,7 +8730,7 @@ type RunJobFlowInput struct {
// A list of steps to run.
Steps []*StepConfig `type:"list"`
// For Amazon EMR releases 3.x and 2.x. For Amazon EMR releases 4.x and greater,
// For Amazon EMR releases 3.x and 2.x. For Amazon EMR releases 4.x and later,
// use Applications.
//
// A list of strings that indicates third-party software to use. For more information,
@@ -8790,6 +8840,18 @@ func (s *RunJobFlowInput) SetConfigurations(v []*Configuration) *RunJobFlowInput
return s
}
// SetCustomAmiId sets the CustomAmiId field's value.
func (s *RunJobFlowInput) SetCustomAmiId(v string) *RunJobFlowInput {
s.CustomAmiId = &v
return s
}
// SetEbsRootVolumeSize sets the EbsRootVolumeSize field's value.
func (s *RunJobFlowInput) SetEbsRootVolumeSize(v int64) *RunJobFlowInput {
s.EbsRootVolumeSize = &v
return s
}
// SetInstances sets the Instances field's value.
func (s *RunJobFlowInput) SetInstances(v *JobFlowInstancesConfig) *RunJobFlowInput {
s.Instances = v
@@ -8826,6 +8888,12 @@ func (s *RunJobFlowInput) SetReleaseLabel(v string) *RunJobFlowInput {
return s
}
// SetRepoUpgradeOnBoot sets the RepoUpgradeOnBoot field's value.
func (s *RunJobFlowInput) SetRepoUpgradeOnBoot(v string) *RunJobFlowInput {
s.RepoUpgradeOnBoot = &v
return s
}
// SetScaleDownBehavior sets the ScaleDownBehavior field's value.
func (s *RunJobFlowInput) SetScaleDownBehavior(v string) *RunJobFlowInput {
s.ScaleDownBehavior = &v
@@ -9514,8 +9582,9 @@ type SpotProvisioningSpecification struct {
// The action to take when TargetSpotCapacity has not been fulfilled when the
// TimeoutDurationMinutes has expired. Spot instances are not uprovisioned within
// the Spot provisioining timeout. Valid values are TERMINATE_CLUSTER and SWITCH_TO_ON_DEMAND
// to fulfill the remaining capacity.
// the Spot provisioining timeout. Valid values are TERMINATE_CLUSTER and SWITCH_TO_ON_DEMAND.
// SWITCH_TO_ON_DEMAND specifies that if no Spot instances are available, On-Demand
// Instances should be provisioned to fulfill any remaining Spot capacity.
//
// TimeoutAction is a required field
TimeoutAction *string `type:"string" required:"true" enum:"SpotProvisioningTimeoutAction"`
@@ -10292,6 +10361,9 @@ const (
// ClusterStateChangeReasonCodeInstanceFailure is a ClusterStateChangeReasonCode enum value
ClusterStateChangeReasonCodeInstanceFailure = "INSTANCE_FAILURE"
// ClusterStateChangeReasonCodeInstanceFleetTimeout is a ClusterStateChangeReasonCode enum value
ClusterStateChangeReasonCodeInstanceFleetTimeout = "INSTANCE_FLEET_TIMEOUT"
// ClusterStateChangeReasonCodeBootstrapFailure is a ClusterStateChangeReasonCode enum value
ClusterStateChangeReasonCodeBootstrapFailure = "BOOTSTRAP_FAILURE"
@@ -10512,6 +10584,14 @@ const (
MarketTypeSpot = "SPOT"
)
const (
// RepoUpgradeOnBootSecurity is a RepoUpgradeOnBoot enum value
RepoUpgradeOnBootSecurity = "SECURITY"
// RepoUpgradeOnBootNone is a RepoUpgradeOnBoot enum value
RepoUpgradeOnBootNone = "NONE"
)
const (
// ScaleDownBehaviorTerminateAtInstanceHour is a ScaleDownBehavior enum value
ScaleDownBehaviorTerminateAtInstanceHour = "TERMINATE_AT_INSTANCE_HOUR"

View File

@@ -1 +1 @@
0.1.34
0.1.35

View File

@@ -23,62 +23,62 @@ type Client struct {
}
/*
GetAppsAppCallsRoute gets route bound calls
GetAppsAppCalls gets app bound calls
Get route-bound calls.
Get app-bound calls can filter to route-bound calls.
*/
func (a *Client) GetAppsAppCallsRoute(params *GetAppsAppCallsRouteParams) (*GetAppsAppCallsRouteOK, error) {
func (a *Client) GetAppsAppCalls(params *GetAppsAppCallsParams) (*GetAppsAppCallsOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewGetAppsAppCallsRouteParams()
params = NewGetAppsAppCallsParams()
}
result, err := a.transport.Submit(&runtime.ClientOperation{
ID: "GetAppsAppCallsRoute",
ID: "GetAppsAppCalls",
Method: "GET",
PathPattern: "/apps/{app}/calls/{route}",
PathPattern: "/apps/{app}/calls/",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &GetAppsAppCallsRouteReader{formats: a.formats},
Reader: &GetAppsAppCallsReader{formats: a.formats},
Context: params.Context,
Client: params.HTTPClient,
})
if err != nil {
return nil, err
}
return result.(*GetAppsAppCallsRouteOK), nil
return result.(*GetAppsAppCallsOK), nil
}
/*
GetCallsCall gets call information
GetAppsAppCallsCall gets call information
Get call information
*/
func (a *Client) GetCallsCall(params *GetCallsCallParams) (*GetCallsCallOK, error) {
func (a *Client) GetAppsAppCallsCall(params *GetAppsAppCallsCallParams) (*GetAppsAppCallsCallOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewGetCallsCallParams()
params = NewGetAppsAppCallsCallParams()
}
result, err := a.transport.Submit(&runtime.ClientOperation{
ID: "GetCallsCall",
ID: "GetAppsAppCallsCall",
Method: "GET",
PathPattern: "/calls/{call}",
PathPattern: "/apps/{app}/calls/{call}",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &GetCallsCallReader{formats: a.formats},
Reader: &GetAppsAppCallsCallReader{formats: a.formats},
Context: params.Context,
Client: params.HTTPClient,
})
if err != nil {
return nil, err
}
return result.(*GetCallsCallOK), nil
return result.(*GetAppsAppCallsCallOK), nil
}

View File

@@ -0,0 +1,156 @@
package call
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"time"
"golang.org/x/net/context"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
strfmt "github.com/go-openapi/strfmt"
)
// NewGetAppsAppCallsCallParams creates a new GetAppsAppCallsCallParams object
// with the default values initialized.
func NewGetAppsAppCallsCallParams() *GetAppsAppCallsCallParams {
var ()
return &GetAppsAppCallsCallParams{
timeout: cr.DefaultTimeout,
}
}
// NewGetAppsAppCallsCallParamsWithTimeout creates a new GetAppsAppCallsCallParams object
// with the default values initialized, and the ability to set a timeout on a request
func NewGetAppsAppCallsCallParamsWithTimeout(timeout time.Duration) *GetAppsAppCallsCallParams {
var ()
return &GetAppsAppCallsCallParams{
timeout: timeout,
}
}
// NewGetAppsAppCallsCallParamsWithContext creates a new GetAppsAppCallsCallParams object
// with the default values initialized, and the ability to set a context for a request
func NewGetAppsAppCallsCallParamsWithContext(ctx context.Context) *GetAppsAppCallsCallParams {
var ()
return &GetAppsAppCallsCallParams{
Context: ctx,
}
}
// NewGetAppsAppCallsCallParamsWithHTTPClient creates a new GetAppsAppCallsCallParams object
// with the default values initialized, and the ability to set a custom HTTPClient for a request
func NewGetAppsAppCallsCallParamsWithHTTPClient(client *http.Client) *GetAppsAppCallsCallParams {
var ()
return &GetAppsAppCallsCallParams{
HTTPClient: client,
}
}
/*GetAppsAppCallsCallParams contains all the parameters to send to the API endpoint
for the get apps app calls call operation typically these are written to a http.Request
*/
type GetAppsAppCallsCallParams struct {
/*App
app name
*/
App string
/*Call
Call ID.
*/
Call string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithTimeout adds the timeout to the get apps app calls call params
func (o *GetAppsAppCallsCallParams) WithTimeout(timeout time.Duration) *GetAppsAppCallsCallParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the get apps app calls call params
func (o *GetAppsAppCallsCallParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the get apps app calls call params
func (o *GetAppsAppCallsCallParams) WithContext(ctx context.Context) *GetAppsAppCallsCallParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the get apps app calls call params
func (o *GetAppsAppCallsCallParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the get apps app calls call params
func (o *GetAppsAppCallsCallParams) WithHTTPClient(client *http.Client) *GetAppsAppCallsCallParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the get apps app calls call params
func (o *GetAppsAppCallsCallParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithApp adds the app to the get apps app calls call params
func (o *GetAppsAppCallsCallParams) WithApp(app string) *GetAppsAppCallsCallParams {
o.SetApp(app)
return o
}
// SetApp adds the app to the get apps app calls call params
func (o *GetAppsAppCallsCallParams) SetApp(app string) {
o.App = app
}
// WithCall adds the call to the get apps app calls call params
func (o *GetAppsAppCallsCallParams) WithCall(call string) *GetAppsAppCallsCallParams {
o.SetCall(call)
return o
}
// SetCall adds the call to the get apps app calls call params
func (o *GetAppsAppCallsCallParams) SetCall(call string) {
o.Call = call
}
// WriteToRequest writes these params to a swagger request
func (o *GetAppsAppCallsCallParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param app
if err := r.SetPathParam("app", o.App); err != nil {
return err
}
// path param call
if err := r.SetPathParam("call", o.Call); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -0,0 +1,101 @@
package call
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"fmt"
"io"
"github.com/go-openapi/runtime"
strfmt "github.com/go-openapi/strfmt"
"github.com/funcy/functions_go/models"
)
// GetAppsAppCallsCallReader is a Reader for the GetAppsAppCallsCall structure.
type GetAppsAppCallsCallReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *GetAppsAppCallsCallReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewGetAppsAppCallsCallOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 404:
result := NewGetAppsAppCallsCallNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("unknown error", response, response.Code())
}
}
// NewGetAppsAppCallsCallOK creates a GetAppsAppCallsCallOK with default headers values
func NewGetAppsAppCallsCallOK() *GetAppsAppCallsCallOK {
return &GetAppsAppCallsCallOK{}
}
/*GetAppsAppCallsCallOK handles this case with default header values.
Call found
*/
type GetAppsAppCallsCallOK struct {
Payload *models.CallWrapper
}
func (o *GetAppsAppCallsCallOK) Error() string {
return fmt.Sprintf("[GET /apps/{app}/calls/{call}][%d] getAppsAppCallsCallOK %+v", 200, o.Payload)
}
func (o *GetAppsAppCallsCallOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.CallWrapper)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewGetAppsAppCallsCallNotFound creates a GetAppsAppCallsCallNotFound with default headers values
func NewGetAppsAppCallsCallNotFound() *GetAppsAppCallsCallNotFound {
return &GetAppsAppCallsCallNotFound{}
}
/*GetAppsAppCallsCallNotFound handles this case with default header values.
Call not found.
*/
type GetAppsAppCallsCallNotFound struct {
Payload *models.Error
}
func (o *GetAppsAppCallsCallNotFound) Error() string {
return fmt.Sprintf("[GET /apps/{app}/calls/{call}][%d] getAppsAppCallsCallNotFound %+v", 404, o.Payload)
}
func (o *GetAppsAppCallsCallNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.Error)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View File

@@ -0,0 +1,167 @@
package call
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"time"
"golang.org/x/net/context"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
strfmt "github.com/go-openapi/strfmt"
)
// NewGetAppsAppCallsParams creates a new GetAppsAppCallsParams object
// with the default values initialized.
func NewGetAppsAppCallsParams() *GetAppsAppCallsParams {
var ()
return &GetAppsAppCallsParams{
timeout: cr.DefaultTimeout,
}
}
// NewGetAppsAppCallsParamsWithTimeout creates a new GetAppsAppCallsParams object
// with the default values initialized, and the ability to set a timeout on a request
func NewGetAppsAppCallsParamsWithTimeout(timeout time.Duration) *GetAppsAppCallsParams {
var ()
return &GetAppsAppCallsParams{
timeout: timeout,
}
}
// NewGetAppsAppCallsParamsWithContext creates a new GetAppsAppCallsParams object
// with the default values initialized, and the ability to set a context for a request
func NewGetAppsAppCallsParamsWithContext(ctx context.Context) *GetAppsAppCallsParams {
var ()
return &GetAppsAppCallsParams{
Context: ctx,
}
}
// NewGetAppsAppCallsParamsWithHTTPClient creates a new GetAppsAppCallsParams object
// with the default values initialized, and the ability to set a custom HTTPClient for a request
func NewGetAppsAppCallsParamsWithHTTPClient(client *http.Client) *GetAppsAppCallsParams {
var ()
return &GetAppsAppCallsParams{
HTTPClient: client,
}
}
/*GetAppsAppCallsParams contains all the parameters to send to the API endpoint
for the get apps app calls operation typically these are written to a http.Request
*/
type GetAppsAppCallsParams struct {
/*App
App name.
*/
App string
/*Route
App route.
*/
Route *string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithTimeout adds the timeout to the get apps app calls params
func (o *GetAppsAppCallsParams) WithTimeout(timeout time.Duration) *GetAppsAppCallsParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the get apps app calls params
func (o *GetAppsAppCallsParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the get apps app calls params
func (o *GetAppsAppCallsParams) WithContext(ctx context.Context) *GetAppsAppCallsParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the get apps app calls params
func (o *GetAppsAppCallsParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the get apps app calls params
func (o *GetAppsAppCallsParams) WithHTTPClient(client *http.Client) *GetAppsAppCallsParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the get apps app calls params
func (o *GetAppsAppCallsParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithApp adds the app to the get apps app calls params
func (o *GetAppsAppCallsParams) WithApp(app string) *GetAppsAppCallsParams {
o.SetApp(app)
return o
}
// SetApp adds the app to the get apps app calls params
func (o *GetAppsAppCallsParams) SetApp(app string) {
o.App = app
}
// WithRoute adds the route to the get apps app calls params
func (o *GetAppsAppCallsParams) WithRoute(route *string) *GetAppsAppCallsParams {
o.SetRoute(route)
return o
}
// SetRoute adds the route to the get apps app calls params
func (o *GetAppsAppCallsParams) SetRoute(route *string) {
o.Route = route
}
// WriteToRequest writes these params to a swagger request
func (o *GetAppsAppCallsParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param app
if err := r.SetPathParam("app", o.App); err != nil {
return err
}
if o.Route != nil {
// query param route
var qrRoute string
if o.Route != nil {
qrRoute = *o.Route
}
qRoute := qrRoute
if qRoute != "" {
if err := r.SetQueryParam("route", qRoute); err != nil {
return err
}
}
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -0,0 +1,101 @@
package call
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"fmt"
"io"
"github.com/go-openapi/runtime"
strfmt "github.com/go-openapi/strfmt"
"github.com/funcy/functions_go/models"
)
// GetAppsAppCallsReader is a Reader for the GetAppsAppCalls structure.
type GetAppsAppCallsReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *GetAppsAppCallsReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewGetAppsAppCallsOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 404:
result := NewGetAppsAppCallsNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("unknown error", response, response.Code())
}
}
// NewGetAppsAppCallsOK creates a GetAppsAppCallsOK with default headers values
func NewGetAppsAppCallsOK() *GetAppsAppCallsOK {
return &GetAppsAppCallsOK{}
}
/*GetAppsAppCallsOK handles this case with default header values.
Calls found
*/
type GetAppsAppCallsOK struct {
Payload *models.CallsWrapper
}
func (o *GetAppsAppCallsOK) Error() string {
return fmt.Sprintf("[GET /apps/{app}/calls/][%d] getAppsAppCallsOK %+v", 200, o.Payload)
}
func (o *GetAppsAppCallsOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.CallsWrapper)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewGetAppsAppCallsNotFound creates a GetAppsAppCallsNotFound with default headers values
func NewGetAppsAppCallsNotFound() *GetAppsAppCallsNotFound {
return &GetAppsAppCallsNotFound{}
}
/*GetAppsAppCallsNotFound handles this case with default header values.
Calls not found.
*/
type GetAppsAppCallsNotFound struct {
Payload *models.Error
}
func (o *GetAppsAppCallsNotFound) Error() string {
return fmt.Sprintf("[GET /apps/{app}/calls/][%d] getAppsAppCallsNotFound %+v", 404, o.Payload)
}
func (o *GetAppsAppCallsNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.Error)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View File

@@ -0,0 +1,156 @@
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"time"
"golang.org/x/net/context"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
strfmt "github.com/go-openapi/strfmt"
)
// NewDeleteAppsAppCallsCallLogParams creates a new DeleteAppsAppCallsCallLogParams object
// with the default values initialized.
func NewDeleteAppsAppCallsCallLogParams() *DeleteAppsAppCallsCallLogParams {
var ()
return &DeleteAppsAppCallsCallLogParams{
timeout: cr.DefaultTimeout,
}
}
// NewDeleteAppsAppCallsCallLogParamsWithTimeout creates a new DeleteAppsAppCallsCallLogParams object
// with the default values initialized, and the ability to set a timeout on a request
func NewDeleteAppsAppCallsCallLogParamsWithTimeout(timeout time.Duration) *DeleteAppsAppCallsCallLogParams {
var ()
return &DeleteAppsAppCallsCallLogParams{
timeout: timeout,
}
}
// NewDeleteAppsAppCallsCallLogParamsWithContext creates a new DeleteAppsAppCallsCallLogParams object
// with the default values initialized, and the ability to set a context for a request
func NewDeleteAppsAppCallsCallLogParamsWithContext(ctx context.Context) *DeleteAppsAppCallsCallLogParams {
var ()
return &DeleteAppsAppCallsCallLogParams{
Context: ctx,
}
}
// NewDeleteAppsAppCallsCallLogParamsWithHTTPClient creates a new DeleteAppsAppCallsCallLogParams object
// with the default values initialized, and the ability to set a custom HTTPClient for a request
func NewDeleteAppsAppCallsCallLogParamsWithHTTPClient(client *http.Client) *DeleteAppsAppCallsCallLogParams {
var ()
return &DeleteAppsAppCallsCallLogParams{
HTTPClient: client,
}
}
/*DeleteAppsAppCallsCallLogParams contains all the parameters to send to the API endpoint
for the delete apps app calls call log operation typically these are written to a http.Request
*/
type DeleteAppsAppCallsCallLogParams struct {
/*App
App name.
*/
App string
/*Call
Call ID.
*/
Call string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithTimeout adds the timeout to the delete apps app calls call log params
func (o *DeleteAppsAppCallsCallLogParams) WithTimeout(timeout time.Duration) *DeleteAppsAppCallsCallLogParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the delete apps app calls call log params
func (o *DeleteAppsAppCallsCallLogParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the delete apps app calls call log params
func (o *DeleteAppsAppCallsCallLogParams) WithContext(ctx context.Context) *DeleteAppsAppCallsCallLogParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the delete apps app calls call log params
func (o *DeleteAppsAppCallsCallLogParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the delete apps app calls call log params
func (o *DeleteAppsAppCallsCallLogParams) WithHTTPClient(client *http.Client) *DeleteAppsAppCallsCallLogParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the delete apps app calls call log params
func (o *DeleteAppsAppCallsCallLogParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithApp adds the app to the delete apps app calls call log params
func (o *DeleteAppsAppCallsCallLogParams) WithApp(app string) *DeleteAppsAppCallsCallLogParams {
o.SetApp(app)
return o
}
// SetApp adds the app to the delete apps app calls call log params
func (o *DeleteAppsAppCallsCallLogParams) SetApp(app string) {
o.App = app
}
// WithCall adds the call to the delete apps app calls call log params
func (o *DeleteAppsAppCallsCallLogParams) WithCall(call string) *DeleteAppsAppCallsCallLogParams {
o.SetCall(call)
return o
}
// SetCall adds the call to the delete apps app calls call log params
func (o *DeleteAppsAppCallsCallLogParams) SetCall(call string) {
o.Call = call
}
// WriteToRequest writes these params to a swagger request
func (o *DeleteAppsAppCallsCallLogParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param app
if err := r.SetPathParam("app", o.App); err != nil {
return err
}
// path param call
if err := r.SetPathParam("call", o.Call); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -0,0 +1,138 @@
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"fmt"
"io"
"github.com/go-openapi/runtime"
strfmt "github.com/go-openapi/strfmt"
"github.com/funcy/functions_go/models"
)
// DeleteAppsAppCallsCallLogReader is a Reader for the DeleteAppsAppCallsCallLog structure.
type DeleteAppsAppCallsCallLogReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *DeleteAppsAppCallsCallLogReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 202:
result := NewDeleteAppsAppCallsCallLogAccepted()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 404:
result := NewDeleteAppsAppCallsCallLogNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
result := NewDeleteAppsAppCallsCallLogDefault(response.Code())
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
if response.Code()/100 == 2 {
return result, nil
}
return nil, result
}
}
// NewDeleteAppsAppCallsCallLogAccepted creates a DeleteAppsAppCallsCallLogAccepted with default headers values
func NewDeleteAppsAppCallsCallLogAccepted() *DeleteAppsAppCallsCallLogAccepted {
return &DeleteAppsAppCallsCallLogAccepted{}
}
/*DeleteAppsAppCallsCallLogAccepted handles this case with default header values.
Log delete request accepted
*/
type DeleteAppsAppCallsCallLogAccepted struct {
}
func (o *DeleteAppsAppCallsCallLogAccepted) Error() string {
return fmt.Sprintf("[DELETE /apps/{app}/calls/{call}/log][%d] deleteAppsAppCallsCallLogAccepted ", 202)
}
func (o *DeleteAppsAppCallsCallLogAccepted) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
return nil
}
// NewDeleteAppsAppCallsCallLogNotFound creates a DeleteAppsAppCallsCallLogNotFound with default headers values
func NewDeleteAppsAppCallsCallLogNotFound() *DeleteAppsAppCallsCallLogNotFound {
return &DeleteAppsAppCallsCallLogNotFound{}
}
/*DeleteAppsAppCallsCallLogNotFound handles this case with default header values.
Does not exist.
*/
type DeleteAppsAppCallsCallLogNotFound struct {
Payload *models.Error
}
func (o *DeleteAppsAppCallsCallLogNotFound) Error() string {
return fmt.Sprintf("[DELETE /apps/{app}/calls/{call}/log][%d] deleteAppsAppCallsCallLogNotFound %+v", 404, o.Payload)
}
func (o *DeleteAppsAppCallsCallLogNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.Error)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewDeleteAppsAppCallsCallLogDefault creates a DeleteAppsAppCallsCallLogDefault with default headers values
func NewDeleteAppsAppCallsCallLogDefault(code int) *DeleteAppsAppCallsCallLogDefault {
return &DeleteAppsAppCallsCallLogDefault{
_statusCode: code,
}
}
/*DeleteAppsAppCallsCallLogDefault handles this case with default header values.
Unexpected error
*/
type DeleteAppsAppCallsCallLogDefault struct {
_statusCode int
Payload *models.Error
}
// Code gets the status code for the delete apps app calls call log default response
func (o *DeleteAppsAppCallsCallLogDefault) Code() int {
return o._statusCode
}
func (o *DeleteAppsAppCallsCallLogDefault) Error() string {
return fmt.Sprintf("[DELETE /apps/{app}/calls/{call}/log][%d] DeleteAppsAppCallsCallLog default %+v", o._statusCode, o.Payload)
}
func (o *DeleteAppsAppCallsCallLogDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.Error)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View File

@@ -0,0 +1,156 @@
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"time"
"golang.org/x/net/context"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime"
cr "github.com/go-openapi/runtime/client"
strfmt "github.com/go-openapi/strfmt"
)
// NewGetAppsAppCallsCallLogParams creates a new GetAppsAppCallsCallLogParams object
// with the default values initialized.
func NewGetAppsAppCallsCallLogParams() *GetAppsAppCallsCallLogParams {
var ()
return &GetAppsAppCallsCallLogParams{
timeout: cr.DefaultTimeout,
}
}
// NewGetAppsAppCallsCallLogParamsWithTimeout creates a new GetAppsAppCallsCallLogParams object
// with the default values initialized, and the ability to set a timeout on a request
func NewGetAppsAppCallsCallLogParamsWithTimeout(timeout time.Duration) *GetAppsAppCallsCallLogParams {
var ()
return &GetAppsAppCallsCallLogParams{
timeout: timeout,
}
}
// NewGetAppsAppCallsCallLogParamsWithContext creates a new GetAppsAppCallsCallLogParams object
// with the default values initialized, and the ability to set a context for a request
func NewGetAppsAppCallsCallLogParamsWithContext(ctx context.Context) *GetAppsAppCallsCallLogParams {
var ()
return &GetAppsAppCallsCallLogParams{
Context: ctx,
}
}
// NewGetAppsAppCallsCallLogParamsWithHTTPClient creates a new GetAppsAppCallsCallLogParams object
// with the default values initialized, and the ability to set a custom HTTPClient for a request
func NewGetAppsAppCallsCallLogParamsWithHTTPClient(client *http.Client) *GetAppsAppCallsCallLogParams {
var ()
return &GetAppsAppCallsCallLogParams{
HTTPClient: client,
}
}
/*GetAppsAppCallsCallLogParams contains all the parameters to send to the API endpoint
for the get apps app calls call log operation typically these are written to a http.Request
*/
type GetAppsAppCallsCallLogParams struct {
/*App
App Name
*/
App string
/*Call
Call ID.
*/
Call string
timeout time.Duration
Context context.Context
HTTPClient *http.Client
}
// WithTimeout adds the timeout to the get apps app calls call log params
func (o *GetAppsAppCallsCallLogParams) WithTimeout(timeout time.Duration) *GetAppsAppCallsCallLogParams {
o.SetTimeout(timeout)
return o
}
// SetTimeout adds the timeout to the get apps app calls call log params
func (o *GetAppsAppCallsCallLogParams) SetTimeout(timeout time.Duration) {
o.timeout = timeout
}
// WithContext adds the context to the get apps app calls call log params
func (o *GetAppsAppCallsCallLogParams) WithContext(ctx context.Context) *GetAppsAppCallsCallLogParams {
o.SetContext(ctx)
return o
}
// SetContext adds the context to the get apps app calls call log params
func (o *GetAppsAppCallsCallLogParams) SetContext(ctx context.Context) {
o.Context = ctx
}
// WithHTTPClient adds the HTTPClient to the get apps app calls call log params
func (o *GetAppsAppCallsCallLogParams) WithHTTPClient(client *http.Client) *GetAppsAppCallsCallLogParams {
o.SetHTTPClient(client)
return o
}
// SetHTTPClient adds the HTTPClient to the get apps app calls call log params
func (o *GetAppsAppCallsCallLogParams) SetHTTPClient(client *http.Client) {
o.HTTPClient = client
}
// WithApp adds the app to the get apps app calls call log params
func (o *GetAppsAppCallsCallLogParams) WithApp(app string) *GetAppsAppCallsCallLogParams {
o.SetApp(app)
return o
}
// SetApp adds the app to the get apps app calls call log params
func (o *GetAppsAppCallsCallLogParams) SetApp(app string) {
o.App = app
}
// WithCall adds the call to the get apps app calls call log params
func (o *GetAppsAppCallsCallLogParams) WithCall(call string) *GetAppsAppCallsCallLogParams {
o.SetCall(call)
return o
}
// SetCall adds the call to the get apps app calls call log params
func (o *GetAppsAppCallsCallLogParams) SetCall(call string) {
o.Call = call
}
// WriteToRequest writes these params to a swagger request
func (o *GetAppsAppCallsCallLogParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
if err := r.SetTimeout(o.timeout); err != nil {
return err
}
var res []error
// path param app
if err := r.SetPathParam("app", o.App); err != nil {
return err
}
// path param call
if err := r.SetPathParam("call", o.Call); err != nil {
return err
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}

View File

@@ -0,0 +1,101 @@
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"fmt"
"io"
"github.com/go-openapi/runtime"
strfmt "github.com/go-openapi/strfmt"
"github.com/funcy/functions_go/models"
)
// GetAppsAppCallsCallLogReader is a Reader for the GetAppsAppCallsCallLog structure.
type GetAppsAppCallsCallLogReader struct {
formats strfmt.Registry
}
// ReadResponse reads a server response into the received o.
func (o *GetAppsAppCallsCallLogReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
switch response.Code() {
case 200:
result := NewGetAppsAppCallsCallLogOK()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return result, nil
case 404:
result := NewGetAppsAppCallsCallLogNotFound()
if err := result.readResponse(response, consumer, o.formats); err != nil {
return nil, err
}
return nil, result
default:
return nil, runtime.NewAPIError("unknown error", response, response.Code())
}
}
// NewGetAppsAppCallsCallLogOK creates a GetAppsAppCallsCallLogOK with default headers values
func NewGetAppsAppCallsCallLogOK() *GetAppsAppCallsCallLogOK {
return &GetAppsAppCallsCallLogOK{}
}
/*GetAppsAppCallsCallLogOK handles this case with default header values.
Log found
*/
type GetAppsAppCallsCallLogOK struct {
Payload *models.LogWrapper
}
func (o *GetAppsAppCallsCallLogOK) Error() string {
return fmt.Sprintf("[GET /apps/{app}/calls/{call}/log][%d] getAppsAppCallsCallLogOK %+v", 200, o.Payload)
}
func (o *GetAppsAppCallsCallLogOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.LogWrapper)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}
// NewGetAppsAppCallsCallLogNotFound creates a GetAppsAppCallsCallLogNotFound with default headers values
func NewGetAppsAppCallsCallLogNotFound() *GetAppsAppCallsCallLogNotFound {
return &GetAppsAppCallsCallLogNotFound{}
}
/*GetAppsAppCallsCallLogNotFound handles this case with default header values.
Log not found.
*/
type GetAppsAppCallsCallLogNotFound struct {
Payload *models.Error
}
func (o *GetAppsAppCallsCallLogNotFound) Error() string {
return fmt.Sprintf("[GET /apps/{app}/calls/{call}/log][%d] getAppsAppCallsCallLogNotFound %+v", 404, o.Payload)
}
func (o *GetAppsAppCallsCallLogNotFound) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
o.Payload = new(models.Error)
// response payload
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
return err
}
return nil
}

View File

@@ -23,62 +23,62 @@ type Client struct {
}
/*
DeleteCallsCallLog deletes call log entry
DeleteAppsAppCallsCallLog deletes call log entry
Delete call log entry
*/
func (a *Client) DeleteCallsCallLog(params *DeleteCallsCallLogParams) (*DeleteCallsCallLogAccepted, error) {
func (a *Client) DeleteAppsAppCallsCallLog(params *DeleteAppsAppCallsCallLogParams) (*DeleteAppsAppCallsCallLogAccepted, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewDeleteCallsCallLogParams()
params = NewDeleteAppsAppCallsCallLogParams()
}
result, err := a.transport.Submit(&runtime.ClientOperation{
ID: "DeleteCallsCallLog",
ID: "DeleteAppsAppCallsCallLog",
Method: "DELETE",
PathPattern: "/calls/{call}/log",
PathPattern: "/apps/{app}/calls/{call}/log",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &DeleteCallsCallLogReader{formats: a.formats},
Reader: &DeleteAppsAppCallsCallLogReader{formats: a.formats},
Context: params.Context,
Client: params.HTTPClient,
})
if err != nil {
return nil, err
}
return result.(*DeleteCallsCallLogAccepted), nil
return result.(*DeleteAppsAppCallsCallLogAccepted), nil
}
/*
GetCallsCallLog gets call logs
GetAppsAppCallsCallLog gets call logs
Get call logs
*/
func (a *Client) GetCallsCallLog(params *GetCallsCallLogParams) (*GetCallsCallLogOK, error) {
func (a *Client) GetAppsAppCallsCallLog(params *GetAppsAppCallsCallLogParams) (*GetAppsAppCallsCallLogOK, error) {
// TODO: Validate the params before sending
if params == nil {
params = NewGetCallsCallLogParams()
params = NewGetAppsAppCallsCallLogParams()
}
result, err := a.transport.Submit(&runtime.ClientOperation{
ID: "GetCallsCallLog",
ID: "GetAppsAppCallsCallLog",
Method: "GET",
PathPattern: "/calls/{call}/log",
PathPattern: "/apps/{app}/calls/{call}/log",
ProducesMediaTypes: []string{"application/json"},
ConsumesMediaTypes: []string{"application/json"},
Schemes: []string{"http", "https"},
Params: params,
Reader: &GetCallsCallLogReader{formats: a.formats},
Reader: &GetAppsAppCallsCallLogReader{formats: a.formats},
Context: params.Context,
Client: params.HTTPClient,
})
if err != nil {
return nil, err
}
return result.(*GetCallsCallLogOK), nil
return result.(*GetAppsAppCallsCallLogOK), nil
}

View File

@@ -6,7 +6,7 @@ swagger: '2.0'
info:
title: Oracle Functions
description: The open source serverless platform.
version: "0.1.34"
version: "0.1.35"
# the domain of the service
host: "127.0.0.1:8080"
# array of all schemes that your API supports
@@ -352,7 +352,7 @@ paths:
schema:
$ref: '#/definitions/Error'
/calls/{call}/log:
/apps/{app}/calls/{call}/log:
get:
summary: Get call logs
description: Get call logs
@@ -360,6 +360,11 @@ paths:
- Call
- Log
parameters:
- name: app
description: App Name
required: true
type: string
in: path
- name: call
description: Call ID.
required: true
@@ -386,6 +391,11 @@ paths:
required: true
type: string
in: path
- name: app
description: App name.
required: true
type: string
in: path
responses:
202:
description: Log delete request accepted
@@ -398,13 +408,18 @@ paths:
schema:
$ref: '#/definitions/Error'
/calls/{call}:
/apps/{app}/calls/{call}:
get:
summary: Get call information
description: Get call information
tags:
- Call
parameters:
- name: app
description: app name
required: true
type: string
in: path
- name: call
description: Call ID.
required: true
@@ -420,10 +435,10 @@ paths:
schema:
$ref: '#/definitions/Error'
/apps/{app}/calls/{route}:
/apps/{app}/calls/:
get:
summary: Get route-bound calls.
description: Get route-bound calls.
summary: Get app-bound calls.
description: Get app-bound calls can filter to route-bound calls.
tags:
- Call
parameters:
@@ -434,9 +449,9 @@ paths:
in: path
- name: route
description: App route.
required: true
required: false
type: string
in: path
in: query
responses:
200:
description: Calls found

99
glide.lock generated
View File

@@ -1,5 +1,5 @@
hash: 68fe5d3130a8346f3e38c0924b70369592ccdf0ffe503858056694a71a19acd2
updated: 2017-07-21T18:13:30.488739267-07:00
hash: a333d90d0cb65a059f0459e426d4a1a11cc4b7385beca641a11ebf2e67b2a371
updated: 2017-07-26T12:30:24.327734143-07:00
imports:
- name: code.cloudfoundry.org/bytefmt
version: f4415fafc5619dd75599a54a7c91fb3948ad58bd
@@ -13,6 +13,38 @@ imports:
- lib/go/thrift
- name: github.com/asaskevich/govalidator
version: aa5cce4a76edb1a5acecab1870c17abbffb5419e
- name: github.com/aws/aws-sdk-go
version: 90dec2183a5f5458ee79cbaf4b8e9ab910bc81a6
subpackages:
- aws
- aws/awserr
- aws/awsutil
- aws/client
- aws/client/metadata
- aws/corehandlers
- aws/credentials
- aws/credentials/ec2rolecreds
- aws/defaults
- aws/ec2metadata
- aws/request
- aws/session
- aws/signer/v4
- private/endpoints
- private/protocol
- private/protocol/json/jsonutil
- private/protocol/jsonrpc
- private/protocol/query
- private/protocol/query/queryutil
- private/protocol/rest
- private/protocol/restjson
- private/protocol/restxml
- private/protocol/xml/xmlutil
- private/waiter
- service/cloudfront/sign
- service/lambda
- service/s3
- vendor/github.com/go-ini/ini
- vendor/github.com/jmespath/go-jmespath
- name: github.com/Azure/go-ansiterm
version: fa152c58bc15761d0200cb75fe958b89a9d4888e
subpackages:
@@ -27,6 +59,10 @@ imports:
version: 230eff6403e22b43f5fba7b28466dae4718934dd
- name: github.com/cenkalti/backoff
version: 5d150e7eec023ce7a124856b37c68e54b4050ac7
- name: github.com/coreos/go-semver
version: 1817cd4bea52af76542157eeabd74b057d1a199e
subpackages:
- semver
- name: github.com/davecgh/go-spew
version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
subpackages:
@@ -106,7 +142,7 @@ imports:
- name: github.com/fsouza/go-dockerclient
version: c933ed18bef34ec2955de03de8ef9a3bb996e3df
- name: github.com/funcy/functions_go
version: 5d9948e8b1292c5421b5dd98bb6a9b5535d5e1ba
version: c540b7a8e1af8dad992a3b520175db85f8e53636
subpackages:
- client
- client/apps
@@ -121,11 +157,18 @@ imports:
subpackages:
- internal
- redis
- name: github.com/giantswarm/semver-bump
version: 7ec6ac8985c24dd50b4942f9a908d13cdfe70f23
subpackages:
- bump
- storage
- name: github.com/gin-gonic/gin
version: d5b353c5d5a560322e6d96121c814115562501f7
subpackages:
- binding
- render
- name: github.com/go-ini/ini
version: 3d73f4b845efdf9989fffd4b4e562727744a34ba
- name: github.com/go-logfmt/logfmt
version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5
- name: github.com/go-openapi/analysis
@@ -152,6 +195,8 @@ imports:
version: f3f9494671f93fcff853e3c6e9e948b3eb71e590
- name: github.com/go-openapi/validate
version: 035dcd74f1f61e83debe1c22950dc53556e7e4b2
- name: github.com/go-resty/resty
version: 6d8c785a63e4b7505c88451cf9c5b452ccf2454c
- name: github.com/go-sql-driver/mysql
version: 56226343bd543f91a3930ed73ebdd03cfd633e85
- name: github.com/gogo/protobuf
@@ -197,12 +242,18 @@ imports:
- api
- config
- mq
- name: github.com/jmespath/go-jmespath
version: bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d
- name: github.com/jmoiron/jsonq
version: e874b168d07ecc7808bc950a17998a8aa3141d82
- name: github.com/jmoiron/sqlx
version: d9bd385d68c068f1fabb5057e3dedcbcbb039d0f
subpackages:
- reflectx
- name: github.com/juju/errgo
version: 08cceb5d0b5331634b9826762a8fd53b29b86ad8
subpackages:
- errors
- name: github.com/kr/logfmt
version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0
- name: github.com/lib/pq
@@ -227,8 +278,26 @@ imports:
version: f533f7a102197536779ea3a8cb881d639e21ec5a
- name: github.com/mitchellh/mapstructure
version: d0303fe809921458f417bcf828397a65db30a7e4
- name: github.com/moby/moby
version: 72cda6a6c2f25854bea2d69168082684f2c9feca
subpackages:
- pkg/jsonmessage
- name: github.com/Nvveen/Gotty
version: cd527374f1e5bff4938207604a14f2e38a9cf512
- name: github.com/onsi/gomega
version: c893efa28eb45626cdaa76c9f653b62488858837
subpackages:
- format
- internal/assertion
- internal/asyncassertion
- internal/oraclematcher
- internal/testingtsupport
- matchers
- matchers/support/goraph/bipartitegraph
- matchers/support/goraph/edge
- matchers/support/goraph/node
- matchers/support/goraph/util
- types
- name: github.com/opencontainers/runc
version: ea35825a6350511ab93fe24e69c0723d6728616d
subpackages:
@@ -271,14 +340,14 @@ imports:
version: 1f30fe9094a513ce4c700b9a54458bbb0c96996c
- name: github.com/Shopify/sarama
version: 2fd980e23bdcbb8edeb78fc704de0c39a6567ffc
- name: github.com/sirupsen/logrus
version: ba1b36c82c5e05c4f912a88eab0dcd91a171688f
- name: github.com/Sirupsen/logrus
version: ba1b36c82c5e05c4f912a88eab0dcd91a171688f
repo: https://github.com/sirupsen/logrus.git
vcs: git
subpackages:
- hooks/syslog
- name: github.com/sirupsen/logrus
version: ba1b36c82c5e05c4f912a88eab0dcd91a171688f
- name: github.com/spf13/afero
version: 9be650865eab0c12963d8753212f4f9c66cdcf12
subpackages:
@@ -291,6 +360,8 @@ imports:
version: 5644820622454e71517561946e3d94b9f9db6842
- name: github.com/spf13/viper
version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2
- name: github.com/urfave/cli
version: 4b90d79a682b4bf685762c7452db20f2a676ecb2
- name: golang.org/x/crypto
version: c10c31b5e94b6f7a0283272dc2bb27163dcea24b
subpackages:
@@ -301,8 +372,12 @@ imports:
subpackages:
- context
- context/ctxhttp
- html
- html/atom
- html/charset
- idna
- proxy
- publicsuffix
- name: golang.org/x/sys
version: 0b25a408a50076fbbcae6b7ac0ea5fbb0b085e79
subpackages:
@@ -311,6 +386,20 @@ imports:
- name: golang.org/x/text
version: 210eee5cf7323015d097341bcf7166130d001cd8
subpackages:
- encoding
- encoding/charmap
- encoding/htmlindex
- encoding/internal
- encoding/internal/identifier
- encoding/japanese
- encoding/korean
- encoding/simplifiedchinese
- encoding/traditionalchinese
- encoding/unicode
- internal/tag
- internal/utf8internal
- language
- runes
- transform
- unicode/norm
- width

View File

@@ -4,6 +4,7 @@ excludeDirs:
import:
- package: code.cloudfoundry.org/bytefmt
- package: github.com/funcy/functions_go
version: ^0.1.35
subpackages:
- models
- package: github.com/Sirupsen/logrus
@@ -28,7 +29,7 @@ import:
subpackages:
- cli/config/configfile
- package: github.com/docker/distribution
branch: master
branch: master
- package: github.com/fsouza/go-dockerclient
- package: github.com/garyburd/redigo
subpackages:

View File

@@ -15,12 +15,12 @@ func TestCalls(t *testing.T) {
t.Run("list-calls-for-missing-app", func(t *testing.T) {
t.Parallel()
s := SetupDefaultSuite()
cfg := &call.GetAppsAppCallsRouteParams{
cfg := &call.GetAppsAppCallsParams{
App: s.AppName,
Route: s.RoutePath,
Route: &s.RoutePath,
Context: s.Context,
}
_, err := s.Client.Call.GetAppsAppCallsRoute(cfg)
_, err := s.Client.Call.GetAppsAppCalls(cfg)
if err == nil {
t.Errorf("Must fail with missing app error, but got %s", err)
}
@@ -31,12 +31,12 @@ func TestCalls(t *testing.T) {
s := SetupDefaultSuite()
CreateApp(t, s.Context, s.Client, s.AppName, map[string]string{})
cfg := &call.GetAppsAppCallsRouteParams{
cfg := &call.GetAppsAppCallsParams{
App: s.AppName,
Route: s.RoutePath,
Route: &s.RoutePath,
Context: s.Context,
}
_, err := s.Client.Call.GetAppsAppCallsRoute(cfg)
_, err := s.Client.Call.GetAppsAppCalls(cfg)
if err == nil {
t.Errorf("Must fail with missing route error, but got %s", err)
}
@@ -51,12 +51,13 @@ func TestCalls(t *testing.T) {
CreateRoute(t, s.Context, s.Client, s.AppName, s.RoutePath, s.Image, s.RouteType,
s.RouteConfig, s.RouteHeaders)
cfg := &call.GetCallsCallParams{
cfg := &call.GetAppsAppCallsCallParams{
Call: "dummy",
App: s.AppName,
Context: s.Context,
}
cfg.WithTimeout(time.Second * 60)
_, err := s.Client.Call.GetCallsCall(cfg)
_, err := s.Client.Call.GetAppsAppCallsCall(cfg)
if err == nil {
t.Error("Must fail because `dummy` call does not exist.")
}
@@ -85,7 +86,10 @@ func TestCalls(t *testing.T) {
Context: s.Context,
}
cfg.WithTimeout(time.Second * 60)
_, err := s.Client.Call.GetCallsCall(cfg)
_, err := s.Client.Call.GetAppsAppCalls(&call.GetAppsAppCallsParams{
App: s.AppName,
Route: &s.RoutePath,
})
if err != nil {
switch err.(type) {
case *call.GetCallsCallNotFound:
@@ -113,17 +117,18 @@ func TestCalls(t *testing.T) {
CallAsync(t, u, &bytes.Buffer{})
time.Sleep(time.Second * 8)
cfg := &call.GetAppsAppCallsRouteParams{
cfg := &call.GetAppsAppCallsParams{
App: s.AppName,
Route: s.RoutePath,
Route: &s.RoutePath,
Context: s.Context,
}
calls, err := s.Client.Call.GetAppsAppCallsRoute(cfg)
calls, err := s.Client.Call.GetAppsAppCalls(cfg)
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
if len(calls.Payload.Calls) == 0 {
if calls == nil || calls.Payload == nil || calls.Payload.Calls == nil || len(calls.Payload.Calls) == 0 {
t.Errorf("Must fail. There should be at least one call to `%v` route.", s.RoutePath)
return
}
for _, c := range calls.Payload.Calls {
if c.Path != s.RoutePath {

View File

@@ -159,12 +159,13 @@ func TestRouteExecutions(t *testing.T) {
callID := CallAsync(t, u, &bytes.Buffer{})
time.Sleep(time.Second * 10)
cfg := &call.GetCallsCallParams{
cfg := &call.GetAppsAppCallsCallParams{
Call: callID,
App: s.AppName,
Context: s.Context,
}
cfg.WithTimeout(time.Second * 60)
callResponse, err := s.Client.Call.GetCallsCall(cfg)
callResponse, err := s.Client.Call.GetAppsAppCallsCall(cfg)
if err != nil {
switch err.(type) {
case *call.GetCallsCallNotFound:
@@ -224,12 +225,13 @@ func TestRouteExecutions(t *testing.T) {
json.NewDecoder(output).Decode(tB)
cfg := &call.GetCallsCallParams{
cfg := &call.GetAppsAppCallsCallParams{
Call: tB.CallID,
App: s.AppName,
Context: s.Context,
}
cfg.WithTimeout(time.Second * 60)
callObj, err := s.Client.Call.GetCallsCall(cfg)
callObj, err := s.Client.Call.GetAppsAppCallsCall(cfg)
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
@@ -262,12 +264,13 @@ func TestRouteExecutions(t *testing.T) {
callID := CallAsync(t, u, &bytes.Buffer{})
time.Sleep(15 * time.Second)
cfg := &operations.GetCallsCallLogParams{
cfg := &operations.GetAppsAppCallsCallLogParams{
Call: callID,
App: s.AppName,
Context: s.Context,
}
logObj, err := s.Client.Operations.GetCallsCallLog(cfg)
logObj, err := s.Client.Operations.GetAppsAppCallsCallLog(cfg)
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
@@ -312,7 +315,7 @@ func TestRouteExecutions(t *testing.T) {
res := output.String()
if !strings.Contains("application/xml, application/json; q=0.2", res) {
t.Errorf("HEADER_ACCEPT='application/xml, application/json; q=0.2' "+
"should be in output, have:\n%", res)
"should be in output, have:%s\n", res)
}
DeleteRoute(t, s.Context, s.Client, s.AppName, routePath)
DeleteApp(t, s.Context, s.Client, s.AppName)
@@ -342,12 +345,13 @@ func TestRouteExecutions(t *testing.T) {
callID := CallAsync(t, u, content)
time.Sleep(10 * time.Second)
cfg := &operations.GetCallsCallLogParams{
cfg := &operations.GetAppsAppCallsCallLogParams{
Call: callID,
App: s.AppName,
Context: s.Context,
}
_, err := s.Client.Operations.GetCallsCallLog(cfg)
_, err := s.Client.Operations.GetAppsAppCallsCallLog(cfg)
if err != nil {
t.Errorf("Unexpected error: %s", err)
@@ -359,7 +363,7 @@ func TestRouteExecutions(t *testing.T) {
t.Run("exec-oversized-log-test", func(t *testing.T) {
t.Parallel()
t.Skip("Skipped until fix for https://github.com/fnproject/fn/issues/86.")
t.Skip("Skipped until fix for https://gitlab-odx.oracle.com/odx/functions/issues/86.")
s := SetupDefaultSuite()
routePath := "/log"
@@ -384,12 +388,13 @@ func TestRouteExecutions(t *testing.T) {
callID := CallAsync(t, u, content)
time.Sleep(5 * time.Second)
cfg := &operations.GetCallsCallLogParams{
cfg := &operations.GetAppsAppCallsCallLogParams{
Call: callID,
App: s.AppName,
Context: s.Context,
}
logObj, err := s.Client.Operations.GetCallsCallLog(cfg)
logObj, err := s.Client.Operations.GetAppsAppCallsCallLog(cfg)
if err != nil {
t.Errorf("Unexpected error: %s", err)
}

11
vendor/github.com/aws/aws-sdk-go/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,11 @@
dist
/doc
/doc-staging
.yardoc
Gemfile.lock
awstesting/integration/smoke/**/importmarker__.go
awstesting/integration/smoke/_test/
/vendor/bin/
/vendor/pkg/
/vendor/src/
/private/model/cli/gen-api/gen-api

14
vendor/github.com/aws/aws-sdk-go/.godoc_config generated vendored Normal file
View File

@@ -0,0 +1,14 @@
{
"PkgHandler": {
"Pattern": "/sdk-for-go/api/",
"StripPrefix": "/sdk-for-go/api",
"Include": ["/src/github.com/aws/aws-sdk-go/aws", "/src/github.com/aws/aws-sdk-go/service"],
"Exclude": ["/src/cmd", "/src/github.com/aws/aws-sdk-go/awstesting", "/src/github.com/aws/aws-sdk-go/awsmigrate"],
"IgnoredSuffixes": ["iface"]
},
"Github": {
"Tag": "master",
"Repo": "/aws/aws-sdk-go",
"UseGithub": true
}
}

23
vendor/github.com/aws/aws-sdk-go/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,23 @@
language: go
sudo: false
go:
- 1.4
- 1.5
- 1.6
- tip
# Use Go 1.5's vendoring experiment for 1.5 tests. 1.4 tests will use the tip of the dependencies repo.
env:
- GO15VENDOREXPERIMENT=1
install:
- make get-deps
script:
- make unit-with-race-cover
matrix:
allow_failures:
- go: tip

7
vendor/github.com/aws/aws-sdk-go/.yardopts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
--plugin go
-e doc-src/plugin/plugin.rb
-m markdown
-o doc/api
--title "AWS SDK for Go"
aws/**/*.go
service/**/*.go

6
vendor/github.com/aws/aws-sdk-go/Gemfile generated vendored Normal file
View File

@@ -0,0 +1,6 @@
source 'https://rubygems.org'
gem 'yard', git: 'git://github.com/lsegal/yard', ref: '5025564a491e1b7c6192632cba2802202ca08449'
gem 'yard-go', git: 'git://github.com/jasdel/yard-go', ref: 'e78e1ef7cdf5e0f3266845b26bb4fd64f1dd6f85'
gem 'rdiscount'

202
vendor/github.com/aws/aws-sdk-go/LICENSE.txt generated vendored Normal file
View File

@@ -0,0 +1,202 @@
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.

152
vendor/github.com/aws/aws-sdk-go/Makefile generated vendored Normal file
View File

@@ -0,0 +1,152 @@
LINTIGNOREDOT='awstesting/integration.+should not use dot imports'
LINTIGNOREDOC='service/[^/]+/(api|service|waiters)\.go:.+(comment on exported|should have comment or be unexported)'
LINTIGNORECONST='service/[^/]+/(api|service|waiters)\.go:.+(type|struct field|const|func) ([^ ]+) should be ([^ ]+)'
LINTIGNORESTUTTER='service/[^/]+/(api|service)\.go:.+(and that stutters)'
LINTIGNOREINFLECT='service/[^/]+/(api|service)\.go:.+method .+ should be '
LINTIGNOREINFLECTS3UPLOAD='service/s3/s3manager/upload\.go:.+struct field SSEKMSKeyId should be '
LINTIGNOREDEPS='vendor/.+\.go'
SDK_WITH_VENDOR_PKGS=$(shell go list ./... | grep -v "/vendor/src")
SDK_ONLY_PKGS=$(shell go list ./... | grep -v "/vendor/")
SDK_GO_1_4=$(shell go version | grep "go1.4")
SDK_GO_VERSION=$(shell go version | awk '''{print $$3}''' | tr -d '''\n''')
all: get-deps generate unit
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " api_info to print a list of services and versions"
@echo " docs to build SDK documentation"
@echo " build to go build the SDK"
@echo " unit to run unit tests"
@echo " integration to run integration tests"
@echo " performance to run performance tests"
@echo " verify to verify tests"
@echo " lint to lint the SDK"
@echo " vet to vet the SDK"
@echo " generate to go generate and make services"
@echo " gen-test to generate protocol tests"
@echo " gen-services to generate services"
@echo " get-deps to go get the SDK dependencies"
@echo " get-deps-tests to get the SDK's test dependencies"
@echo " get-deps-verify to get the SDK's verification dependencies"
generate: gen-test gen-endpoints gen-services
gen-test: gen-protocol-test
gen-services:
go generate ./service
gen-protocol-test:
go generate ./private/protocol/...
gen-endpoints:
go generate ./private/endpoints
build:
@echo "go build SDK and vendor packages"
@go build ${SDK_ONLY_PKGS}
unit: get-deps-tests build verify
@echo "go test SDK and vendor packages"
@go test -tags $(SDK_ONLY_PKGS)
unit-with-race-cover: get-deps-tests build verify
@echo "go test SDK and vendor packages"
@go test -tags -race -cpu=1,2,4 $(SDK_ONLY_PKGS)
integration: get-deps-tests integ-custom smoke-tests performance
integ-custom:
go test -tags "integration" ./awstesting/integration/customizations/...
smoke-tests: get-deps-tests
gucumber -go-tags "integration" ./awstesting/integration/smoke
performance: get-deps-tests
AWS_TESTING_LOG_RESULTS=${log-detailed} AWS_TESTING_REGION=$(region) AWS_TESTING_DB_TABLE=$(table) gucumber -go-tags "integration" ./awstesting/performance
sandbox-tests: sandbox-test-go14 sandbox-test-go15 sandbox-test-go15-novendorexp sandbox-test-go16 sandbox-test-go17 sandbox-test-gotip
sandbox-test-go14:
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.4 -t "aws-sdk-go-1.4" .
docker run -t aws-sdk-go-1.4
sandbox-test-go15:
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.5 -t "aws-sdk-go-1.5" .
docker run -t aws-sdk-go-1.5
sandbox-test-go15-novendorexp:
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.5-novendorexp -t "aws-sdk-go-1.5-novendorexp" .
docker run -t aws-sdk-go-1.5-novendorexp
sandbox-test-go16:
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.6 -t "aws-sdk-go-1.6" .
docker run -t aws-sdk-go-1.6
sandbox-test-go17:
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.7 -t "aws-sdk-go-1.7" .
docker run -t aws-sdk-go-1.7
sandbox-test-gotip:
@echo "Run make update-aws-golang-tip, if this test fails because missing aws-golang:tip container"
docker build -f ./awstesting/sandbox/Dockerfile.test.gotip -t "aws-sdk-go-tip" .
docker run -t aws-sdk-go-tip
update-aws-golang-tip:
docker build -f ./awstesting/sandbox/Dockerfile.golang-tip -t "aws-golang:tip" .
verify: get-deps-verify lint vet
lint:
@echo "go lint SDK and vendor packages"
@lint=`if [ -z "${SDK_GO_1_4}" ]; then golint ./...; else echo "skipping golint"; fi`; \
lint=`echo "$$lint" | grep -E -v -e ${LINTIGNOREDOT} -e ${LINTIGNOREDOC} -e ${LINTIGNORECONST} -e ${LINTIGNORESTUTTER} -e ${LINTIGNOREINFLECT} -e ${LINTIGNOREDEPS} -e ${LINTIGNOREINFLECTS3UPLOAD}`; \
echo "$$lint"; \
if [ "$$lint" != "" ] && [ "$$lint" != "skipping golint" ]; then exit 1; fi
SDK_BASE_FOLDERS=$(shell ls -d */ | grep -v vendor | grep -v awsmigrate)
ifneq (,$(findstring go1.5, ${SDK_GO_VERSION}))
GO_VET_CMD=go tool vet --all -shadow
else ifneq (,$(findstring go1.6, ${SDK_GO_VERSION}))
GO_VET_CMD=go tool vet --all -shadow -example=false
else ifneq (,$(findstring devel, ${SDK_GO_VERSION}))
GO_VET_CMD=go tool vet --all -shadow -tests=false
else
GO_VET_CMD=echo skipping go vet, ${SDK_GO_VERSION}
endif
vet:
${GO_VET_CMD} ${SDK_BASE_FOLDERS}
get-deps: get-deps-tests get-deps-verify
@echo "go get SDK dependencies"
@go get -v $(SDK_ONLY_PKGS)
get-deps-tests:
@echo "go get SDK testing dependencies"
go get github.com/lsegal/gucumber/cmd/gucumber
go get github.com/stretchr/testify
go get github.com/smartystreets/goconvey
get-deps-verify:
@echo "go get SDK verification utilities"
@if [ -z "${SDK_GO_1_4}" ]; then go get github.com/golang/lint/golint; else echo "skipped getting golint"; fi
bench:
@echo "go bench SDK packages"
@go test -run NONE -bench . -benchmem -tags 'bench' $(SDK_ONLY_PKGS)
bench-protocol:
@echo "go bench SDK protocol marshallers"
@go test -run NONE -bench . -benchmem -tags 'bench' ./private/protocol/...
docs:
@echo "generate SDK docs"
rm -rf doc && bundle install && bundle exec yard
@# This env variable, DOCS, is for internal use
@if [ -n "$(AWS_DOC_GEN_TOOL)" ]; then echo "For internal use. Subject to change."; $(AWS_DOC_GEN_TOOL) `pwd`; fi
api_info:
@go run private/model/cli/api-info/api-info.go

3
vendor/github.com/aws/aws-sdk-go/NOTICE.txt generated vendored Normal file
View File

@@ -0,0 +1,3 @@
AWS SDK for Go
Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Copyright 2014-2015 Stripe, Inc.

116
vendor/github.com/aws/aws-sdk-go/README.md generated vendored Normal file
View File

@@ -0,0 +1,116 @@
# AWS SDK for Go
<span style="display: inline-block;">
[![API Reference](http://img.shields.io/badge/api-reference-blue.svg)](http://docs.aws.amazon.com/sdk-for-go/api)
[![Join the chat at https://gitter.im/aws/aws-sdk-go](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/aws/aws-sdk-go?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://img.shields.io/travis/aws/aws-sdk-go.svg)](https://travis-ci.org/aws/aws-sdk-go)
[![Apache V2 License](http://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt)
</span>
aws-sdk-go is the official AWS SDK for the Go programming language.
Checkout our [release notes](https://github.com/aws/aws-sdk-go/releases) for information about the latest bug fixes, updates, and features added to the SDK.
## Installing
If you are using Go 1.5 with the `GO15VENDOREXPERIMENT=1` vendoring flag, or 1.6 and higher you can use the following command to retrieve the SDK. The SDK's non-testing dependencies will be included and are vendored in the `vendor` folder.
go get -u github.com/aws/aws-sdk-go
Otherwise if your Go environment does not have vendoring support enabled, or you do not want to include the vendored SDK's dependencies you can use the following command to retrieve the SDK and its non-testing dependencies using `go get`.
go get -u github.com/aws/aws-sdk-go/aws/...
go get -u github.com/aws/aws-sdk-go/service/...
If you're looking to retrieve just the SDK without any dependencies use the following command.
go get -d github.com/aws/aws-sdk-go/
These two processes will still include the `vendor` folder and it should be deleted if its not going to be used by your environment.
rm -rf $GOPATH/src/github.com/aws/aws-sdk-go/vendor
## Reference Documentation
[`Getting Started Guide`](https://aws.amazon.com/sdk-for-go/) - This document is a general introduction how to configure and make requests with the SDK. If this is your first time using the SDK, this documentation and the API documentation will help you get started. This document focuses on the syntax and behavior of the SDK. The [Service Developer Guide](https://aws.amazon.com/documentation/) will help you get started using specific AWS services.
[`SDK API Reference Documentation`](https://docs.aws.amazon.com/sdk-for-go/api/) - Use this document to look up all API operation input and output parameters for AWS services supported by the SDK. The API reference also includes documentation of the SDK, and examples how to using the SDK, service client API operations, and API operation require parameters.
[`Service Developer Guide`](https://aws.amazon.com/documentation/) - Use this documentation to learn how to interface with an AWS service. These are great guides both, if you're getting started with a service, or looking for more information on a service. You should not need this document for coding, though in some cases, services may supply helpful samples that you might want to look out for.
[`SDK Examples`](https://github.com/aws/aws-sdk-go/tree/master/example) - Included in the SDK's repo are a several hand crafted examples using the SDK features and AWS services.
## Configuring Credentials
Before using the SDK, ensure that you've configured credentials. The best
way to configure credentials on a development machine is to use the
`~/.aws/credentials` file, which might look like:
```
[default]
aws_access_key_id = AKID1234567890
aws_secret_access_key = MY-SECRET-KEY
```
You can learn more about the credentials file from this
[blog post](http://blogs.aws.amazon.com/security/post/Tx3D6U6WSFGOK2H/A-New-and-Standardized-Way-to-Manage-Credentials-in-the-AWS-SDKs).
Alternatively, you can set the following environment variables:
```
AWS_ACCESS_KEY_ID=AKID1234567890
AWS_SECRET_ACCESS_KEY=MY-SECRET-KEY
```
### AWS CLI config file (`~/.aws/config`)
The AWS SDK for Go does not support the AWS CLI's config file. The SDK will not use any contents from this file. The SDK only supports the shared credentials file (`~/.aws/credentials`). #384 tracks this feature request discussion.
## Using the Go SDK
To use a service in the SDK, create a service variable by calling the `New()`
function. Once you have a service client, you can call API operations which each
return response data and a possible error.
To list a set of instance IDs from EC2, you could run:
```go
package main
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/ec2"
)
func main() {
// Create an EC2 service object in the "us-west-2" region
// Note that you can also configure your region globally by
// exporting the AWS_REGION environment variable
svc := ec2.New(session.New(), &aws.Config{Region: aws.String("us-west-2")})
// Call the DescribeInstances Operation
resp, err := svc.DescribeInstances(nil)
if err != nil {
panic(err)
}
// resp has all of the response data, pull out instance IDs:
fmt.Println("> Number of reservation sets: ", len(resp.Reservations))
for idx, res := range resp.Reservations {
fmt.Println(" > Number of instances: ", len(res.Instances))
for _, inst := range resp.Reservations[idx].Instances {
fmt.Println(" - Instance ID: ", *inst.InstanceId)
}
}
}
```
You can find more information and operations in our
[API documentation](http://docs.aws.amazon.com/sdk-for-go/api/).
## License
This SDK is distributed under the
[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0),
see LICENSE.txt and NOTICE.txt for more information.

145
vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go generated vendored Normal file
View File

@@ -0,0 +1,145 @@
// 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 occured 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 occured 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 new request error wrapper for the given Error
// provided.
func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure {
return newRequestError(err, statusCode, reqID)
}

194
vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go generated vendored Normal file
View File

@@ -0,0 +1,194 @@
package awserr
import "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 occured", 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
}
// 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()}
}
// 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 += fmt.Sprintf("%s", 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
}

100
vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go generated vendored Normal file
View File

@@ -0,0 +1,100 @@
package awsutil
import (
"io"
"reflect"
)
// 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() {
dst.Set(reflect.New(e))
}
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)
}
}
}

View File

@@ -0,0 +1,233 @@
package awsutil_test
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"testing"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/stretchr/testify/assert"
)
func ExampleCopy() {
type Foo struct {
A int
B []*string
}
// Create the initial value
str1 := "hello"
str2 := "bye bye"
f1 := &Foo{A: 1, B: []*string{&str1, &str2}}
// Do the copy
var f2 Foo
awsutil.Copy(&f2, f1)
// Print the result
fmt.Println(awsutil.Prettify(f2))
// Output:
// {
// A: 1,
// B: ["hello","bye bye"]
// }
}
func TestCopy(t *testing.T) {
type Foo struct {
A int
B []*string
C map[string]*int
}
// Create the initial value
str1 := "hello"
str2 := "bye bye"
int1 := 1
int2 := 2
f1 := &Foo{
A: 1,
B: []*string{&str1, &str2},
C: map[string]*int{
"A": &int1,
"B": &int2,
},
}
// Do the copy
var f2 Foo
awsutil.Copy(&f2, f1)
// Values are equal
assert.Equal(t, f2.A, f1.A)
assert.Equal(t, f2.B, f1.B)
assert.Equal(t, f2.C, f1.C)
// But pointers are not!
str3 := "nothello"
int3 := 57
f2.A = 100
f2.B[0] = &str3
f2.C["B"] = &int3
assert.NotEqual(t, f2.A, f1.A)
assert.NotEqual(t, f2.B, f1.B)
assert.NotEqual(t, f2.C, f1.C)
}
func TestCopyNestedWithUnexported(t *testing.T) {
type Bar struct {
a int
B int
}
type Foo struct {
A string
B Bar
}
f1 := &Foo{A: "string", B: Bar{a: 1, B: 2}}
var f2 Foo
awsutil.Copy(&f2, f1)
// Values match
assert.Equal(t, f2.A, f1.A)
assert.NotEqual(t, f2.B, f1.B)
assert.NotEqual(t, f2.B.a, f1.B.a)
assert.Equal(t, f2.B.B, f2.B.B)
}
func TestCopyIgnoreNilMembers(t *testing.T) {
type Foo struct {
A *string
B []string
C map[string]string
}
f := &Foo{}
assert.Nil(t, f.A)
assert.Nil(t, f.B)
assert.Nil(t, f.C)
var f2 Foo
awsutil.Copy(&f2, f)
assert.Nil(t, f2.A)
assert.Nil(t, f2.B)
assert.Nil(t, f2.C)
fcopy := awsutil.CopyOf(f)
f3 := fcopy.(*Foo)
assert.Nil(t, f3.A)
assert.Nil(t, f3.B)
assert.Nil(t, f3.C)
}
func TestCopyPrimitive(t *testing.T) {
str := "hello"
var s string
awsutil.Copy(&s, &str)
assert.Equal(t, "hello", s)
}
func TestCopyNil(t *testing.T) {
var s string
awsutil.Copy(&s, nil)
assert.Equal(t, "", s)
}
func TestCopyReader(t *testing.T) {
var buf io.Reader = bytes.NewReader([]byte("hello world"))
var r io.Reader
awsutil.Copy(&r, buf)
b, err := ioutil.ReadAll(r)
assert.NoError(t, err)
assert.Equal(t, []byte("hello world"), b)
// empty bytes because this is not a deep copy
b, err = ioutil.ReadAll(buf)
assert.NoError(t, err)
assert.Equal(t, []byte(""), b)
}
func TestCopyDifferentStructs(t *testing.T) {
type SrcFoo struct {
A int
B []*string
C map[string]*int
SrcUnique string
SameNameDiffType int
unexportedPtr *int
ExportedPtr *int
}
type DstFoo struct {
A int
B []*string
C map[string]*int
DstUnique int
SameNameDiffType string
unexportedPtr *int
ExportedPtr *int
}
// Create the initial value
str1 := "hello"
str2 := "bye bye"
int1 := 1
int2 := 2
f1 := &SrcFoo{
A: 1,
B: []*string{&str1, &str2},
C: map[string]*int{
"A": &int1,
"B": &int2,
},
SrcUnique: "unique",
SameNameDiffType: 1,
unexportedPtr: &int1,
ExportedPtr: &int2,
}
// Do the copy
var f2 DstFoo
awsutil.Copy(&f2, f1)
// Values are equal
assert.Equal(t, f2.A, f1.A)
assert.Equal(t, f2.B, f1.B)
assert.Equal(t, f2.C, f1.C)
assert.Equal(t, "unique", f1.SrcUnique)
assert.Equal(t, 1, f1.SameNameDiffType)
assert.Equal(t, 0, f2.DstUnique)
assert.Equal(t, "", f2.SameNameDiffType)
assert.Equal(t, int1, *f1.unexportedPtr)
assert.Nil(t, f2.unexportedPtr)
assert.Equal(t, int2, *f1.ExportedPtr)
assert.Equal(t, int2, *f2.ExportedPtr)
}
func ExampleCopyOf() {
type Foo struct {
A int
B []*string
}
// Create the initial value
str1 := "hello"
str2 := "bye bye"
f1 := &Foo{A: 1, B: []*string{&str1, &str2}}
// Do the copy
v := awsutil.CopyOf(f1)
var f2 *Foo = v.(*Foo)
// Print the result
fmt.Println(awsutil.Prettify(f2))
// Output:
// {
// A: 1,
// B: ["hello","bye bye"]
// }
}

27
vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go generated vendored Normal file
View File

@@ -0,0 +1,27 @@
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 the 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())
}

View File

@@ -0,0 +1,29 @@
package awsutil_test
import (
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/stretchr/testify/assert"
)
func TestDeepEqual(t *testing.T) {
cases := []struct {
a, b interface{}
equal bool
}{
{"a", "a", true},
{"a", "b", false},
{"a", aws.String(""), false},
{"a", nil, false},
{"a", aws.String("a"), true},
{(*bool)(nil), (*bool)(nil), true},
{(*bool)(nil), (*string)(nil), false},
{nil, nil, true},
}
for i, c := range cases {
assert.Equal(t, c.equal, awsutil.DeepEqual(c.a, c.b), "%d, a:%v b:%v, %t", i, c.a, c.b, c.equal)
}
}

View File

@@ -0,0 +1,222 @@
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.ToLower(name) == strings.ToLower(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 _, value := range values {
value := reflect.Indirect(value)
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{}) {
if rvals := rValuesAtPath(i, path, true, false, v == nil); rvals != 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)
}
}

View File

@@ -0,0 +1,142 @@
package awsutil_test
import (
"testing"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/stretchr/testify/assert"
)
type Struct struct {
A []Struct
z []Struct
B *Struct
D *Struct
C string
E map[string]string
}
var data = Struct{
A: []Struct{{C: "value1"}, {C: "value2"}, {C: "value3"}},
z: []Struct{{C: "value1"}, {C: "value2"}, {C: "value3"}},
B: &Struct{B: &Struct{C: "terminal"}, D: &Struct{C: "terminal2"}},
C: "initial",
}
var data2 = Struct{A: []Struct{
{A: []Struct{{C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}}},
{A: []Struct{{C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}}},
}}
func TestValueAtPathSuccess(t *testing.T) {
var testCases = []struct {
expect []interface{}
data interface{}
path string
}{
{[]interface{}{"initial"}, data, "C"},
{[]interface{}{"value1"}, data, "A[0].C"},
{[]interface{}{"value2"}, data, "A[1].C"},
{[]interface{}{"value3"}, data, "A[2].C"},
{[]interface{}{"value3"}, data, "a[2].c"},
{[]interface{}{"value3"}, data, "A[-1].C"},
{[]interface{}{"value1", "value2", "value3"}, data, "A[].C"},
{[]interface{}{"terminal"}, data, "B . B . C"},
{[]interface{}{"initial"}, data, "A.D.X || C"},
{[]interface{}{"initial"}, data, "A[0].B || C"},
{[]interface{}{
Struct{A: []Struct{{C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}}},
Struct{A: []Struct{{C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}}},
}, data2, "A"},
}
for i, c := range testCases {
v, err := awsutil.ValuesAtPath(c.data, c.path)
assert.NoError(t, err, "case %d, expected no error, %s", i, c.path)
assert.Equal(t, c.expect, v, "case %d, %s", i, c.path)
}
}
func TestValueAtPathFailure(t *testing.T) {
var testCases = []struct {
expect []interface{}
errContains string
data interface{}
path string
}{
{nil, "", data, "C.x"},
{nil, "SyntaxError: Invalid token: tDot", data, ".x"},
{nil, "", data, "X.Y.Z"},
{nil, "", data, "A[100].C"},
{nil, "", data, "A[3].C"},
{nil, "", data, "B.B.C.Z"},
{nil, "", data, "z[-1].C"},
{nil, "", nil, "A.B.C"},
{[]interface{}{}, "", Struct{}, "A"},
{nil, "", data, "A[0].B.C"},
{nil, "", data, "D"},
}
for i, c := range testCases {
v, err := awsutil.ValuesAtPath(c.data, c.path)
if c.errContains != "" {
assert.Contains(t, err.Error(), c.errContains, "case %d, expected error, %s", i, c.path)
continue
} else {
assert.NoError(t, err, "case %d, expected no error, %s", i, c.path)
}
assert.Equal(t, c.expect, v, "case %d, %s", i, c.path)
}
}
func TestSetValueAtPathSuccess(t *testing.T) {
var s Struct
awsutil.SetValueAtPath(&s, "C", "test1")
awsutil.SetValueAtPath(&s, "B.B.C", "test2")
awsutil.SetValueAtPath(&s, "B.D.C", "test3")
assert.Equal(t, "test1", s.C)
assert.Equal(t, "test2", s.B.B.C)
assert.Equal(t, "test3", s.B.D.C)
awsutil.SetValueAtPath(&s, "B.*.C", "test0")
assert.Equal(t, "test0", s.B.B.C)
assert.Equal(t, "test0", s.B.D.C)
var s2 Struct
awsutil.SetValueAtPath(&s2, "b.b.c", "test0")
assert.Equal(t, "test0", s2.B.B.C)
awsutil.SetValueAtPath(&s2, "A", []Struct{{}})
assert.Equal(t, []Struct{{}}, s2.A)
str := "foo"
s3 := Struct{}
awsutil.SetValueAtPath(&s3, "b.b.c", str)
assert.Equal(t, "foo", s3.B.B.C)
s3 = Struct{B: &Struct{B: &Struct{C: str}}}
awsutil.SetValueAtPath(&s3, "b.b.c", nil)
assert.Equal(t, "", s3.B.B.C)
s3 = Struct{}
awsutil.SetValueAtPath(&s3, "b.b.c", nil)
assert.Equal(t, "", s3.B.B.C)
s3 = Struct{}
awsutil.SetValueAtPath(&s3, "b.b.c", &str)
assert.Equal(t, "foo", s3.B.B.C)
var s4 struct{ Name *string }
awsutil.SetValueAtPath(&s4, "Name", str)
assert.Equal(t, str, *s4.Name)
s4 = struct{ Name *string }{}
awsutil.SetValueAtPath(&s4, "Name", nil)
assert.Equal(t, (*string)(nil), s4.Name)
s4 = struct{ Name *string }{Name: &str}
awsutil.SetValueAtPath(&s4, "Name", nil)
assert.Equal(t, (*string)(nil), s4.Name)
s4 = struct{ Name *string }{}
awsutil.SetValueAtPath(&s4, "Name", &str)
assert.Equal(t, str, *s4.Name)
}

View File

@@ -0,0 +1,107 @@
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)
buf.WriteString(strings.Repeat(" ", indent+2))
buf.WriteString(n + ": ")
prettify(val, indent+2, buf)
if i < len(names)-1 {
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)
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())
}
}

View File

@@ -0,0 +1,89 @@
package awsutil
import (
"bytes"
"fmt"
"reflect"
"strings"
)
// StringValue returns the string representation of a value.
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")
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.IsNil() {
continue // ignore unset fields
}
names = append(names, name)
}
for i, n := range names {
val := v.FieldByName(n)
buf.WriteString(strings.Repeat(" ", indent+2))
buf.WriteString(n + ": ")
stringValue(val, indent+2, buf)
if i < len(names)-1 {
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())
}
}

120
vendor/github.com/aws/aws-sdk-go/aws/client/client.go generated vendored Normal file
View File

@@ -0,0 +1,120 @@
package client
import (
"fmt"
"io/ioutil"
"net/http/httputil"
"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
Endpoint, SigningRegion string
}
// 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
}
// 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,
}
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 = 3
}
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() {
if !c.Config.LogLevel.AtLeast(aws.LogDebug) {
return
}
c.Handlers.Send.PushFront(logRequest)
c.Handlers.Send.PushBack(logResponse)
}
const logReqMsg = `DEBUG: Request %s/%s Details:
---[ REQUEST POST-SIGN ]-----------------------------
%s
-----------------------------------------------------`
func logRequest(r *request.Request) {
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
dumpedBody, _ := httputil.DumpRequestOut(r.HTTPRequest, logBody)
if logBody {
// 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.
r.Body.Seek(r.BodyStart, 0)
r.HTTPRequest.Body = ioutil.NopCloser(r.Body)
}
r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody)))
}
const logRespMsg = `DEBUG: Response %s/%s Details:
---[ RESPONSE ]--------------------------------------
%s
-----------------------------------------------------`
func logResponse(r *request.Request) {
var msg = "no response data"
if r.HTTPResponse != nil {
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody)
msg = string(dumpedBody)
} else if r.Error != nil {
msg = r.Error.Error()
}
r.Config.Logger.Log(fmt.Sprintf(logRespMsg, r.ClientInfo.ServiceName, r.Operation.Name, msg))
}

View File

@@ -0,0 +1,90 @@
package client
import (
"math/rand"
"sync"
"time"
"github.com/aws/aws-sdk-go/aws/request"
)
// DefaultRetryer implements basic retry logic using exponential backoff for
// most services. If you want to implement custom retry logic, implement the
// request.Retryer interface or create a structure type that composes this
// struct and override the specific methods. For example, to override only
// the MaxRetries method:
//
// type retryer struct {
// service.DefaultRetryer
// }
//
// // This implementation always has 100 max retries
// func (d retryer) MaxRetries() uint { return 100 }
type DefaultRetryer struct {
NumMaxRetries int
}
// 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
}
var seededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())})
// RetryRules returns the delay duration before retrying this request again
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
// Set the upper limit of delay in retrying at ~five minutes
minTime := 30
throttle := d.shouldThrottle(r)
if throttle {
minTime = 500
}
retryCount := r.RetryCount
if retryCount > 13 {
retryCount = 13
} else if throttle && retryCount > 8 {
retryCount = 8
}
delay := (1 << uint(retryCount)) * (seededRand.Intn(minTime) + minTime)
return time.Duration(delay) * time.Millisecond
}
// ShouldRetry returns true if the request should be retried.
func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
if r.HTTPResponse.StatusCode >= 500 {
return true
}
return r.IsErrorRetryable() || d.shouldThrottle(r)
}
// ShouldThrottle returns true if the request should be throttled.
func (d DefaultRetryer) shouldThrottle(r *request.Request) bool {
if r.HTTPResponse.StatusCode == 502 ||
r.HTTPResponse.StatusCode == 503 ||
r.HTTPResponse.StatusCode == 504 {
return true
}
return r.IsErrorThrottle()
}
// lockedSource is a thread-safe implementation of rand.Source
type lockedSource struct {
lk sync.Mutex
src rand.Source
}
func (r *lockedSource) Int63() (n int64) {
r.lk.Lock()
n = r.src.Int63()
r.lk.Unlock()
return
}
func (r *lockedSource) Seed(seed int64) {
r.lk.Lock()
r.src.Seed(seed)
r.lk.Unlock()
}

View File

@@ -0,0 +1,12 @@
package metadata
// ClientInfo wraps immutable data from the client.Client structure.
type ClientInfo struct {
ServiceName string
APIVersion string
Endpoint string
SigningName string
SigningRegion string
JSONVersion string
TargetPrefix string
}

363
vendor/github.com/aws/aws-sdk-go/aws/config.go generated vendored Normal file
View File

@@ -0,0 +1,363 @@
package aws
import (
"net/http"
"time"
"github.com/aws/aws-sdk-go/aws/credentials"
)
// 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.
type Config struct {
// Enables verbose error printing of all credential chain errors.
// Should be used when wanting to see all errors while attempting to retreive
// 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 `""` to use the default generated endpoint.
//
// @note You must still provide a `Region` value when specifying an
// endpoint for a client.
Endpoint *string
// 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
// 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 request.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
// 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 disble 100-Continue if you experiance issues
// with proxies or thrid 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
// 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.New() in order to disable the EC2Metadata
// overriding the timeout for default credentials chain.
//
// Example:
// sess := session.New(aws.NewConfig().WithEC2MetadataDiableTimeoutOverride(true))
// svc := s3.New(sess)
//
EC2MetadataDisableTimeoutOverride *bool
// 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 func(time.Duration)
}
// NewConfig returns a new Config pointer that can be chained with builder methods to
// set multiple configuration values inline without using pointers.
//
// sess := session.New(aws.NewConfig().WithRegion("us-west-2").WithMaxRetries(10))
//
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
}
// WithRegion sets a config Region value returning a Config pointer for
// chaining.
func (c *Config) WithRegion(region string) *Config {
c.Region = &region
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
}
// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value
// returning a Config pointer for chaining.
func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config {
c.EC2MetadataDisableTimeoutOverride = &enable
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
}
// 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.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.EC2MetadataDisableTimeoutOverride != nil {
dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride
}
if other.SleepDelay != nil {
dst.SleepDelay = other.SleepDelay
}
}
// 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
}

86
vendor/github.com/aws/aws-sdk-go/aws/config_test.go generated vendored Normal file
View File

@@ -0,0 +1,86 @@
package aws
import (
"net/http"
"reflect"
"testing"
"github.com/aws/aws-sdk-go/aws/credentials"
)
var testCredentials = credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
var copyTestConfig = Config{
Credentials: testCredentials,
Endpoint: String("CopyTestEndpoint"),
Region: String("COPY_TEST_AWS_REGION"),
DisableSSL: Bool(true),
HTTPClient: http.DefaultClient,
LogLevel: LogLevel(LogDebug),
Logger: NewDefaultLogger(),
MaxRetries: Int(3),
DisableParamValidation: Bool(true),
DisableComputeChecksums: Bool(true),
S3ForcePathStyle: Bool(true),
}
func TestCopy(t *testing.T) {
want := copyTestConfig
got := copyTestConfig.Copy()
if !reflect.DeepEqual(*got, want) {
t.Errorf("Copy() = %+v", got)
t.Errorf(" want %+v", want)
}
got.Region = String("other")
if got.Region == want.Region {
t.Errorf("Expect setting copy values not not reflect in source")
}
}
func TestCopyReturnsNewInstance(t *testing.T) {
want := copyTestConfig
got := copyTestConfig.Copy()
if got == &want {
t.Errorf("Copy() = %p; want different instance as source %p", got, &want)
}
}
var mergeTestZeroValueConfig = Config{}
var mergeTestConfig = Config{
Credentials: testCredentials,
Endpoint: String("MergeTestEndpoint"),
Region: String("MERGE_TEST_AWS_REGION"),
DisableSSL: Bool(true),
HTTPClient: http.DefaultClient,
LogLevel: LogLevel(LogDebug),
Logger: NewDefaultLogger(),
MaxRetries: Int(10),
DisableParamValidation: Bool(true),
DisableComputeChecksums: Bool(true),
S3ForcePathStyle: Bool(true),
}
var mergeTests = []struct {
cfg *Config
in *Config
want *Config
}{
{&Config{}, nil, &Config{}},
{&Config{}, &mergeTestZeroValueConfig, &Config{}},
{&Config{}, &mergeTestConfig, &mergeTestConfig},
}
func TestMerge(t *testing.T) {
for i, tt := range mergeTests {
got := tt.cfg.Copy()
got.MergeIn(tt.in)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Config %d %+v", i, tt.cfg)
t.Errorf(" Merge(%+v)", tt.in)
t.Errorf(" got %+v", got)
t.Errorf(" want %+v", tt.want)
}
}
}

369
vendor/github.com/aws/aws-sdk-go/aws/convert_types.go generated vendored Normal file
View File

@@ -0,0 +1,369 @@
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
}
// 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
}
// 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{}
}
// 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
}

View File

@@ -0,0 +1,437 @@
package aws
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
var testCasesStringSlice = [][]string{
{"a", "b", "c", "d", "e"},
{"a", "b", "", "", "e"},
}
func TestStringSlice(t *testing.T) {
for idx, in := range testCasesStringSlice {
if in == nil {
continue
}
out := StringSlice(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
}
out2 := StringValueSlice(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
}
}
var testCasesStringValueSlice = [][]*string{
{String("a"), String("b"), nil, String("c")},
}
func TestStringValueSlice(t *testing.T) {
for idx, in := range testCasesStringValueSlice {
if in == nil {
continue
}
out := StringValueSlice(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
if in[i] == nil {
assert.Empty(t, out[i], "Unexpected value at idx %d", idx)
} else {
assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx)
}
}
out2 := StringSlice(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
for i := range out2 {
if in[i] == nil {
assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx)
} else {
assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx)
}
}
}
}
var testCasesStringMap = []map[string]string{
{"a": "1", "b": "2", "c": "3"},
}
func TestStringMap(t *testing.T) {
for idx, in := range testCasesStringMap {
if in == nil {
continue
}
out := StringMap(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
}
out2 := StringValueMap(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
}
}
var testCasesBoolSlice = [][]bool{
{true, true, false, false},
}
func TestBoolSlice(t *testing.T) {
for idx, in := range testCasesBoolSlice {
if in == nil {
continue
}
out := BoolSlice(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
}
out2 := BoolValueSlice(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
}
}
var testCasesBoolValueSlice = [][]*bool{}
func TestBoolValueSlice(t *testing.T) {
for idx, in := range testCasesBoolValueSlice {
if in == nil {
continue
}
out := BoolValueSlice(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
if in[i] == nil {
assert.Empty(t, out[i], "Unexpected value at idx %d", idx)
} else {
assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx)
}
}
out2 := BoolSlice(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
for i := range out2 {
if in[i] == nil {
assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx)
} else {
assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx)
}
}
}
}
var testCasesBoolMap = []map[string]bool{
{"a": true, "b": false, "c": true},
}
func TestBoolMap(t *testing.T) {
for idx, in := range testCasesBoolMap {
if in == nil {
continue
}
out := BoolMap(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
}
out2 := BoolValueMap(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
}
}
var testCasesIntSlice = [][]int{
{1, 2, 3, 4},
}
func TestIntSlice(t *testing.T) {
for idx, in := range testCasesIntSlice {
if in == nil {
continue
}
out := IntSlice(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
}
out2 := IntValueSlice(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
}
}
var testCasesIntValueSlice = [][]*int{}
func TestIntValueSlice(t *testing.T) {
for idx, in := range testCasesIntValueSlice {
if in == nil {
continue
}
out := IntValueSlice(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
if in[i] == nil {
assert.Empty(t, out[i], "Unexpected value at idx %d", idx)
} else {
assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx)
}
}
out2 := IntSlice(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
for i := range out2 {
if in[i] == nil {
assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx)
} else {
assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx)
}
}
}
}
var testCasesIntMap = []map[string]int{
{"a": 3, "b": 2, "c": 1},
}
func TestIntMap(t *testing.T) {
for idx, in := range testCasesIntMap {
if in == nil {
continue
}
out := IntMap(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
}
out2 := IntValueMap(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
}
}
var testCasesInt64Slice = [][]int64{
{1, 2, 3, 4},
}
func TestInt64Slice(t *testing.T) {
for idx, in := range testCasesInt64Slice {
if in == nil {
continue
}
out := Int64Slice(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
}
out2 := Int64ValueSlice(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
}
}
var testCasesInt64ValueSlice = [][]*int64{}
func TestInt64ValueSlice(t *testing.T) {
for idx, in := range testCasesInt64ValueSlice {
if in == nil {
continue
}
out := Int64ValueSlice(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
if in[i] == nil {
assert.Empty(t, out[i], "Unexpected value at idx %d", idx)
} else {
assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx)
}
}
out2 := Int64Slice(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
for i := range out2 {
if in[i] == nil {
assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx)
} else {
assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx)
}
}
}
}
var testCasesInt64Map = []map[string]int64{
{"a": 3, "b": 2, "c": 1},
}
func TestInt64Map(t *testing.T) {
for idx, in := range testCasesInt64Map {
if in == nil {
continue
}
out := Int64Map(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
}
out2 := Int64ValueMap(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
}
}
var testCasesFloat64Slice = [][]float64{
{1, 2, 3, 4},
}
func TestFloat64Slice(t *testing.T) {
for idx, in := range testCasesFloat64Slice {
if in == nil {
continue
}
out := Float64Slice(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
}
out2 := Float64ValueSlice(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
}
}
var testCasesFloat64ValueSlice = [][]*float64{}
func TestFloat64ValueSlice(t *testing.T) {
for idx, in := range testCasesFloat64ValueSlice {
if in == nil {
continue
}
out := Float64ValueSlice(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
if in[i] == nil {
assert.Empty(t, out[i], "Unexpected value at idx %d", idx)
} else {
assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx)
}
}
out2 := Float64Slice(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
for i := range out2 {
if in[i] == nil {
assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx)
} else {
assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx)
}
}
}
}
var testCasesFloat64Map = []map[string]float64{
{"a": 3, "b": 2, "c": 1},
}
func TestFloat64Map(t *testing.T) {
for idx, in := range testCasesFloat64Map {
if in == nil {
continue
}
out := Float64Map(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
}
out2 := Float64ValueMap(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
}
}
var testCasesTimeSlice = [][]time.Time{
{time.Now(), time.Now().AddDate(100, 0, 0)},
}
func TestTimeSlice(t *testing.T) {
for idx, in := range testCasesTimeSlice {
if in == nil {
continue
}
out := TimeSlice(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
}
out2 := TimeValueSlice(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
}
}
var testCasesTimeValueSlice = [][]*time.Time{}
func TestTimeValueSlice(t *testing.T) {
for idx, in := range testCasesTimeValueSlice {
if in == nil {
continue
}
out := TimeValueSlice(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
if in[i] == nil {
assert.Empty(t, out[i], "Unexpected value at idx %d", idx)
} else {
assert.Equal(t, *(in[i]), out[i], "Unexpected value at idx %d", idx)
}
}
out2 := TimeSlice(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
for i := range out2 {
if in[i] == nil {
assert.Empty(t, *(out2[i]), "Unexpected value at idx %d", idx)
} else {
assert.Equal(t, in[i], out2[i], "Unexpected value at idx %d", idx)
}
}
}
}
var testCasesTimeMap = []map[string]time.Time{
{"a": time.Now().AddDate(-100, 0, 0), "b": time.Now()},
}
func TestTimeMap(t *testing.T) {
for idx, in := range testCasesTimeMap {
if in == nil {
continue
}
out := TimeMap(in)
assert.Len(t, out, len(in), "Unexpected len at idx %d", idx)
for i := range out {
assert.Equal(t, in[i], *(out[i]), "Unexpected value at idx %d", idx)
}
out2 := TimeValueMap(out)
assert.Len(t, out2, len(in), "Unexpected len at idx %d", idx)
assert.Equal(t, in, out2, "Unexpected value at idx %d", idx)
}
}

View File

@@ -0,0 +1,152 @@
package corehandlers
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"regexp"
"runtime"
"strconv"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"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 aded 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 {
switch body := r.Body.(type) {
case nil:
length = 0
case lener:
length = int64(body.Len())
case io.Seeker:
r.BodyStart, _ = body.Seek(0, 1)
end, _ := body.Seek(0, 2)
body.Seek(r.BodyStart, 0) // make sure to seek back to original location
length = end - r.BodyStart
default:
panic("Cannot get length of body, must provide `ContentLength`")
}
}
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")
}
}}
// 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),
}
var reStatusCode = regexp.MustCompile(`^(\d{3})`)
// SendHandler is a request handler to send service request using HTTP client.
var SendHandler = request.NamedHandler{Name: "core.SendHandler", Fn: func(r *request.Request) {
var err error
r.HTTPResponse, err = r.Config.HTTPClient.Do(r.HTTPRequest)
if err != nil {
// 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 other request errors.
r.Error = awserr.New("RequestError", "send request failed", err)
r.Retryable = aws.Bool(true) // network errors are retryable
}
}}
// 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", nil)
}
}}
// 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 {
r.Retryable = aws.Bool(r.ShouldRetry(r))
}
if r.WillRetry() {
r.RetryDelay = r.RetryRules(r)
r.Config.SleepDelay(r.RetryDelay)
// 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 == "" {
r.Error = aws.ErrMissingEndpoint
}
}}

View File

@@ -0,0 +1,192 @@
package corehandlers_test
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"testing"
"github.com/stretchr/testify/assert"
"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/request"
"github.com/aws/aws-sdk-go/awstesting"
"github.com/aws/aws-sdk-go/awstesting/unit"
"github.com/aws/aws-sdk-go/service/s3"
)
func TestValidateEndpointHandler(t *testing.T) {
os.Clearenv()
svc := awstesting.NewClient(aws.NewConfig().WithRegion("us-west-2"))
svc.Handlers.Clear()
svc.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
err := req.Build()
assert.NoError(t, err)
}
func TestValidateEndpointHandlerErrorRegion(t *testing.T) {
os.Clearenv()
svc := awstesting.NewClient()
svc.Handlers.Clear()
svc.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
err := req.Build()
assert.Error(t, err)
assert.Equal(t, aws.ErrMissingRegion, err)
}
type mockCredsProvider struct {
expired bool
retrieveCalled bool
}
func (m *mockCredsProvider) Retrieve() (credentials.Value, error) {
m.retrieveCalled = true
return credentials.Value{ProviderName: "mockCredsProvider"}, nil
}
func (m *mockCredsProvider) IsExpired() bool {
return m.expired
}
func TestAfterRetryRefreshCreds(t *testing.T) {
os.Clearenv()
credProvider := &mockCredsProvider{}
svc := awstesting.NewClient(&aws.Config{
Credentials: credentials.NewCredentials(credProvider),
MaxRetries: aws.Int(1),
})
svc.Handlers.Clear()
svc.Handlers.ValidateResponse.PushBack(func(r *request.Request) {
r.Error = awserr.New("UnknownError", "", nil)
r.HTTPResponse = &http.Response{StatusCode: 400, Body: ioutil.NopCloser(bytes.NewBuffer([]byte{}))}
})
svc.Handlers.UnmarshalError.PushBack(func(r *request.Request) {
r.Error = awserr.New("ExpiredTokenException", "", nil)
})
svc.Handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
assert.True(t, svc.Config.Credentials.IsExpired(), "Expect to start out expired")
assert.False(t, credProvider.retrieveCalled)
req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
req.Send()
assert.True(t, svc.Config.Credentials.IsExpired())
assert.False(t, credProvider.retrieveCalled)
_, err := svc.Config.Credentials.Get()
assert.NoError(t, err)
assert.True(t, credProvider.retrieveCalled)
}
type testSendHandlerTransport struct{}
func (t *testSendHandlerTransport) RoundTrip(r *http.Request) (*http.Response, error) {
return nil, fmt.Errorf("mock error")
}
func TestSendHandlerError(t *testing.T) {
svc := awstesting.NewClient(&aws.Config{
HTTPClient: &http.Client{
Transport: &testSendHandlerTransport{},
},
})
svc.Handlers.Clear()
svc.Handlers.Send.PushBackNamed(corehandlers.SendHandler)
r := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
r.Send()
assert.Error(t, r.Error)
assert.NotNil(t, r.HTTPResponse)
}
func setupContentLengthTestServer(t *testing.T, hasContentLength bool, contentLength int64) *httptest.Server {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, ok := r.Header["Content-Length"]
assert.Equal(t, hasContentLength, ok, "expect content length to be set, %t", hasContentLength)
assert.Equal(t, contentLength, r.ContentLength)
b, err := ioutil.ReadAll(r.Body)
assert.NoError(t, err)
r.Body.Close()
authHeader := r.Header.Get("Authorization")
if hasContentLength {
assert.Contains(t, authHeader, "content-length")
} else {
assert.NotContains(t, authHeader, "content-length")
}
assert.Equal(t, contentLength, int64(len(b)))
}))
return server
}
func TestBuildContentLength_ZeroBody(t *testing.T) {
server := setupContentLengthTestServer(t, false, 0)
svc := s3.New(unit.Session, &aws.Config{
Endpoint: aws.String(server.URL),
S3ForcePathStyle: aws.Bool(true),
DisableSSL: aws.Bool(true),
})
_, err := svc.GetObject(&s3.GetObjectInput{
Bucket: aws.String("bucketname"),
Key: aws.String("keyname"),
})
assert.NoError(t, err)
}
func TestBuildContentLength_NegativeBody(t *testing.T) {
server := setupContentLengthTestServer(t, false, 0)
svc := s3.New(unit.Session, &aws.Config{
Endpoint: aws.String(server.URL),
S3ForcePathStyle: aws.Bool(true),
DisableSSL: aws.Bool(true),
})
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
Bucket: aws.String("bucketname"),
Key: aws.String("keyname"),
})
req.HTTPRequest.Header.Set("Content-Length", "-1")
assert.NoError(t, req.Send())
}
func TestBuildContentLength_WithBody(t *testing.T) {
server := setupContentLengthTestServer(t, true, 1024)
svc := s3.New(unit.Session, &aws.Config{
Endpoint: aws.String(server.URL),
S3ForcePathStyle: aws.Bool(true),
DisableSSL: aws.Bool(true),
})
_, err := svc.PutObject(&s3.PutObjectInput{
Bucket: aws.String("bucketname"),
Key: aws.String("keyname"),
Body: bytes.NewReader(make([]byte, 1024)),
})
assert.NoError(t, err)
}

View File

@@ -0,0 +1,17 @@
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
}
}
}}

View File

@@ -0,0 +1,254 @@
package corehandlers_test
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"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"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/kinesis"
"github.com/stretchr/testify/require"
)
var testSvc = func() *client.Client {
s := &client.Client{
Config: aws.Config{},
ClientInfo: metadata.ClientInfo{
ServiceName: "mock-service",
APIVersion: "2015-01-01",
},
}
return s
}()
type StructShape struct {
_ struct{} `type:"structure"`
RequiredList []*ConditionalStructShape `required:"true"`
RequiredMap map[string]*ConditionalStructShape `required:"true"`
RequiredBool *bool `required:"true"`
OptionalStruct *ConditionalStructShape
hiddenParameter *string
}
func (s *StructShape) Validate() error {
invalidParams := request.ErrInvalidParams{Context: "StructShape"}
if s.RequiredList == nil {
invalidParams.Add(request.NewErrParamRequired("RequiredList"))
}
if s.RequiredMap == nil {
invalidParams.Add(request.NewErrParamRequired("RequiredMap"))
}
if s.RequiredBool == nil {
invalidParams.Add(request.NewErrParamRequired("RequiredBool"))
}
if s.RequiredList != nil {
for i, v := range s.RequiredList {
if v == nil {
continue
}
if err := v.Validate(); err != nil {
invalidParams.AddNested(fmt.Sprintf("%s[%v]", "RequiredList", i), err.(request.ErrInvalidParams))
}
}
}
if s.RequiredMap != nil {
for i, v := range s.RequiredMap {
if v == nil {
continue
}
if err := v.Validate(); err != nil {
invalidParams.AddNested(fmt.Sprintf("%s[%v]", "RequiredMap", i), err.(request.ErrInvalidParams))
}
}
}
if s.OptionalStruct != nil {
if err := s.OptionalStruct.Validate(); err != nil {
invalidParams.AddNested("OptionalStruct", err.(request.ErrInvalidParams))
}
}
if invalidParams.Len() > 0 {
return invalidParams
}
return nil
}
type ConditionalStructShape struct {
_ struct{} `type:"structure"`
Name *string `required:"true"`
}
func (s *ConditionalStructShape) Validate() error {
invalidParams := request.ErrInvalidParams{Context: "ConditionalStructShape"}
if s.Name == nil {
invalidParams.Add(request.NewErrParamRequired("Name"))
}
if invalidParams.Len() > 0 {
return invalidParams
}
return nil
}
func TestNoErrors(t *testing.T) {
input := &StructShape{
RequiredList: []*ConditionalStructShape{},
RequiredMap: map[string]*ConditionalStructShape{
"key1": {Name: aws.String("Name")},
"key2": {Name: aws.String("Name")},
},
RequiredBool: aws.Bool(true),
OptionalStruct: &ConditionalStructShape{Name: aws.String("Name")},
}
req := testSvc.NewRequest(&request.Operation{}, input, nil)
corehandlers.ValidateParametersHandler.Fn(req)
require.NoError(t, req.Error)
}
func TestMissingRequiredParameters(t *testing.T) {
input := &StructShape{}
req := testSvc.NewRequest(&request.Operation{}, input, nil)
corehandlers.ValidateParametersHandler.Fn(req)
require.Error(t, req.Error)
assert.Equal(t, "InvalidParameter", req.Error.(awserr.Error).Code())
assert.Equal(t, "3 validation error(s) found.", req.Error.(awserr.Error).Message())
errs := req.Error.(awserr.BatchedErrors).OrigErrs()
assert.Len(t, errs, 3)
assert.Equal(t, "ParamRequiredError: missing required field, StructShape.RequiredList.", errs[0].Error())
assert.Equal(t, "ParamRequiredError: missing required field, StructShape.RequiredMap.", errs[1].Error())
assert.Equal(t, "ParamRequiredError: missing required field, StructShape.RequiredBool.", errs[2].Error())
assert.Equal(t, "InvalidParameter: 3 validation error(s) found.\n- missing required field, StructShape.RequiredList.\n- missing required field, StructShape.RequiredMap.\n- missing required field, StructShape.RequiredBool.\n", req.Error.Error())
}
func TestNestedMissingRequiredParameters(t *testing.T) {
input := &StructShape{
RequiredList: []*ConditionalStructShape{{}},
RequiredMap: map[string]*ConditionalStructShape{
"key1": {Name: aws.String("Name")},
"key2": {},
},
RequiredBool: aws.Bool(true),
OptionalStruct: &ConditionalStructShape{},
}
req := testSvc.NewRequest(&request.Operation{}, input, nil)
corehandlers.ValidateParametersHandler.Fn(req)
require.Error(t, req.Error)
assert.Equal(t, "InvalidParameter", req.Error.(awserr.Error).Code())
assert.Equal(t, "3 validation error(s) found.", req.Error.(awserr.Error).Message())
errs := req.Error.(awserr.BatchedErrors).OrigErrs()
assert.Len(t, errs, 3)
assert.Equal(t, "ParamRequiredError: missing required field, StructShape.RequiredList[0].Name.", errs[0].Error())
assert.Equal(t, "ParamRequiredError: missing required field, StructShape.RequiredMap[key2].Name.", errs[1].Error())
assert.Equal(t, "ParamRequiredError: missing required field, StructShape.OptionalStruct.Name.", errs[2].Error())
}
type testInput struct {
StringField *string `min:"5"`
ListField []string `min:"3"`
MapField map[string]string `min:"4"`
}
func (s testInput) Validate() error {
invalidParams := request.ErrInvalidParams{Context: "testInput"}
if s.StringField != nil && len(*s.StringField) < 5 {
invalidParams.Add(request.NewErrParamMinLen("StringField", 5))
}
if s.ListField != nil && len(s.ListField) < 3 {
invalidParams.Add(request.NewErrParamMinLen("ListField", 3))
}
if s.MapField != nil && len(s.MapField) < 4 {
invalidParams.Add(request.NewErrParamMinLen("MapField", 4))
}
if invalidParams.Len() > 0 {
return invalidParams
}
return nil
}
var testsFieldMin = []struct {
err awserr.Error
in testInput
}{
{
err: func() awserr.Error {
invalidParams := request.ErrInvalidParams{Context: "testInput"}
invalidParams.Add(request.NewErrParamMinLen("StringField", 5))
return invalidParams
}(),
in: testInput{StringField: aws.String("abcd")},
},
{
err: func() awserr.Error {
invalidParams := request.ErrInvalidParams{Context: "testInput"}
invalidParams.Add(request.NewErrParamMinLen("StringField", 5))
invalidParams.Add(request.NewErrParamMinLen("ListField", 3))
return invalidParams
}(),
in: testInput{StringField: aws.String("abcd"), ListField: []string{"a", "b"}},
},
{
err: func() awserr.Error {
invalidParams := request.ErrInvalidParams{Context: "testInput"}
invalidParams.Add(request.NewErrParamMinLen("StringField", 5))
invalidParams.Add(request.NewErrParamMinLen("ListField", 3))
invalidParams.Add(request.NewErrParamMinLen("MapField", 4))
return invalidParams
}(),
in: testInput{StringField: aws.String("abcd"), ListField: []string{"a", "b"}, MapField: map[string]string{"a": "a", "b": "b"}},
},
{
err: nil,
in: testInput{StringField: aws.String("abcde"),
ListField: []string{"a", "b", "c"}, MapField: map[string]string{"a": "a", "b": "b", "c": "c", "d": "d"}},
},
}
func TestValidateFieldMinParameter(t *testing.T) {
for i, c := range testsFieldMin {
req := testSvc.NewRequest(&request.Operation{}, &c.in, nil)
corehandlers.ValidateParametersHandler.Fn(req)
assert.Equal(t, c.err, req.Error, "%d case failed", i)
}
}
func BenchmarkValidateAny(b *testing.B) {
input := &kinesis.PutRecordsInput{
StreamName: aws.String("stream"),
}
for i := 0; i < 100; i++ {
record := &kinesis.PutRecordsRequestEntry{
Data: make([]byte, 10000),
PartitionKey: aws.String("partition"),
}
input.Records = append(input.Records, record)
}
req, _ := kinesis.New(session.New()).PutRecordsRequest(input)
b.ResetTimer()
for i := 0; i < b.N; i++ {
corehandlers.ValidateParametersHandler.Fn(req)
if err := req.Error; err != nil {
b.Fatalf("validation failed: %v", err)
}
}
}

View File

@@ -0,0 +1,100 @@
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
//
// @readonly
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
// vai 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 := NewChainCredentials(
// []Provider{
// &EnvProvider{},
// &EC2RoleProvider{
// Client: ec2metadata.New(sess),
// },
// })
//
// // Usage of ChainCredentials with aws.Config
// svc := ec2.New(&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
}

View File

@@ -0,0 +1,154 @@
package credentials
import (
"testing"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/stretchr/testify/assert"
)
type secondStubProvider struct {
creds Value
expired bool
err error
}
func (s *secondStubProvider) Retrieve() (Value, error) {
s.expired = false
s.creds.ProviderName = "secondStubProvider"
return s.creds, s.err
}
func (s *secondStubProvider) IsExpired() bool {
return s.expired
}
func TestChainProviderWithNames(t *testing.T) {
p := &ChainProvider{
Providers: []Provider{
&stubProvider{err: awserr.New("FirstError", "first provider error", nil)},
&stubProvider{err: awserr.New("SecondError", "second provider error", nil)},
&secondStubProvider{
creds: Value{
AccessKeyID: "AKIF",
SecretAccessKey: "NOSECRET",
SessionToken: "",
},
},
&stubProvider{
creds: Value{
AccessKeyID: "AKID",
SecretAccessKey: "SECRET",
SessionToken: "",
},
},
},
}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "secondStubProvider", creds.ProviderName, "Expect provider name to match")
// Also check credentials
assert.Equal(t, "AKIF", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "NOSECRET", creds.SecretAccessKey, "Expect secret access key to match")
assert.Empty(t, creds.SessionToken, "Expect session token to be empty")
}
func TestChainProviderGet(t *testing.T) {
p := &ChainProvider{
Providers: []Provider{
&stubProvider{err: awserr.New("FirstError", "first provider error", nil)},
&stubProvider{err: awserr.New("SecondError", "second provider error", nil)},
&stubProvider{
creds: Value{
AccessKeyID: "AKID",
SecretAccessKey: "SECRET",
SessionToken: "",
},
},
},
}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "AKID", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "SECRET", creds.SecretAccessKey, "Expect secret access key to match")
assert.Empty(t, creds.SessionToken, "Expect session token to be empty")
}
func TestChainProviderIsExpired(t *testing.T) {
stubProvider := &stubProvider{expired: true}
p := &ChainProvider{
Providers: []Provider{
stubProvider,
},
}
assert.True(t, p.IsExpired(), "Expect expired to be true before any Retrieve")
_, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.False(t, p.IsExpired(), "Expect not expired after retrieve")
stubProvider.expired = true
assert.True(t, p.IsExpired(), "Expect return of expired provider")
_, err = p.Retrieve()
assert.False(t, p.IsExpired(), "Expect not expired after retrieve")
}
func TestChainProviderWithNoProvider(t *testing.T) {
p := &ChainProvider{
Providers: []Provider{},
}
assert.True(t, p.IsExpired(), "Expect expired with no providers")
_, err := p.Retrieve()
assert.Equal(t,
ErrNoValidProvidersFoundInChain,
err,
"Expect no providers error returned")
}
func TestChainProviderWithNoValidProvider(t *testing.T) {
errs := []error{
awserr.New("FirstError", "first provider error", nil),
awserr.New("SecondError", "second provider error", nil),
}
p := &ChainProvider{
Providers: []Provider{
&stubProvider{err: errs[0]},
&stubProvider{err: errs[1]},
},
}
assert.True(t, p.IsExpired(), "Expect expired with no providers")
_, err := p.Retrieve()
assert.Equal(t,
ErrNoValidProvidersFoundInChain,
err,
"Expect no providers error returned")
}
func TestChainProviderWithNoValidProviderWithVerboseEnabled(t *testing.T) {
errs := []error{
awserr.New("FirstError", "first provider error", nil),
awserr.New("SecondError", "second provider error", nil),
}
p := &ChainProvider{
VerboseErrors: true,
Providers: []Provider{
&stubProvider{err: errs[0]},
&stubProvider{err: errs[1]},
},
}
assert.True(t, p.IsExpired(), "Expect expired with no providers")
_, err := p.Retrieve()
assert.Equal(t,
awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs),
err,
"Expect no providers error returned")
}

View File

@@ -0,0 +1,223 @@
// 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 := 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 := NewCredentials(&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 := NewCredentials(&MyProvider{})
// credValue, err := creds.Get()
//
package credentials
import (
"sync"
"time"
)
// 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(&aws.Config{Credentials: AnonymousCredentials})
// // Access public S3 buckets.
//
// @readonly
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
}
// 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 {
// Refresh 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
}
// 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) {
e.expiration = expiration
if window > 0 {
e.expiration = e.expiration.Add(-window)
}
}
// IsExpired returns if the credentials are expired.
func (e *Expiry) IsExpired() bool {
if e.CurrentTime == nil {
e.CurrentTime = time.Now
}
return e.expiration.Before(e.CurrentTime())
}
// A Credentials provides synchronous 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 {
creds Value
forceRefresh bool
m sync.Mutex
provider Provider
}
// NewCredentials returns a pointer to a new Credentials with the provider set.
func NewCredentials(provider Provider) *Credentials {
return &Credentials{
provider: provider,
forceRefresh: true,
}
}
// 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) {
c.m.Lock()
defer c.m.Unlock()
if c.isExpired() {
creds, err := c.provider.Retrieve()
if err != nil {
return Value{}, err
}
c.creds = creds
c.forceRefresh = false
}
return c.creds, nil
}
// 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.forceRefresh = true
}
// 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.Lock()
defer c.m.Unlock()
return c.isExpired()
}
// isExpired helper method wrapping the definition of expired credentials.
func (c *Credentials) isExpired() bool {
return c.forceRefresh || c.provider.IsExpired()
}

View File

@@ -0,0 +1,73 @@
package credentials
import (
"testing"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/stretchr/testify/assert"
)
type stubProvider struct {
creds Value
expired bool
err error
}
func (s *stubProvider) Retrieve() (Value, error) {
s.expired = false
s.creds.ProviderName = "stubProvider"
return s.creds, s.err
}
func (s *stubProvider) IsExpired() bool {
return s.expired
}
func TestCredentialsGet(t *testing.T) {
c := NewCredentials(&stubProvider{
creds: Value{
AccessKeyID: "AKID",
SecretAccessKey: "SECRET",
SessionToken: "",
},
expired: true,
})
creds, err := c.Get()
assert.Nil(t, err, "Expected no error")
assert.Equal(t, "AKID", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "SECRET", creds.SecretAccessKey, "Expect secret access key to match")
assert.Empty(t, creds.SessionToken, "Expect session token to be empty")
}
func TestCredentialsGetWithError(t *testing.T) {
c := NewCredentials(&stubProvider{err: awserr.New("provider error", "", nil), expired: true})
_, err := c.Get()
assert.Equal(t, "provider error", err.(awserr.Error).Code(), "Expected provider error")
}
func TestCredentialsExpire(t *testing.T) {
stub := &stubProvider{}
c := NewCredentials(stub)
stub.expired = false
assert.True(t, c.IsExpired(), "Expected to start out expired")
c.Expire()
assert.True(t, c.IsExpired(), "Expected to be expired")
c.forceRefresh = false
assert.False(t, c.IsExpired(), "Expected not to be expired")
stub.expired = true
assert.True(t, c.IsExpired(), "Expected to be expired")
}
func TestCredentialsGetWithProviderName(t *testing.T) {
stub := &stubProvider{}
c := NewCredentials(stub)
creds, err := c.Get()
assert.Nil(t, err, "Expected no error")
assert.Equal(t, creds.ProviderName, "stubProvider", "Expected provider name to match")
}

View File

@@ -0,0 +1,178 @@
package ec2rolecreds
import (
"bufio"
"encoding/json"
"fmt"
"path"
"strings"
"time"
"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"
)
// 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) {
credsList, err := requestCredList(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(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 unmarshalling 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(client *ec2metadata.EC2Metadata) ([]string, error) {
resp, err := client.GetMetadata(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("SerializationError", "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(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCredRespBody, error) {
resp, err := client.GetMetadata(path.Join(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("SerializationError",
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
}

View File

@@ -0,0 +1,159 @@
package ec2rolecreds_test
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
)
const credsRespTmpl = `{
"Code": "Success",
"Type": "AWS-HMAC",
"AccessKeyId" : "accessKey",
"SecretAccessKey" : "secret",
"Token" : "token",
"Expiration" : "%s",
"LastUpdated" : "2009-11-23T0:00:00Z"
}`
const credsFailRespTmpl = `{
"Code": "ErrorCode",
"Message": "ErrorMsg",
"LastUpdated": "2009-11-23T0:00:00Z"
}`
func initTestServer(expireOn string, failAssume bool) *httptest.Server {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/latest/meta-data/iam/security-credentials" {
fmt.Fprintln(w, "RoleName")
} else if r.URL.Path == "/latest/meta-data/iam/security-credentials/RoleName" {
if failAssume {
fmt.Fprintf(w, credsFailRespTmpl)
} else {
fmt.Fprintf(w, credsRespTmpl, expireOn)
}
} else {
http.Error(w, "bad request", http.StatusBadRequest)
}
}))
return server
}
func TestEC2RoleProvider(t *testing.T) {
server := initTestServer("2014-12-16T01:51:37Z", false)
defer server.Close()
p := &ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error, %v", err)
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
}
func TestEC2RoleProviderFailAssume(t *testing.T) {
server := initTestServer("2014-12-16T01:51:37Z", true)
defer server.Close()
p := &ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
}
creds, err := p.Retrieve()
assert.Error(t, err, "Expect error")
e := err.(awserr.Error)
assert.Equal(t, "ErrorCode", e.Code())
assert.Equal(t, "ErrorMsg", e.Message())
assert.Nil(t, e.OrigErr())
assert.Equal(t, "", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "", creds.SecretAccessKey, "Expect secret access key to match")
assert.Equal(t, "", creds.SessionToken, "Expect session token to match")
}
func TestEC2RoleProviderIsExpired(t *testing.T) {
server := initTestServer("2014-12-16T01:51:37Z", false)
defer server.Close()
p := &ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
}
p.CurrentTime = func() time.Time {
return time.Date(2014, 12, 15, 21, 26, 0, 0, time.UTC)
}
assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.")
_, err := p.Retrieve()
assert.Nil(t, err, "Expect no error, %v", err)
assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.")
p.CurrentTime = func() time.Time {
return time.Date(3014, 12, 15, 21, 26, 0, 0, time.UTC)
}
assert.True(t, p.IsExpired(), "Expect creds to be expired.")
}
func TestEC2RoleProviderExpiryWindowIsExpired(t *testing.T) {
server := initTestServer("2014-12-16T01:51:37Z", false)
defer server.Close()
p := &ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
ExpiryWindow: time.Hour * 1,
}
p.CurrentTime = func() time.Time {
return time.Date(2014, 12, 15, 0, 51, 37, 0, time.UTC)
}
assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.")
_, err := p.Retrieve()
assert.Nil(t, err, "Expect no error, %v", err)
assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.")
p.CurrentTime = func() time.Time {
return time.Date(2014, 12, 16, 0, 55, 37, 0, time.UTC)
}
assert.True(t, p.IsExpired(), "Expect creds to be expired.")
}
func BenchmarkEC3RoleProvider(b *testing.B) {
server := initTestServer("2014-12-16T01:51:37Z", false)
defer server.Close()
p := &ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
}
_, err := p.Retrieve()
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := p.Retrieve(); err != nil {
b.Fatal(err)
}
}
}

View File

@@ -0,0 +1,77 @@
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.
//
// @readonly
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.
//
// @readonly
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
}

View File

@@ -0,0 +1,70 @@
package credentials
import (
"github.com/stretchr/testify/assert"
"os"
"testing"
)
func TestEnvProviderRetrieve(t *testing.T) {
os.Clearenv()
os.Setenv("AWS_ACCESS_KEY_ID", "access")
os.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
os.Setenv("AWS_SESSION_TOKEN", "token")
e := EnvProvider{}
creds, err := e.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "access", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
}
func TestEnvProviderIsExpired(t *testing.T) {
os.Clearenv()
os.Setenv("AWS_ACCESS_KEY_ID", "access")
os.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
os.Setenv("AWS_SESSION_TOKEN", "token")
e := EnvProvider{}
assert.True(t, e.IsExpired(), "Expect creds to be expired before retrieve.")
_, err := e.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.False(t, e.IsExpired(), "Expect creds to not be expired after retrieve.")
}
func TestEnvProviderNoAccessKeyID(t *testing.T) {
os.Clearenv()
os.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
e := EnvProvider{}
creds, err := e.Retrieve()
assert.Equal(t, ErrAccessKeyIDNotFound, err, "ErrAccessKeyIDNotFound expected, but was %#v error: %#v", creds, err)
}
func TestEnvProviderNoSecretAccessKey(t *testing.T) {
os.Clearenv()
os.Setenv("AWS_ACCESS_KEY_ID", "access")
e := EnvProvider{}
creds, err := e.Retrieve()
assert.Equal(t, ErrSecretAccessKeyNotFound, err, "ErrSecretAccessKeyNotFound expected, but was %#v error: %#v", creds, err)
}
func TestEnvProviderAlternateNames(t *testing.T) {
os.Clearenv()
os.Setenv("AWS_ACCESS_KEY", "access")
os.Setenv("AWS_SECRET_KEY", "secret")
e := EnvProvider{}
creds, err := e.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "access", creds.AccessKeyID, "Expected access key ID")
assert.Equal(t, "secret", creds.SecretAccessKey, "Expected secret access key")
assert.Empty(t, creds.SessionToken, "Expected no token")
}

View File

@@ -0,0 +1,12 @@
[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

View File

@@ -0,0 +1,151 @@
package credentials
import (
"fmt"
"os"
"path/filepath"
"github.com/go-ini/ini"
"github.com/aws/aws-sdk-go/aws/awserr"
)
// SharedCredsProviderName provides a name of SharedCreds provider
const SharedCredsProviderName = "SharedCredentialsProvider"
var (
// ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found.
//
// @readonly
ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil)
)
// A SharedCredentialsProvider retrieves 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.Load(filename)
if err != nil {
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err)
}
iniProfile, err := config.GetSection(profile)
if err != nil {
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", err)
}
id, err := iniProfile.GetKey("aws_access_key_id")
if err != nil {
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsAccessKey",
fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename),
err)
}
secret, err := iniProfile.GetKey("aws_secret_access_key")
if err != nil {
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.Key("aws_session_token")
return Value{
AccessKeyID: id.String(),
SecretAccessKey: secret.String(),
SessionToken: token.String(),
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 p.Filename == "" {
if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); p.Filename != "" {
return p.Filename, nil
}
homeDir := os.Getenv("HOME") // *nix
if homeDir == "" { // Windows
homeDir = os.Getenv("USERPROFILE")
}
if homeDir == "" {
return "", ErrSharedCredentialsHomeNotFound
}
p.Filename = filepath.Join(homeDir, ".aws", "credentials")
}
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
}

View File

@@ -0,0 +1,116 @@
package credentials
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestSharedCredentialsProvider(t *testing.T) {
os.Clearenv()
p := SharedCredentialsProvider{Filename: "example.ini", Profile: ""}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
}
func TestSharedCredentialsProviderIsExpired(t *testing.T) {
os.Clearenv()
p := SharedCredentialsProvider{Filename: "example.ini", Profile: ""}
assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve")
_, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve")
}
func TestSharedCredentialsProviderWithAWS_SHARED_CREDENTIALS_FILE(t *testing.T) {
os.Clearenv()
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", "example.ini")
p := SharedCredentialsProvider{}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
}
func TestSharedCredentialsProviderWithAWS_SHARED_CREDENTIALS_FILEAbsPath(t *testing.T) {
os.Clearenv()
wd, err := os.Getwd()
assert.NoError(t, err)
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", filepath.Join(wd, "example.ini"))
p := SharedCredentialsProvider{}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
}
func TestSharedCredentialsProviderWithAWS_PROFILE(t *testing.T) {
os.Clearenv()
os.Setenv("AWS_PROFILE", "no_token")
p := SharedCredentialsProvider{Filename: "example.ini", Profile: ""}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
assert.Empty(t, creds.SessionToken, "Expect no token")
}
func TestSharedCredentialsProviderWithoutTokenFromProfile(t *testing.T) {
os.Clearenv()
p := SharedCredentialsProvider{Filename: "example.ini", Profile: "no_token"}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
assert.Empty(t, creds.SessionToken, "Expect no token")
}
func TestSharedCredentialsProviderColonInCredFile(t *testing.T) {
os.Clearenv()
p := SharedCredentialsProvider{Filename: "example.ini", Profile: "with_colon"}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
assert.Empty(t, creds.SessionToken, "Expect no token")
}
func BenchmarkSharedCredentialsProvider(b *testing.B) {
os.Clearenv()
p := SharedCredentialsProvider{Filename: "example.ini", Profile: ""}
_, err := p.Retrieve()
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := p.Retrieve()
if err != nil {
b.Fatal(err)
}
}
}

View File

@@ -0,0 +1,48 @@
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.
//
// @readonly
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.
func NewStaticCredentials(id, secret, token string) *Credentials {
return NewCredentials(&StaticProvider{Value: Value{
AccessKeyID: id,
SecretAccessKey: secret,
SessionToken: token,
}})
}
// 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
}
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
}

View File

@@ -0,0 +1,34 @@
package credentials
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestStaticProviderGet(t *testing.T) {
s := StaticProvider{
Value: Value{
AccessKeyID: "AKID",
SecretAccessKey: "SECRET",
SessionToken: "",
},
}
creds, err := s.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "AKID", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "SECRET", creds.SecretAccessKey, "Expect secret access key to match")
assert.Empty(t, creds.SessionToken, "Expect no session token")
}
func TestStaticProviderIsExpired(t *testing.T) {
s := StaticProvider{
Value: Value{
AccessKeyID: "AKID",
SecretAccessKey: "SECRET",
SessionToken: "",
},
}
assert.False(t, s.IsExpired(), "Expect static credentials to never expire")
}

View File

@@ -0,0 +1,161 @@
// 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.
package stscreds
import (
"fmt"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/service/sts"
)
// 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)
}
// 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 provider must be used explicitly,
// as it is not included in the credentials chain.
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
// 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 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 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.
TokenCode *string
// 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
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
// role will be named after a nanosecond timestamp of this operation.
//
// Takes a Config provider to create the STS client. The ConfigProvider is
// satisfied by the session.Session type.
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 object wrapping the
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
// role will be named after a nanosecond timestamp of this operation.
//
// Takes an AssumeRoler which can be satisfiede by the STS client.
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) {
// 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
}
input := &sts.AssumeRoleInput{
DurationSeconds: aws.Int64(int64(p.Duration / time.Second)),
RoleArn: aws.String(p.RoleARN),
RoleSessionName: aws.String(p.RoleSessionName),
ExternalId: p.ExternalID,
}
if p.Policy != nil {
input.Policy = p.Policy
}
if p.SerialNumber != nil && p.TokenCode != nil {
input.SerialNumber = p.SerialNumber
input.TokenCode = p.TokenCode
}
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
}

View File

@@ -0,0 +1,56 @@
package stscreds
import (
"testing"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/stretchr/testify/assert"
)
type stubSTS struct {
}
func (s *stubSTS) AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) {
expiry := time.Now().Add(60 * time.Minute)
return &sts.AssumeRoleOutput{
Credentials: &sts.Credentials{
// Just reflect the role arn to the provider.
AccessKeyId: input.RoleArn,
SecretAccessKey: aws.String("assumedSecretAccessKey"),
SessionToken: aws.String("assumedSessionToken"),
Expiration: &expiry,
},
}, nil
}
func TestAssumeRoleProvider(t *testing.T) {
stub := &stubSTS{}
p := &AssumeRoleProvider{
Client: stub,
RoleARN: "roleARN",
}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "roleARN", creds.AccessKeyID, "Expect access key ID to be reflected role ARN")
assert.Equal(t, "assumedSecretAccessKey", creds.SecretAccessKey, "Expect secret access key to match")
assert.Equal(t, "assumedSessionToken", creds.SessionToken, "Expect session token to match")
}
func BenchmarkAssumeRoleProvider(b *testing.B) {
stub := &stubSTS{}
p := &AssumeRoleProvider{
Client: stub,
RoleARN: "roleARN",
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := p.Retrieve(); err != nil {
b.Fatal(err)
}
}
}

View File

@@ -0,0 +1,98 @@
// 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 (
"net/http"
"os"
"time"
"github.com/aws/aws-sdk-go/aws"
"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/ec2metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/endpoints"
)
// 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).
WithSleepDelay(time.Sleep)
}
// 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.AfterEachFn = request.HandlerListStopOnError
handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
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 {
endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, *cfg.Region, true)
return credentials.NewCredentials(&credentials.ChainProvider{
VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
Providers: []credentials.Provider{
&credentials.EnvProvider{},
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
&ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.NewClient(*cfg, handlers, endpoint, signingRegion),
ExpiryWindow: 5 * time.Minute,
},
}})
}

140
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go generated vendored Normal file
View File

@@ -0,0 +1,140 @@
package ec2metadata
import (
"encoding/json"
"fmt"
"path"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
)
// GetMetadata uses the path provided to request information from the EC2
// instance metdata service. The content will be returned as a string, or
// error if the request failed.
func (c *EC2Metadata) GetMetadata(p string) (string, error) {
op := &request.Operation{
Name: "GetMetadata",
HTTPMethod: "GET",
HTTPPath: path.Join("/", "meta-data", p),
}
output := &metadataOutput{}
req := c.NewRequest(op, nil, output)
return output.Content, req.Send()
}
// 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) {
op := &request.Operation{
Name: "GetDynamicData",
HTTPMethod: "GET",
HTTPPath: path.Join("/", "dynamic", p),
}
output := &metadataOutput{}
req := c.NewRequest(op, nil, output)
return output.Content, req.Send()
}
// 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) {
resp, err := c.GetDynamicData("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("SerializationError",
"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) {
resp, err := c.GetMetadata("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("SerializationError",
"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) {
resp, err := c.GetMetadata("placement/availability-zone")
if err != nil {
return "", err
}
// returns region without the suffix. Eg: us-west-2a becomes us-west-2
return resp[:len(resp)-1], 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 {
if _, err := c.GetMetadata("instance-id"); err != nil {
return false
}
return true
}
// An EC2IAMInfo provides the shape for unmarshalling
// 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 unmarshalling
// an instance identity document
type EC2InstanceIdentityDocument struct {
DevpayProductCodes []string `json:"devpayProductCodes"`
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"`
}

View File

@@ -0,0 +1,195 @@
package ec2metadata_test
import (
"bytes"
"io/ioutil"
"net/http"
"net/http/httptest"
"path"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/session"
)
const instanceIdentityDocument = `{
"devpayProductCodes" : null,
"availabilityZone" : "us-east-1d",
"privateIp" : "10.158.112.84",
"version" : "2010-08-31",
"region" : "us-east-1",
"instanceId" : "i-1234567890abcdef0",
"billingProducts" : null,
"instanceType" : "t1.micro",
"accountId" : "123456789012",
"pendingTime" : "2015-11-19T16:32:11Z",
"imageId" : "ami-5fb8c835",
"kernelId" : "aki-919dcaf8",
"ramdiskId" : null,
"architecture" : "x86_64"
}`
const validIamInfo = `{
"Code" : "Success",
"LastUpdated" : "2016-03-17T12:27:32Z",
"InstanceProfileArn" : "arn:aws:iam::123456789012:instance-profile/my-instance-profile",
"InstanceProfileId" : "AIPAABCDEFGHIJKLMN123"
}`
const unsuccessfulIamInfo = `{
"Code" : "Failed",
"LastUpdated" : "2016-03-17T12:27:32Z",
"InstanceProfileArn" : "arn:aws:iam::123456789012:instance-profile/my-instance-profile",
"InstanceProfileId" : "AIPAABCDEFGHIJKLMN123"
}`
func initTestServer(path string, resp string) *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.RequestURI != path {
http.Error(w, "not found", http.StatusNotFound)
return
}
w.Write([]byte(resp))
}))
}
func TestEndpoint(t *testing.T) {
c := ec2metadata.New(session.New())
op := &request.Operation{
Name: "GetMetadata",
HTTPMethod: "GET",
HTTPPath: path.Join("/", "meta-data", "testpath"),
}
req := c.NewRequest(op, nil, nil)
assert.Equal(t, "http://169.254.169.254/latest", req.ClientInfo.Endpoint)
assert.Equal(t, "http://169.254.169.254/latest/meta-data/testpath", req.HTTPRequest.URL.String())
}
func TestGetMetadata(t *testing.T) {
server := initTestServer(
"/latest/meta-data/some/path",
"success", // real response includes suffix
)
defer server.Close()
c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
resp, err := c.GetMetadata("some/path")
assert.NoError(t, err)
assert.Equal(t, "success", resp)
}
func TestGetRegion(t *testing.T) {
server := initTestServer(
"/latest/meta-data/placement/availability-zone",
"us-west-2a", // real response includes suffix
)
defer server.Close()
c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
region, err := c.Region()
assert.NoError(t, err)
assert.Equal(t, "us-west-2", region)
}
func TestMetadataAvailable(t *testing.T) {
server := initTestServer(
"/latest/meta-data/instance-id",
"instance-id",
)
defer server.Close()
c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
available := c.Available()
assert.True(t, available)
}
func TestMetadataIAMInfo_success(t *testing.T) {
server := initTestServer(
"/latest/meta-data/iam/info",
validIamInfo,
)
defer server.Close()
c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
iamInfo, err := c.IAMInfo()
assert.NoError(t, err)
assert.Equal(t, "Success", iamInfo.Code)
assert.Equal(t, "arn:aws:iam::123456789012:instance-profile/my-instance-profile", iamInfo.InstanceProfileArn)
assert.Equal(t, "AIPAABCDEFGHIJKLMN123", iamInfo.InstanceProfileID)
}
func TestMetadataIAMInfo_failure(t *testing.T) {
server := initTestServer(
"/latest/meta-data/iam/info",
unsuccessfulIamInfo,
)
defer server.Close()
c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
iamInfo, err := c.IAMInfo()
assert.NotNil(t, err)
assert.Equal(t, "", iamInfo.Code)
assert.Equal(t, "", iamInfo.InstanceProfileArn)
assert.Equal(t, "", iamInfo.InstanceProfileID)
}
func TestMetadataNotAvailable(t *testing.T) {
c := ec2metadata.New(session.New())
c.Handlers.Send.Clear()
c.Handlers.Send.PushBack(func(r *request.Request) {
r.HTTPResponse = &http.Response{
StatusCode: int(0),
Status: http.StatusText(int(0)),
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
}
r.Error = awserr.New("RequestError", "send request failed", nil)
r.Retryable = aws.Bool(true) // network errors are retryable
})
available := c.Available()
assert.False(t, available)
}
func TestMetadataErrorResponse(t *testing.T) {
c := ec2metadata.New(session.New())
c.Handlers.Send.Clear()
c.Handlers.Send.PushBack(func(r *request.Request) {
r.HTTPResponse = &http.Response{
StatusCode: http.StatusBadRequest,
Status: http.StatusText(http.StatusBadRequest),
Body: ioutil.NopCloser(strings.NewReader("error message text")),
}
r.Retryable = aws.Bool(false) // network errors are retryable
})
data, err := c.GetMetadata("uri/path")
assert.Empty(t, data)
assert.Contains(t, err.Error(), "error message text")
}
func TestEC2RoleProviderInstanceIdentity(t *testing.T) {
server := initTestServer(
"/latest/dynamic/instance-identity/document",
instanceIdentityDocument,
)
defer server.Close()
c := ec2metadata.New(session.New(), &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
doc, err := c.GetInstanceIdentityDocument()
assert.Nil(t, err, "Expect no error, %v", err)
assert.Equal(t, doc.AccountID, "123456789012")
assert.Equal(t, doc.AvailabilityZone, "us-east-1d")
assert.Equal(t, doc.Region, "us-east-1")
}

View File

@@ -0,0 +1,124 @@
// Package ec2metadata provides the client for making API calls to the
// EC2 Metadata service.
package ec2metadata
import (
"bytes"
"errors"
"io"
"net/http"
"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/request"
)
// ServiceName is the name of the service.
const ServiceName = "ec2metadata"
// 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.
//
// 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: 5 * time.Second,
}
}
svc := &EC2Metadata{
Client: client.New(
cfg,
metadata.ClientInfo{
ServiceName: ServiceName,
Endpoint: endpoint,
APIVersion: "latest",
},
handlers,
),
}
svc.Handlers.Unmarshal.PushBack(unmarshalHandler)
svc.Handlers.UnmarshalError.PushBack(unmarshalError)
svc.Handlers.Validate.Clear()
svc.Handlers.Validate.PushBack(validateEndpointHandler)
// 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
}
func unmarshalHandler(r *request.Request) {
defer r.HTTPResponse.Body.Close()
b := &bytes.Buffer{}
if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err)
return
}
if data, ok := r.Data.(*metadataOutput); ok {
data.Content = b.String()
}
}
func unmarshalError(r *request.Request) {
defer r.HTTPResponse.Body.Close()
b := &bytes.Buffer{}
if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err)
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("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String()))
}
func validateEndpointHandler(r *request.Request) {
if r.ClientInfo.Endpoint == "" {
r.Error = aws.ErrMissingEndpoint
}
}

View File

@@ -0,0 +1,79 @@
package ec2metadata_test
import (
"net/http"
"net/http/httptest"
"sync"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/stretchr/testify/assert"
)
func TestClientOverrideDefaultHTTPClientTimeout(t *testing.T) {
svc := ec2metadata.New(session.New())
assert.NotEqual(t, http.DefaultClient, svc.Config.HTTPClient)
assert.Equal(t, 5*time.Second, svc.Config.HTTPClient.Timeout)
}
func TestClientNotOverrideDefaultHTTPClientTimeout(t *testing.T) {
origClient := *http.DefaultClient
http.DefaultClient.Transport = &http.Transport{}
defer func() {
http.DefaultClient = &origClient
}()
svc := ec2metadata.New(session.New())
assert.Equal(t, http.DefaultClient, svc.Config.HTTPClient)
tr, ok := svc.Config.HTTPClient.Transport.(*http.Transport)
assert.True(t, ok)
assert.NotNil(t, tr)
assert.Nil(t, tr.Dial)
}
func TestClientDisableOverrideDefaultHTTPClientTimeout(t *testing.T) {
svc := ec2metadata.New(session.New(aws.NewConfig().WithEC2MetadataDisableTimeoutOverride(true)))
assert.Equal(t, http.DefaultClient, svc.Config.HTTPClient)
}
func TestClientOverrideDefaultHTTPClientTimeoutRace(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("us-east-1a"))
}))
cfg := aws.NewConfig().WithEndpoint(server.URL)
runEC2MetadataClients(t, cfg, 100)
}
func TestClientOverrideDefaultHTTPClientTimeoutRaceWithTransport(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("us-east-1a"))
}))
cfg := aws.NewConfig().WithEndpoint(server.URL).WithHTTPClient(&http.Client{
Transport: http.DefaultTransport,
})
runEC2MetadataClients(t, cfg, 100)
}
func runEC2MetadataClients(t *testing.T, cfg *aws.Config, atOnce int) {
var wg sync.WaitGroup
wg.Add(atOnce)
for i := 0; i < atOnce; i++ {
go func() {
svc := ec2metadata.New(session.New(), cfg)
_, err := svc.Region()
assert.NoError(t, err)
wg.Done()
}()
}
wg.Wait()
}

17
vendor/github.com/aws/aws-sdk-go/aws/errors.go generated vendored Normal file
View File

@@ -0,0 +1,17 @@
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.
//
// @readonly
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.
//
// @readonly
ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil)
)

Some files were not shown because too many files have changed in this diff Show More