vendor: update all dependencies

This commit is contained in:
Nick Craig-Wood 2020-02-25 14:20:57 +00:00
parent 17b4058ee9
commit abb9f89f65
443 changed files with 32118 additions and 18237 deletions

57
go.mod
View file

@ -1,75 +1,70 @@
module github.com/rclone/rclone module github.com/rclone/rclone
require ( require (
bazil.org/fuse v0.0.0-20191225233854-3a99aca11732 bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc
cloud.google.com/go v0.47.0 // indirect cloud.google.com/go v0.53.0 // indirect
github.com/Azure/azure-pipeline-go v0.2.2 github.com/Azure/azure-pipeline-go v0.2.2
github.com/Azure/azure-storage-blob-go v0.8.0 github.com/Azure/azure-storage-blob-go v0.8.0
github.com/Azure/go-autorest/autorest/adal v0.6.0 // indirect github.com/Azure/go-autorest/autorest/adal v0.6.0 // indirect
github.com/Unknwon/goconfig v0.0.0-20190425194916-3dba17dd7b9e github.com/Unknwon/goconfig v0.0.0-20191126170842-860a72fb44fd
github.com/a8m/tree v0.0.0-20181222104329-6a0b80129de4 github.com/a8m/tree v0.0.0-20181222104329-6a0b80129de4
github.com/abbot/go-http-auth v0.4.0 github.com/abbot/go-http-auth v0.4.0
github.com/anacrolix/dms v1.1.0 github.com/anacrolix/dms v1.1.0
github.com/atotto/clipboard v0.1.2 github.com/atotto/clipboard v0.1.2
github.com/aws/aws-sdk-go v1.25.31 github.com/aws/aws-sdk-go v1.29.9
github.com/billziss-gh/cgofuse v1.2.0 github.com/billziss-gh/cgofuse v1.2.0
github.com/djherbis/times v1.2.0 github.com/djherbis/times v1.2.0
github.com/dropbox/dropbox-sdk-go-unofficial v5.4.0+incompatible github.com/dropbox/dropbox-sdk-go-unofficial v5.6.0+incompatible
github.com/etcd-io/bbolt v1.3.3 github.com/etcd-io/bbolt v1.3.3
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect
github.com/google/go-cmp v0.3.1 // indirect
github.com/google/go-querystring v1.0.0 // indirect github.com/google/go-querystring v1.0.0 // indirect
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect
github.com/hanwen/go-fuse/v2 v2.0.3-0.20191108143333-152e6ac32d54 github.com/hanwen/go-fuse/v2 v2.0.3-0.20191108143333-152e6ac32d54
github.com/jlaffaye/ftp v0.0.0-20191025175106-a59fe673c9b2 github.com/jlaffaye/ftp v0.0.0-20191218041957-e1b8fdd0dcc3
github.com/jzelinskie/whirlpool v0.0.0-20170603002051-c19460b8caa6 github.com/jzelinskie/whirlpool v0.0.0-20170603002051-c19460b8caa6
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/koofr/go-httpclient v0.0.0-20190818202018-e0dc8fd921dc github.com/koofr/go-httpclient v0.0.0-20190818202018-e0dc8fd921dc
github.com/koofr/go-koofrclient v0.0.0-20190724113126-8e5366da203a github.com/koofr/go-koofrclient v0.0.0-20190724113126-8e5366da203a
github.com/mattn/go-colorable v0.1.4 github.com/mattn/go-colorable v0.1.4
github.com/mattn/go-ieproxy v0.0.0-20190805055040-f9202b1cfdeb // indirect github.com/mattn/go-ieproxy v0.0.0-20200203040449-2dbc853185d9 // indirect
github.com/mattn/go-isatty v0.0.11-0.20191112051248-2a2f0ea997f9 // indirect github.com/mattn/go-isatty v0.0.12 // indirect
github.com/mattn/go-runewidth v0.0.7 github.com/mattn/go-runewidth v0.0.8
github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir v1.1.0
github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2 github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2
github.com/ncw/swift v1.0.49 github.com/ncw/swift v1.0.50
github.com/nsf/termbox-go v0.0.0-20191229070316-58d4fcbce2a7 github.com/nsf/termbox-go v0.0.0-20200204031403-4d2b513ad8be
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd
github.com/onsi/ginkgo v1.9.0 // indirect github.com/onsi/ginkgo v1.9.0 // indirect
github.com/onsi/gomega v1.6.0 // indirect github.com/onsi/gomega v1.6.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.9.1
github.com/pkg/sftp v1.10.1 github.com/pkg/sftp v1.11.0
github.com/putdotio/go-putio v0.0.0-20190822121956-19b9c636c877 github.com/putdotio/go-putio/putio v0.0.0-20200123120452-16d982cac2b8
github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46 github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46
github.com/sevlyar/go-daemon v0.1.5 github.com/sevlyar/go-daemon v0.1.5
github.com/sirupsen/logrus v1.4.2 github.com/sirupsen/logrus v1.4.2
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
github.com/smartystreets/assertions v1.0.1 // indirect github.com/smartystreets/assertions v1.0.1 // indirect
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect
github.com/spf13/cobra v0.0.5 github.com/spf13/cobra v0.0.6
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.5.1
github.com/t3rm1n4l/go-mega v0.0.0-20200117211730-79a813bb328d github.com/t3rm1n4l/go-mega v0.0.0-20200117211730-79a813bb328d
github.com/xanzy/ssh-agent v0.2.1 github.com/xanzy/ssh-agent v0.2.1
github.com/youmark/pkcs8 v0.0.0-20191102193632-94c173a94d60 github.com/youmark/pkcs8 v0.0.0-20191102193632-94c173a94d60
github.com/yunify/qingstor-sdk-go/v3 v3.1.1 github.com/yunify/qingstor-sdk-go/v3 v3.2.0
go.etcd.io/bbolt v1.3.3 // indirect go.etcd.io/bbolt v1.3.3 // indirect
go.opencensus.io v0.22.2 // indirect goftp.io/server v0.3.2
goftp.io/server v0.0.0-20190812052725-72a57b186803 golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d
golang.org/x/crypto v0.0.0-20200109152110-61a87790db17 golang.org/x/net v0.0.0-20200222125558-5a598a2470a0
golang.org/x/net v0.0.0-20191109021931-daa7c04131f5 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae
golang.org/x/text v0.3.2 golang.org/x/text v0.3.2
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 golang.org/x/time v0.0.0-20191024005414-555d28b269f0
google.golang.org/api v0.13.0 google.golang.org/api v0.18.0
google.golang.org/appengine v1.6.5 // indirect google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688 // indirect
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a // indirect gopkg.in/yaml.v2 v2.2.8
google.golang.org/grpc v1.25.1 // indirect
gopkg.in/yaml.v2 v2.2.5
) )
go 1.13 go 1.13

266
go.sum
View file

@ -1,5 +1,5 @@
bazil.org/fuse v0.0.0-20191225233854-3a99aca11732 h1:gaB1+kZCJDExjlrdy37gIwxV0M7v81EzIFKQZ5o5YV0= bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc h1:utDghgcjE8u+EBjHOgYT+dJPcnDF05KqWMBcjuJy510=
bazil.org/fuse v0.0.0-20191225233854-3a99aca11732/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@ -7,16 +7,17 @@ cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6A
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.47.0 h1:1JUtpcY9E7+eTospEwWS2QXP3DEn7poB3E2j0jN74mM= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.47.0/go.mod h1:5p3Ky/7f3N10VBkhuR5LFtddroTiMyjZV/Kj5qOQFxU= cloud.google.com/go v0.53.0 h1:MZQCQQaRwOrAcuKjiHWHrgKykt4fZyuwF2dtiG3fGW8=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
gitea.com/goftp/file-driver v0.0.0-20190712091345-f79c2ed973f8/go.mod h1:ghdogu0Da3rwYCSJ20JPgTiMcDpzeRbzvuFIOOW3G7w=
gitea.com/goftp/file-driver v0.0.0-20190812052443-efcdcba68b34 h1:3wshUWDKHcy8hrNafCS4rtuAdON2KYsuznc05zdHTrQ=
gitea.com/goftp/file-driver v0.0.0-20190812052443-efcdcba68b34/go.mod h1:6+f1gclV97PmaVmE4YJbH3KIKnl+r3/HWR0zD/z1CG4=
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY= github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY=
github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
@ -38,75 +39,100 @@ github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1Gn
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w= github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w=
github.com/Unknwon/goconfig v0.0.0-20190425194916-3dba17dd7b9e h1:ZaFHdRwv6wJQMYsg5qITIsqWRqZRvUETiq0xxrl+8fc= github.com/Unknwon/goconfig v0.0.0-20191126170842-860a72fb44fd h1:+CYOsXi89xOqBkj7CuEJjA2It+j+R3ngUZEydr6mtkw=
github.com/Unknwon/goconfig v0.0.0-20190425194916-3dba17dd7b9e/go.mod h1:wngxua9XCNjvHjDiTiV26DaKDT+0c63QR6H5hjVUUxw= github.com/Unknwon/goconfig v0.0.0-20191126170842-860a72fb44fd/go.mod h1:wngxua9XCNjvHjDiTiV26DaKDT+0c63QR6H5hjVUUxw=
github.com/a8m/tree v0.0.0-20181222104329-6a0b80129de4 h1:mK1/QgFPU4osbhjJ26B1w738kjQHaGJcon8uCLMS8fk= github.com/a8m/tree v0.0.0-20181222104329-6a0b80129de4 h1:mK1/QgFPU4osbhjJ26B1w738kjQHaGJcon8uCLMS8fk=
github.com/a8m/tree v0.0.0-20181222104329-6a0b80129de4/go.mod h1:FSdwKX97koS5efgm8WevNf7XS3PqtyFkKDDXrz778cg= github.com/a8m/tree v0.0.0-20181222104329-6a0b80129de4/go.mod h1:FSdwKX97koS5efgm8WevNf7XS3PqtyFkKDDXrz778cg=
github.com/abbot/go-http-auth v0.4.0 h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0= github.com/abbot/go-http-auth v0.4.0 h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0=
github.com/abbot/go-http-auth v0.4.0/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM= github.com/abbot/go-http-auth v0.4.0/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/anacrolix/dms v1.1.0 h1:vbBXZS7T5FaZm+9p1pdmVVo9tN3qdc27bKSETdeT3xo= github.com/anacrolix/dms v1.1.0 h1:vbBXZS7T5FaZm+9p1pdmVVo9tN3qdc27bKSETdeT3xo=
github.com/anacrolix/dms v1.1.0/go.mod h1:msPKAoppoNRfrYplJqx63FZ+VipDZ4Xsj3KzIQxyU7k= github.com/anacrolix/dms v1.1.0/go.mod h1:msPKAoppoNRfrYplJqx63FZ+VipDZ4Xsj3KzIQxyU7k=
github.com/anacrolix/envpprof v0.0.0-20180404065416-323002cec2fa/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c= github.com/anacrolix/envpprof v0.0.0-20180404065416-323002cec2fa/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c=
github.com/anacrolix/envpprof v1.0.0/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c= github.com/anacrolix/envpprof v1.0.0/go.mod h1:KgHhUaQMc8cC0+cEflSgCFNFbKwi5h54gqtVn8yhP7c=
github.com/anacrolix/ffprobe v1.0.0 h1:j8fGLBsXejwdXd0pkA9iR3Dt1XwMFv5wjeYWObcue8A=
github.com/anacrolix/ffprobe v1.0.0/go.mod h1:BIw+Bjol6CWjm/CRWrVLk2Vy+UYlkgmBZ05vpSYqZPw= github.com/anacrolix/ffprobe v1.0.0/go.mod h1:BIw+Bjol6CWjm/CRWrVLk2Vy+UYlkgmBZ05vpSYqZPw=
github.com/anacrolix/missinggo v1.1.0/go.mod h1:MBJu3Sk/k3ZfGYcS7z18gwfu72Ey/xopPFJJbTi5yIo= github.com/anacrolix/missinggo v1.1.0/go.mod h1:MBJu3Sk/k3ZfGYcS7z18gwfu72Ey/xopPFJJbTi5yIo=
github.com/anacrolix/tagflag v0.0.0-20180109131632-2146c8d41bf0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw= github.com/anacrolix/tagflag v0.0.0-20180109131632-2146c8d41bf0/go.mod h1:1m2U/K6ZT+JZG0+bdMK6qauP49QT4wE5pmhJXOKKCHw=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/atotto/clipboard v0.1.2 h1:YZCtFu5Ie8qX2VmVTBnrqLSiU9XOWwqNRmdT3gIQzbY= github.com/atotto/clipboard v0.1.2 h1:YZCtFu5Ie8qX2VmVTBnrqLSiU9XOWwqNRmdT3gIQzbY=
github.com/atotto/clipboard v0.1.2/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/atotto/clipboard v0.1.2/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aws/aws-sdk-go v1.25.31 h1:14mdh3HsTgRekePPkYcCbAaEXJknc3mN7f4XfsiMMDA= github.com/aws/aws-sdk-go v1.29.9 h1:PHq9ddjfZYfCOXyqHKiCZ1CHRAk7nXhV7WTqj5l+bmQ=
github.com/aws/aws-sdk-go v1.25.31/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.29.9/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/billziss-gh/cgofuse v1.2.0 h1:FMdQSygSBpD4yEPENJcmvfCdmNWMVkPLlD7wWdl/7IA= github.com/billziss-gh/cgofuse v1.2.0 h1:FMdQSygSBpD4yEPENJcmvfCdmNWMVkPLlD7wWdl/7IA=
github.com/billziss-gh/cgofuse v1.2.0/go.mod h1:LJjoaUojlVjgo5GQoEJTcJNqZJeRU0nCR84CyxKt2YM= github.com/billziss-gh/cgofuse v1.2.0/go.mod h1:LJjoaUojlVjgo5GQoEJTcJNqZJeRU0nCR84CyxKt2YM=
github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo= github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
github.com/bradfitz/iter v0.0.0-20190303215204-33e6a9893b0c/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo= github.com/bradfitz/iter v0.0.0-20190303215204-33e6a9893b0c/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/djherbis/times v1.2.0 h1:xANXjsC/iBqbO00vkWlYwPWgBgEVU6m6AFYg0Pic+Mc= github.com/djherbis/times v1.2.0 h1:xANXjsC/iBqbO00vkWlYwPWgBgEVU6m6AFYg0Pic+Mc=
github.com/djherbis/times v1.2.0/go.mod h1:CGMZlo255K5r4Yw0b9RRfFQpM2y7uOmxg4jm9HsaVf8= github.com/djherbis/times v1.2.0/go.mod h1:CGMZlo255K5r4Yw0b9RRfFQpM2y7uOmxg4jm9HsaVf8=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dropbox/dropbox-sdk-go-unofficial v5.4.0+incompatible h1:9jnukMIowLSo3SY7+GTwxmYJv4QC0LxXbo97zHWCyoc= github.com/dropbox/dropbox-sdk-go-unofficial v5.6.0+incompatible h1:DtumzkLk2zZ2SeElEr+VNz+zV7l+BTe509cV4sKPXbM=
github.com/dropbox/dropbox-sdk-go-unofficial v5.4.0+incompatible/go.mod h1:lr+LhMM3F6Y3lW1T9j2U5l7QeuWm87N9+PPXo3yH4qY= github.com/dropbox/dropbox-sdk-go-unofficial v5.6.0+incompatible/go.mod h1:lr+LhMM3F6Y3lW1T9j2U5l7QeuWm87N9+PPXo3yH4qY=
github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM= github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM=
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9 h1:cC0Hbb+18DJ4i6ybqDybvj4wdIDS4vnD0QEci98PgM8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9/go.mod h1:GpOj6zuVBG3Inr9qjEnuVTgBlk2lZ1S9DcoFiXWyKss= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/goftp/server v0.0.0-20190304020633-eabccc535b5a/go.mod h1:k/SS6VWkxY7dHPhoMQ8IdRu8L4lQtmGbhyXGg+vCnXE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 h1:uHTyIjqVhYRhLbJ8nIiOJHkEZZ+5YoOsAbD3sk82NiE= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@ -116,11 +142,14 @@ github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
@ -129,6 +158,10 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk= github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk=
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hanwen/go-fuse v1.0.0 h1:GxS9Zrn6c35/BnfiVsZVWmsG803xwE7eVRDvcf/BEVc= github.com/hanwen/go-fuse v1.0.0 h1:GxS9Zrn6c35/BnfiVsZVWmsG803xwE7eVRDvcf/BEVc=
github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok=
github.com/hanwen/go-fuse/v2 v2.0.3-0.20191108143333-152e6ac32d54 h1:0JL4/kY3QKTRevfl0IbEncTzA+jczGba+swfDBBluuU= github.com/hanwen/go-fuse/v2 v2.0.3-0.20191108143333-152e6ac32d54 h1:0JL4/kY3QKTRevfl0IbEncTzA+jczGba+swfDBBluuU=
@ -140,21 +173,26 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jlaffaye/ftp v0.0.0-20190624084859-c1312a7102bf/go.mod h1:lli8NYPQOFy3O++YmYbqVgOcQ1JPCwdOy+5zSjKJ9qY= github.com/jlaffaye/ftp v0.0.0-20190624084859-c1312a7102bf/go.mod h1:lli8NYPQOFy3O++YmYbqVgOcQ1JPCwdOy+5zSjKJ9qY=
github.com/jlaffaye/ftp v0.0.0-20191025175106-a59fe673c9b2 h1:WY3P4euRv9s8F2rpZUK1jnk4ZMiV3O2ltdnoZK/GTUU= github.com/jlaffaye/ftp v0.0.0-20191218041957-e1b8fdd0dcc3 h1:QyB6CQGLB65Al72mAIbqrkGRk56JdGMHgBziM3F0FCw=
github.com/jlaffaye/ftp v0.0.0-20191025175106-a59fe673c9b2/go.mod h1:PwUeyujmhaGohgOf0kJKxPfk3HcRv8QD/wAUN44go4k= github.com/jlaffaye/ftp v0.0.0-20191218041957-e1b8fdd0dcc3/go.mod h1:PwUeyujmhaGohgOf0kJKxPfk3HcRv8QD/wAUN44go4k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/jzelinskie/whirlpool v0.0.0-20170603002051-c19460b8caa6 h1:RyOL4+OIUc6u5ac2LclitlZvFES6k+sg18fBMfxFUUs= github.com/jzelinskie/whirlpool v0.0.0-20170603002051-c19460b8caa6 h1:RyOL4+OIUc6u5ac2LclitlZvFES6k+sg18fBMfxFUUs=
github.com/jzelinskie/whirlpool v0.0.0-20170603002051-c19460b8caa6/go.mod h1:KmHnJWQrgEvbuy0vcvj00gtMqbvNn1L+3YUZLK/B92c= github.com/jzelinskie/whirlpool v0.0.0-20170603002051-c19460b8caa6/go.mod h1:KmHnJWQrgEvbuy0vcvj00gtMqbvNn1L+3YUZLK/B92c=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@ -166,6 +204,7 @@ github.com/koofr/go-koofrclient v0.0.0-20190724113126-8e5366da203a h1:02cx9xF4W2
github.com/koofr/go-koofrclient v0.0.0-20190724113126-8e5366da203a/go.mod h1:MRAz4Gsxd+OzrZ0owwrUHc0zLESL+1Y5syqK/sJxK2A= github.com/koofr/go-koofrclient v0.0.0-20190724113126-8e5366da203a/go.mod h1:MRAz4Gsxd+OzrZ0owwrUHc0zLESL+1Y5syqK/sJxK2A=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -178,25 +217,29 @@ github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaa
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
github.com/mattn/go-ieproxy v0.0.0-20190805055040-f9202b1cfdeb h1:hXqqXzQtJbENrsb+rsIqkVqcg4FUJL0SQFGw08Dgivw= github.com/mattn/go-ieproxy v0.0.0-20200203040449-2dbc853185d9 h1:a6/tH/zhh2tdoUSDgS4gNcY6H2Mae/70R+jEkRv52ws=
github.com/mattn/go-ieproxy v0.0.0-20190805055040-f9202b1cfdeb/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20200203040449-2dbc853185d9/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11-0.20191112051248-2a2f0ea997f9 h1:tM1L+QoyOIq/0KiBQ4y/jUW0jxB5kz35bz+PSoQYjq8= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.11-0.20191112051248-2a2f0ea997f9/go.mod h1:cxQpGCW53krnBJYXw0m6SYdk+OIHR4jbEstSUj/+MQ4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2 h1:VlXvEx6JbFp7F9iz92zXP2Ew+9VupSpfybr+TxmjdH0= github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2 h1:VlXvEx6JbFp7F9iz92zXP2Ew+9VupSpfybr+TxmjdH0=
github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2/go.mod h1:MLIrzg7gp/kzVBxRE1olT7CWYMCklcUWU+ekoxOD9x0= github.com/ncw/go-acd v0.0.0-20171120105400-887eb06ab6a2/go.mod h1:MLIrzg7gp/kzVBxRE1olT7CWYMCklcUWU+ekoxOD9x0=
github.com/ncw/swift v1.0.49 h1:eQaKIjSt/PXLKfYgzg01nevmO+CMXfXGRhB1gOhDs7E= github.com/ncw/swift v1.0.50 h1:E01b5bVIssNhx2KnzAjMWEXkKrb8ytTqCDWY7lqmWjA=
github.com/ncw/swift v1.0.49/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/ncw/swift v1.0.50/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/nsf/termbox-go v0.0.0-20191229070316-58d4fcbce2a7 h1:OkWEy7aQeQTbgdrcGi9bifx+Y6bMM7ae7y42hDFaBvA= github.com/nsf/termbox-go v0.0.0-20200204031403-4d2b513ad8be h1:yzmWtPyxEUIKdZg4RcPq64MfS8NA6A5fNOJgYhpR9EQ=
github.com/nsf/termbox-go v0.0.0-20191229070316-58d4fcbce2a7/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ= github.com/nsf/termbox-go v0.0.0-20200204031403-4d2b513ad8be/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd h1:+iAPaTbi1gZpcpDwe/BW1fx7Xoesv69hLNGPheoyhBs= github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd h1:+iAPaTbi1gZpcpDwe/BW1fx7Xoesv69hLNGPheoyhBs=
github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd/go.mod h1:4soZNh0zW0LtYGdQ416i0jO0EIqMGcbtaspRS4BDvRQ= github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd/go.mod h1:4soZNh0zW0LtYGdQ416i0jO0EIqMGcbtaspRS4BDvRQ=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -210,44 +253,63 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14 h1:XeOYlK9W1uCmhjJSsY78Mcuh7MVkNjTzmHx1yBzizSU= github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14 h1:XeOYlK9W1uCmhjJSsY78Mcuh7MVkNjTzmHx1yBzizSU=
github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14/go.mod h1:jVblp62SafmidSkvWrXyxAme3gaTfEtWwRPGz5cpvHg= github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14/go.mod h1:jVblp62SafmidSkvWrXyxAme3gaTfEtWwRPGz5cpvHg=
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.11.0 h1:4Zv0OGbpkg4yNuUtH0s8rvoYxRCNyT29NVUo6pgPmxI=
github.com/pkg/sftp v1.11.0/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/putdotio/go-putio v0.0.0-20190822121956-19b9c636c877 h1:sKIa5MAIViLAnQbEo+uiDi2FMowy8KcdZW8XZpmyNxs= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/putdotio/go-putio v0.0.0-20190822121956-19b9c636c877/go.mod h1:EWtDL88jJLLWZzywr0QaPO+mGP8gFpvl8dcox8qTk3Y= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/putdotio/go-putio/putio v0.0.0-20200123120452-16d982cac2b8 h1:Y258uzXU/potCYnQd1r6wlAnoMB68BiCkCcCnKx1SH8=
github.com/putdotio/go-putio/putio v0.0.0-20200123120452-16d982cac2b8/go.mod h1:bSJjRokAHHOhA+XFxplld8w2R/dXLH7Z3BZ532vhFwU=
github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46 h1:w2CpS5muK+jyydnmlkqpAhzKmHmMBzBkfYUDjQNS1Dk= github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46 h1:w2CpS5muK+jyydnmlkqpAhzKmHmMBzBkfYUDjQNS1Dk=
github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46/go.mod h1:U2bmx0hDj8EyDdcxmD5t3XHDnBFnyNNc22n1R4008eM= github.com/rfjakob/eme v0.0.0-20171028163933-2222dbd4ba46/go.mod h1:U2bmx0hDj8EyDdcxmD5t3XHDnBFnyNNc22n1R4008eM=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8= github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8=
github.com/sevlyar/go-daemon v0.1.5 h1:Zy/6jLbM8CfqJ4x4RPr7MJlSKt90f00kNM1D401C+Qk= github.com/sevlyar/go-daemon v0.1.5 h1:Zy/6jLbM8CfqJ4x4RPr7MJlSKt90f00kNM1D401C+Qk=
github.com/sevlyar/go-daemon v0.1.5/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE= github.com/sevlyar/go-daemon v0.1.5/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e h1:VAzdS5Nw68fbf5RZ8RDVlUvPXNU6Z3jtPCK/qvm4FoQ= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
github.com/skratchdot/open-golang v0.0.0-20190402232053-79abb63cd66e/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w= github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@ -257,20 +319,25 @@ github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709 h1:Ko2LQMrRU+Oy
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/t3rm1n4l/go-mega v0.0.0-20200117211730-79a813bb328d h1:GsRmok9VXIEc5B6SmRWuuO9hx4x2YBqFqgOXGt9Xs94= github.com/t3rm1n4l/go-mega v0.0.0-20200117211730-79a813bb328d h1:GsRmok9VXIEc5B6SmRWuuO9hx4x2YBqFqgOXGt9Xs94=
github.com/t3rm1n4l/go-mega v0.0.0-20200117211730-79a813bb328d/go.mod h1:XWL4vDyd3JKmJx+hZWUVgCNmmhZ2dTBcaNDcxH465s0= github.com/t3rm1n4l/go-mega v0.0.0-20200117211730-79a813bb328d/go.mod h1:XWL4vDyd3JKmJx+hZWUVgCNmmhZ2dTBcaNDcxH465s0=
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ=
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/youmark/pkcs8 v0.0.0-20191102193632-94c173a94d60 h1:Ud2neINE1YFEwrcJ4EqnbRZlm9R3T8SuFKeqjIw7k44= github.com/youmark/pkcs8 v0.0.0-20191102193632-94c173a94d60 h1:Ud2neINE1YFEwrcJ4EqnbRZlm9R3T8SuFKeqjIw7k44=
github.com/youmark/pkcs8 v0.0.0-20191102193632-94c173a94d60/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/youmark/pkcs8 v0.0.0-20191102193632-94c173a94d60/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yunify/qingstor-sdk-go/v3 v3.1.1 h1:jQkY9N+zSL8h8CqgrDQpXe8/mqJOx8vgGjk6O//RA/4= github.com/yunify/qingstor-sdk-go/v3 v3.2.0 h1:9sB2WZMgjwSUNZhrgvaNGazVltoFUUfuS9f0uCWtTr8=
github.com/yunify/qingstor-sdk-go/v3 v3.1.1/go.mod h1:KciFNuMu6F4WLk9nGwwK69sCGKLCdd9f97ac/wfumS4= github.com/yunify/qingstor-sdk-go/v3 v3.2.0/go.mod h1:KciFNuMu6F4WLk9nGwwK69sCGKLCdd9f97ac/wfumS4=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@ -278,11 +345,14 @@ go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs= go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
goftp.io/server v0.0.0-20190712054601-1149070ae46b/go.mod h1:xreggPYu7ZuNe9PfbxiQca7bYGwU44IvlCCg3KzWJtQ= go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
goftp.io/server v0.0.0-20190812034929-9b3874d17690/go.mod h1:99FISrRpwKfaL4Ey/dX8N48WToveng/s2OXR5sJ3cnc= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
goftp.io/server v0.0.0-20190812052725-72a57b186803 h1:I2IgXYRuOZ6LceE7VY6aSnYuUy6Wot3WFhqI5WsAHXQ= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
goftp.io/server v0.0.0-20190812052725-72a57b186803/go.mod h1:eDjthxa5tFTS2JVry2jHt1g9y3J0Vgu2Nd+lmNWev7Y= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
goftp.io/server v0.3.2 h1:bcsI4ijbvFZkA4rrUtIE/t1jNhT+0uSkiTQ4ASjZAXQ=
goftp.io/server v0.3.2/go.mod h1:wfeAZeQgacupLVl+Ex3ozYFaAGNfCKYZiZNxLzgw6z4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -290,13 +360,17 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200109152110-61a87790db17 h1:nVJ3guKA9qdkEQ3TUdXI9QSINo2CUPM/cySEvw2w8I0= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200109152110-61a87790db17/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -305,14 +379,21 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@ -320,15 +401,23 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190415214537-1da14a5a36f2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190415214537-1da14a5a36f2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191109021931-daa7c04131f5 h1:bHNaocaoJxYBo5cw41UyTMLjYlb8wPY7+WFrnklbHOM= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191109021931-daa7c04131f5/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0 h1:MsuvTghUPjX762sGLnGsxC3HM0B5r83wEtYcYR8/vRs=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -338,8 +427,10 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -351,9 +442,17 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ= golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
@ -363,6 +462,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZe
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -378,17 +478,32 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191010171213-8abd42400456/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM= google.golang.org/api v0.7.0 h1:9sdfJOzWlkqPltHAuzT2Cp+yrBeY1KRVYgms8soxMwM=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0 h1:Q3Ui3V3/CVinFWFiW39Iw0kMuVrRzYX0wN6OPFp0lTA=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0 h1:TgDr+1inK2XVUKZx3BYAqQg/GwucGdBkzZjWaTg/I+A=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -405,33 +520,48 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688 h1:1+0Z5cgv1eDXJD9z2tdQF9PSSQnJXwism490hJydMRI=
google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

84
vendor/bazil.org/fuse/fs/serve.go generated vendored
View file

@ -14,6 +14,7 @@ import (
"runtime" "runtime"
"strings" "strings"
"sync" "sync"
"syscall"
"time" "time"
"bazil.org/fuse" "bazil.org/fuse"
@ -467,7 +468,6 @@ func (sn *serveNode) attr(ctx context.Context, attr *fuse.Attr) error {
type serveHandle struct { type serveHandle struct {
handle Handle handle Handle
readData []byte readData []byte
nodeID fuse.NodeID
} }
// NodeRef is deprecated. It remains here to decrease code churn on // NodeRef is deprecated. It remains here to decrease code churn on
@ -501,9 +501,9 @@ func (c *Server) saveNode(inode uint64, node Node) (id fuse.NodeID, gen uint64)
return id, sn.generation return id, sn.generation
} }
func (c *Server) saveHandle(handle Handle, nodeID fuse.NodeID) (id fuse.HandleID) { func (c *Server) saveHandle(handle Handle) (id fuse.HandleID) {
c.meta.Lock() c.meta.Lock()
shandle := &serveHandle{handle: handle, nodeID: nodeID} shandle := &serveHandle{handle: handle}
if n := len(c.freeHandle); n > 0 { if n := len(c.freeHandle); n > 0 {
id = c.freeHandle[n-1] id = c.freeHandle[n-1]
c.freeHandle = c.freeHandle[:n-1] c.freeHandle = c.freeHandle[:n-1]
@ -756,7 +756,7 @@ func (e handleNotReaderError) Error() string {
var _ fuse.ErrorNumber = handleNotReaderError{} var _ fuse.ErrorNumber = handleNotReaderError{}
func (e handleNotReaderError) Errno() fuse.Errno { func (e handleNotReaderError) Errno() fuse.Errno {
return fuse.ENOTSUP return fuse.Errno(syscall.ENOTSUP)
} }
func initLookupResponse(s *fuse.LookupResponse) { func initLookupResponse(s *fuse.LookupResponse) {
@ -788,10 +788,11 @@ func (c *Server) serve(r fuse.Request) {
} }
if snode == nil { if snode == nil {
c.meta.Unlock() c.meta.Unlock()
err := syscall.ESTALE
c.debug(response{ c.debug(response{
Op: opName(r), Op: opName(r),
Request: logResponseHeader{ID: hdr.ID}, Request: logResponseHeader{ID: hdr.ID},
Error: fuse.ESTALE.ErrnoName(), Error: fuse.Errno(err).ErrnoName(),
// this is the only place that sets both Error and // this is the only place that sets both Error and
// Out; not sure if i want to do that; might get rid // Out; not sure if i want to do that; might get rid
// of len(c.node) things altogether // of len(c.node) things altogether
@ -799,7 +800,7 @@ func (c *Server) serve(r fuse.Request) {
MaxNode: fuse.NodeID(len(c.node)), MaxNode: fuse.NodeID(len(c.node)),
}, },
}) })
r.RespondError(fuse.ESTALE) r.RespondError(err)
return return
} }
node = snode.node node = snode.node
@ -824,17 +825,12 @@ func (c *Server) serve(r fuse.Request) {
Request: logResponseHeader{ID: hdr.ID}, Request: logResponseHeader{ID: hdr.ID},
} }
if err, ok := resp.(error); ok { if err, ok := resp.(error); ok {
msg.Error = err.Error() errno := fuse.ToErrno(err)
if ferr, ok := err.(fuse.ErrorNumber); ok { msg.Errno = errno.ErrnoName()
errno := ferr.Errno() if errno != err && syscall.Errno(errno) != err {
msg.Errno = errno.ErrnoName() // if it's more than just a fuse.Errno or a
if errno == err { // syscall.Errno, log extra detail
// it's just a fuse.Errno with no extra detail; msg.Error = err.Error()
// skip the textual message for log readability
msg.Error = ""
}
} else {
msg.Errno = fuse.DefaultErrno.ErrnoName()
} }
} else { } else {
msg.Out = resp msg.Out = resp
@ -887,7 +883,7 @@ func (c *Server) serve(r fuse.Request) {
// //
// Decent write-up on role of EINTR: // Decent write-up on role of EINTR:
// http://250bpm.com/blog:12 // http://250bpm.com/blog:12
err = fuse.EINTR err = syscall.EINTR
default: default:
// nothing // nothing
} }
@ -907,7 +903,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
// Note: To FUSE, ENOSYS means "this server never implements this request." // Note: To FUSE, ENOSYS means "this server never implements this request."
// It would be inappropriate to return ENOSYS for other operations in this // It would be inappropriate to return ENOSYS for other operations in this
// switch that might only be unavailable in some contexts, not all. // switch that might only be unavailable in some contexts, not all.
return fuse.ENOSYS return syscall.ENOSYS
case *fuse.StatfsRequest: case *fuse.StatfsRequest:
s := &fuse.StatfsResponse{} s := &fuse.StatfsResponse{}
@ -956,7 +952,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
initLookupResponse(&s.LookupResponse) initLookupResponse(&s.LookupResponse)
n, ok := node.(NodeSymlinker) n, ok := node.(NodeSymlinker)
if !ok { if !ok {
return fuse.EIO // XXX or EPERM like Mkdir? return syscall.EIO // XXX or EPERM like Mkdir?
} }
n2, err := n.Symlink(ctx, r) n2, err := n.Symlink(ctx, r)
if err != nil { if err != nil {
@ -972,7 +968,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
case *fuse.ReadlinkRequest: case *fuse.ReadlinkRequest:
n, ok := node.(NodeReadlinker) n, ok := node.(NodeReadlinker)
if !ok { if !ok {
return fuse.EIO /// XXX or EPERM? return syscall.EIO /// XXX or EPERM?
} }
target, err := n.Readlink(ctx, r) target, err := n.Readlink(ctx, r)
if err != nil { if err != nil {
@ -985,7 +981,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
case *fuse.LinkRequest: case *fuse.LinkRequest:
n, ok := node.(NodeLinker) n, ok := node.(NodeLinker)
if !ok { if !ok {
return fuse.EIO /// XXX or EPERM? return syscall.EIO /// XXX or EPERM?
} }
c.meta.Lock() c.meta.Lock()
var oldNode *serveNode var oldNode *serveNode
@ -998,7 +994,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
Request: r.Hdr(), Request: r.Hdr(),
In: r, In: r,
}) })
return fuse.EIO return syscall.EIO
} }
n2, err := n.Link(ctx, r, oldNode.node) n2, err := n.Link(ctx, r, oldNode.node)
if err != nil { if err != nil {
@ -1016,7 +1012,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
case *fuse.RemoveRequest: case *fuse.RemoveRequest:
n, ok := node.(NodeRemover) n, ok := node.(NodeRemover)
if !ok { if !ok {
return fuse.EIO /// XXX or EPERM? return syscall.EIO /// XXX or EPERM?
} }
err := n.Remove(ctx, r) err := n.Remove(ctx, r)
if err != nil { if err != nil {
@ -1046,7 +1042,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
} else if n, ok := node.(NodeRequestLookuper); ok { } else if n, ok := node.(NodeRequestLookuper); ok {
n2, err = n.Lookup(ctx, r, s) n2, err = n.Lookup(ctx, r, s)
} else { } else {
return fuse.ENOENT return syscall.ENOENT
} }
if err != nil { if err != nil {
return err return err
@ -1063,7 +1059,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
initLookupResponse(&s.LookupResponse) initLookupResponse(&s.LookupResponse)
n, ok := node.(NodeMkdirer) n, ok := node.(NodeMkdirer)
if !ok { if !ok {
return fuse.EPERM return syscall.EPERM
} }
n2, err := n.Mkdir(ctx, r) n2, err := n.Mkdir(ctx, r)
if err != nil { if err != nil {
@ -1088,7 +1084,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
} else { } else {
h2 = node h2 = node
} }
s.Handle = c.saveHandle(h2, r.Hdr().Node) s.Handle = c.saveHandle(h2)
done(s) done(s)
r.Respond(s) r.Respond(s)
return nil return nil
@ -1097,7 +1093,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
n, ok := node.(NodeCreater) n, ok := node.(NodeCreater)
if !ok { if !ok {
// If we send back ENOSYS, FUSE will try mknod+open. // If we send back ENOSYS, FUSE will try mknod+open.
return fuse.EPERM return syscall.EPERM
} }
s := &fuse.CreateResponse{OpenResponse: fuse.OpenResponse{}} s := &fuse.CreateResponse{OpenResponse: fuse.OpenResponse{}}
initLookupResponse(&s.LookupResponse) initLookupResponse(&s.LookupResponse)
@ -1108,7 +1104,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.Name, n2); err != nil { if err := c.saveLookup(ctx, &s.LookupResponse, snode, r.Name, n2); err != nil {
return err return err
} }
s.Handle = c.saveHandle(h2, r.Hdr().Node) s.Handle = c.saveHandle(h2)
done(s) done(s)
r.Respond(s) r.Respond(s)
return nil return nil
@ -1116,7 +1112,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
case *fuse.GetxattrRequest: case *fuse.GetxattrRequest:
n, ok := node.(NodeGetxattrer) n, ok := node.(NodeGetxattrer)
if !ok { if !ok {
return fuse.ENOTSUP return syscall.ENOTSUP
} }
s := &fuse.GetxattrResponse{} s := &fuse.GetxattrResponse{}
err := n.Getxattr(ctx, r, s) err := n.Getxattr(ctx, r, s)
@ -1124,7 +1120,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
return err return err
} }
if r.Size != 0 && uint64(len(s.Xattr)) > uint64(r.Size) { if r.Size != 0 && uint64(len(s.Xattr)) > uint64(r.Size) {
return fuse.ERANGE return syscall.ERANGE
} }
done(s) done(s)
r.Respond(s) r.Respond(s)
@ -1133,7 +1129,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
case *fuse.ListxattrRequest: case *fuse.ListxattrRequest:
n, ok := node.(NodeListxattrer) n, ok := node.(NodeListxattrer)
if !ok { if !ok {
return fuse.ENOTSUP return syscall.ENOTSUP
} }
s := &fuse.ListxattrResponse{} s := &fuse.ListxattrResponse{}
err := n.Listxattr(ctx, r, s) err := n.Listxattr(ctx, r, s)
@ -1141,7 +1137,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
return err return err
} }
if r.Size != 0 && uint64(len(s.Xattr)) > uint64(r.Size) { if r.Size != 0 && uint64(len(s.Xattr)) > uint64(r.Size) {
return fuse.ERANGE return syscall.ERANGE
} }
done(s) done(s)
r.Respond(s) r.Respond(s)
@ -1150,7 +1146,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
case *fuse.SetxattrRequest: case *fuse.SetxattrRequest:
n, ok := node.(NodeSetxattrer) n, ok := node.(NodeSetxattrer)
if !ok { if !ok {
return fuse.ENOTSUP return syscall.ENOTSUP
} }
err := n.Setxattr(ctx, r) err := n.Setxattr(ctx, r)
if err != nil { if err != nil {
@ -1163,7 +1159,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
case *fuse.RemovexattrRequest: case *fuse.RemovexattrRequest:
n, ok := node.(NodeRemovexattrer) n, ok := node.(NodeRemovexattrer)
if !ok { if !ok {
return fuse.ENOTSUP return syscall.ENOTSUP
} }
err := n.Removexattr(ctx, r) err := n.Removexattr(ctx, r)
if err != nil { if err != nil {
@ -1189,7 +1185,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
case *fuse.ReadRequest: case *fuse.ReadRequest:
shandle := c.getHandle(r.Handle) shandle := c.getHandle(r.Handle)
if shandle == nil { if shandle == nil {
return fuse.ESTALE return syscall.ESTALE
} }
handle := shandle.handle handle := shandle.handle
@ -1254,7 +1250,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
case *fuse.WriteRequest: case *fuse.WriteRequest:
shandle := c.getHandle(r.Handle) shandle := c.getHandle(r.Handle)
if shandle == nil { if shandle == nil {
return fuse.ESTALE return syscall.ESTALE
} }
s := &fuse.WriteResponse{} s := &fuse.WriteResponse{}
@ -1266,12 +1262,12 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
r.Respond(s) r.Respond(s)
return nil return nil
} }
return fuse.EIO return syscall.EIO
case *fuse.FlushRequest: case *fuse.FlushRequest:
shandle := c.getHandle(r.Handle) shandle := c.getHandle(r.Handle)
if shandle == nil { if shandle == nil {
return fuse.ESTALE return syscall.ESTALE
} }
handle := shandle.handle handle := shandle.handle
@ -1287,7 +1283,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
case *fuse.ReleaseRequest: case *fuse.ReleaseRequest:
shandle := c.getHandle(r.Handle) shandle := c.getHandle(r.Handle)
if shandle == nil { if shandle == nil {
return fuse.ESTALE return syscall.ESTALE
} }
handle := shandle.handle handle := shandle.handle
@ -1323,11 +1319,11 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
Request: r.Hdr(), Request: r.Hdr(),
In: r, In: r,
}) })
return fuse.EIO return syscall.EIO
} }
n, ok := node.(NodeRenamer) n, ok := node.(NodeRenamer)
if !ok { if !ok {
return fuse.EIO // XXX or EPERM like Mkdir? return syscall.EIO // XXX or EPERM like Mkdir?
} }
err := n.Rename(ctx, r, newDirNode.node) err := n.Rename(ctx, r, newDirNode.node)
if err != nil { if err != nil {
@ -1340,7 +1336,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
case *fuse.MknodRequest: case *fuse.MknodRequest:
n, ok := node.(NodeMknoder) n, ok := node.(NodeMknoder)
if !ok { if !ok {
return fuse.EIO return syscall.EIO
} }
n2, err := n.Mknod(ctx, r) n2, err := n.Mknod(ctx, r)
if err != nil { if err != nil {
@ -1358,7 +1354,7 @@ func (c *Server) handleRequest(ctx context.Context, node Node, snode *serveNode,
case *fuse.FsyncRequest: case *fuse.FsyncRequest:
n, ok := node.(NodeFsyncer) n, ok := node.(NodeFsyncer)
if !ok { if !ok {
return fuse.EIO return syscall.EIO
} }
err := n.Fsync(ctx, r) err := n.Fsync(ctx, r)
if err != nil { if err != nil {

3
vendor/bazil.org/fuse/fs/tree.go generated vendored
View file

@ -7,6 +7,7 @@ import (
"os" "os"
pathpkg "path" pathpkg "path"
"strings" "strings"
"syscall"
"bazil.org/fuse" "bazil.org/fuse"
) )
@ -84,7 +85,7 @@ func (t *tree) Lookup(ctx context.Context, name string) (Node, error) {
if n != nil { if n != nil {
return n, nil return n, nil
} }
return nil, fuse.ENOENT return nil, syscall.ENOENT
} }
func (t *tree) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) { func (t *tree) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {

48
vendor/bazil.org/fuse/fuse.go generated vendored
View file

@ -79,7 +79,7 @@
// is cancelled and no longer needed, the context will be cancelled. // is cancelled and no longer needed, the context will be cancelled.
// Blocking operations should select on a receive from ctx.Done() and attempt to // Blocking operations should select on a receive from ctx.Done() and attempt to
// abort the operation early if the receive succeeds (meaning the channel is closed). // abort the operation early if the receive succeeds (meaning the channel is closed).
// To indicate that the operation failed because it was aborted, return fuse.EINTR. // To indicate that the operation failed because it was aborted, return syscall.EINTR.
// //
// If an operation does not block for an indefinite amount of time, supporting // If an operation does not block for an indefinite amount of time, supporting
// cancellation is not necessary. // cancellation is not necessary.
@ -90,8 +90,8 @@
// inspect req.Pid, req.Uid, and req.Gid as necessary to implement // inspect req.Pid, req.Uid, and req.Gid as necessary to implement
// permission checking. The kernel FUSE layer normally prevents other // permission checking. The kernel FUSE layer normally prevents other
// users from accessing the FUSE file system (to change this, see // users from accessing the FUSE file system (to change this, see
// AllowOther, AllowRoot), but does not enforce access modes (to // AllowOther), but does not enforce access modes (to change this, see
// change this, see DefaultPermissions). // DefaultPermissions).
// //
// Mount Options // Mount Options
// //
@ -323,6 +323,8 @@ type ErrorNumber interface {
Errno() Errno Errno() Errno
} }
// Deprecated: Return a syscall.Errno directly. See ToErrno for exact
// rules.
const ( const (
// ENOSYS indicates that the call is not supported. // ENOSYS indicates that the call is not supported.
ENOSYS = Errno(syscall.ENOSYS) ENOSYS = Errno(syscall.ENOSYS)
@ -348,13 +350,14 @@ const (
const DefaultErrno = EIO const DefaultErrno = EIO
var errnoNames = map[Errno]string{ var errnoNames = map[Errno]string{
ENOSYS: "ENOSYS", ENOSYS: "ENOSYS",
ESTALE: "ESTALE", ESTALE: "ESTALE",
ENOENT: "ENOENT", ENOENT: "ENOENT",
EIO: "EIO", EIO: "EIO",
EPERM: "EPERM", EPERM: "EPERM",
EINTR: "EINTR", EINTR: "EINTR",
EEXIST: "EEXIST", EEXIST: "EEXIST",
Errno(syscall.ENAMETOOLONG): "ENAMETOOLONG",
} }
// Errno implements Error and ErrorNumber using a syscall.Errno. // Errno implements Error and ErrorNumber using a syscall.Errno.
@ -390,11 +393,28 @@ func (e Errno) MarshalText() ([]byte, error) {
return []byte(s), nil return []byte(s), nil
} }
func (h *Header) RespondError(err error) { // ToErrno converts arbitrary errors to Errno.
errno := DefaultErrno //
if ferr, ok := err.(ErrorNumber); ok { // If the underlying type of err is syscall.Errno, it is used
errno = ferr.Errno() // directly. No unwrapping is done, to prevent wrong errors from
// leaking via e.g. *os.PathError.
//
// If err unwraps to implement ErrorNumber, that is used.
//
// Finally, returns DefaultErrno.
func ToErrno(err error) Errno {
if err, ok := err.(syscall.Errno); ok {
return Errno(err)
} }
var errnum ErrorNumber
if errors.As(err, &errnum) {
return Errno(errnum.Errno())
}
return DefaultErrno
}
func (h *Header) RespondError(err error) {
errno := ToErrno(err)
// FUSE uses negative errors! // FUSE uses negative errors!
// TODO: File bug report against OSXFUSE: positive error causes kernel panic. // TODO: File bug report against OSXFUSE: positive error causes kernel panic.
buf := newBuffer(0) buf := newBuffer(0)

View file

@ -633,8 +633,6 @@ func (fl WriteFlags) String() string {
return flagString(uint32(fl), writeFlagNames) return flagString(uint32(fl), writeFlagNames)
} }
const compatStatfsSize = 48
type statfsOut struct { type statfsOut struct {
St kstatfs St kstatfs
} }

25
vendor/bazil.org/fuse/options.go generated vendored
View file

@ -148,37 +148,14 @@ func DaemonTimeout(name string) MountOption {
return daemonTimeout(name) return daemonTimeout(name)
} }
var ErrCannotCombineAllowOtherAndAllowRoot = errors.New("cannot combine AllowOther and AllowRoot")
// AllowOther allows other users to access the file system. // AllowOther allows other users to access the file system.
//
// Only one of AllowOther or AllowRoot can be used.
func AllowOther() MountOption { func AllowOther() MountOption {
return func(conf *mountConfig) error { return func(conf *mountConfig) error {
if _, ok := conf.options["allow_root"]; ok {
return ErrCannotCombineAllowOtherAndAllowRoot
}
conf.options["allow_other"] = "" conf.options["allow_other"] = ""
return nil return nil
} }
} }
// AllowRoot allows root (but not just everyone) to access the file
// system.
//
// Only one of AllowOther or AllowRoot can be used.
//
// FreeBSD ignores this option.
func AllowRoot() MountOption {
return func(conf *mountConfig) error {
if _, ok := conf.options["allow_other"]; ok {
return ErrCannotCombineAllowOtherAndAllowRoot
}
conf.options["allow_root"] = ""
return nil
}
}
// AllowDev enables interpreting character or block special devices on the // AllowDev enables interpreting character or block special devices on the
// filesystem. // filesystem.
func AllowDev() MountOption { func AllowDev() MountOption {
@ -202,7 +179,7 @@ func AllowSUID() MountOption {
// //
// Without this option, the Node itself decides what is and is not // Without this option, the Node itself decides what is and is not
// allowed. This is normally ok because FUSE file systems cannot be // allowed. This is normally ok because FUSE file systems cannot be
// accessed by other users without AllowOther/AllowRoot. // accessed by other users without AllowOther.
// //
// FreeBSD ignores this option. // FreeBSD ignores this option.
func DefaultPermissions() MountOption { func DefaultPermissions() MountOption {

View file

@ -1,12 +0,0 @@
{
"name": "metadata",
"name_pretty": "Google Compute Engine Metadata API",
"product_documentation": "https://cloud.google.com/compute/docs/storing-retrieving-metadata",
"client_documentation": "https://godoc.org/cloud.google.com/go/compute/metadata",
"release_level": "ga",
"language": "go",
"repo": "googleapis/google-cloud-go",
"distribution_name": "cloud.google.com/go/compute/metadata",
"api_id": "compute:metadata",
"requires_billing": false
}

View file

@ -68,7 +68,6 @@ var (
Timeout: 2 * time.Second, Timeout: 2 * time.Second,
KeepAlive: 30 * time.Second, KeepAlive: 30 * time.Second,
}).Dial, }).Dial,
ResponseHeaderTimeout: 2 * time.Second,
}, },
}} }}
subscribeClient = &Client{hc: &http.Client{ subscribeClient = &Client{hc: &http.Client{
@ -304,7 +303,10 @@ func (c *Client) getETag(suffix string) (value, etag string, err error) {
host = metadataIP host = metadataIP
} }
u := "http://" + host + "/computeMetadata/v1/" + suffix u := "http://" + host + "/computeMetadata/v1/" + suffix
req, _ := http.NewRequest("GET", u, nil) req, err := http.NewRequest("GET", u, nil)
if err != nil {
return "", "", err
}
req.Header.Set("Metadata-Flavor", "Google") req.Header.Set("Metadata-Flavor", "Google")
req.Header.Set("User-Agent", userAgent) req.Header.Set("User-Agent", userAgent)
res, err := c.hc.Do(req) res, err := c.hc.Do(req)
@ -407,11 +409,7 @@ func (c *Client) InstanceTags() ([]string, error) {
// InstanceName returns the current VM's instance ID string. // InstanceName returns the current VM's instance ID string.
func (c *Client) InstanceName() (string, error) { func (c *Client) InstanceName() (string, error) {
host, err := c.Hostname() return c.getTrimmed("instance/name")
if err != nil {
return "", err
}
return strings.Split(host, ".")[0], nil
} }
// Zone returns the current VM's zone, such as "us-central1-b". // Zone returns the current VM's zone, such as "us-central1-b".

View file

@ -1,4 +1,4 @@
goconfig [![Build Status](https://drone.io/github.com/Unknwon/goconfig/status.png)](https://drone.io/github.com/Unknwon/goconfig/latest) [![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/Unknwon/goconfig) goconfig [![Go Walker](http://gowalker.org/api/v1/badge)](http://gowalker.org/github.com/Unknwon/goconfig)
======== ========
[中文文档](README_ZH.md) [中文文档](README_ZH.md)
@ -26,15 +26,11 @@ The configuration file consists of sections, led by a `[section]` header and fol
## Installation ## Installation
go get github.com/Unknwon/goconfig go get github.com/unknwon/goconfig
Or
gopm get github.com/Unknwon/goconfig
## API Documentation ## API Documentation
[Go Walker](http://gowalker.org/github.com/Unknwon/goconfig). [Go Walker](http://gowalker.org/github.com/unknwon/goconfig).
## Example ## Example

View file

@ -1,45 +0,0 @@
package upnpav
import (
"encoding/xml"
)
const (
NoSuchObjectErrorCode = 701
)
type Resource struct {
XMLName xml.Name `xml:"res"`
ProtocolInfo string `xml:"protocolInfo,attr"`
URL string `xml:",chardata"`
Size uint64 `xml:"size,attr,omitempty"`
Bitrate uint `xml:"bitrate,attr,omitempty"`
Duration string `xml:"duration,attr,omitempty"`
Resolution string `xml:"resolution,attr,omitempty"`
}
type Container struct {
Object
XMLName xml.Name `xml:"container"`
ChildCount int `xml:"childCount,attr"`
}
type Item struct {
Object
XMLName xml.Name `xml:"item"`
Res []Resource
}
type Object struct {
ID string `xml:"id,attr"`
ParentID string `xml:"parentID,attr"`
Restricted int `xml:"restricted,attr"` // indicates whether the object is modifiable
Class string `xml:"upnp:class"`
Icon string `xml:"upnp:icon,omitempty"`
Title string `xml:"dc:title"`
Artist string `xml:"upnp:artist,omitempty"`
Album string `xml:"upnp:album,omitempty"`
Genre string `xml:"upnp:genre,omitempty"`
AlbumArtURI string `xml:"upnp:albumArtURI,omitempty"`
Searchable int `xml:"searchable,attr"`
}

93
vendor/github.com/aws/aws-sdk-go/aws/arn/arn.go generated vendored Normal file
View file

@ -0,0 +1,93 @@
// Package arn provides a parser for interacting with Amazon Resource Names.
package arn
import (
"errors"
"strings"
)
const (
arnDelimiter = ":"
arnSections = 6
arnPrefix = "arn:"
// zero-indexed
sectionPartition = 1
sectionService = 2
sectionRegion = 3
sectionAccountID = 4
sectionResource = 5
// errors
invalidPrefix = "arn: invalid prefix"
invalidSections = "arn: not enough sections"
)
// ARN captures the individual fields of an Amazon Resource Name.
// See http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html for more information.
type ARN struct {
// The partition that the resource is in. For standard AWS regions, the partition is "aws". If you have resources in
// other partitions, the partition is "aws-partitionname". For example, the partition for resources in the China
// (Beijing) region is "aws-cn".
Partition string
// The service namespace that identifies the AWS product (for example, Amazon S3, IAM, or Amazon RDS). For a list of
// namespaces, see
// http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-aws-service-namespaces.
Service string
// The region the resource resides in. Note that the ARNs for some resources do not require a region, so this
// component might be omitted.
Region string
// The ID of the AWS account that owns the resource, without the hyphens. For example, 123456789012. Note that the
// ARNs for some resources don't require an account number, so this component might be omitted.
AccountID string
// The content of this part of the ARN varies by service. It often includes an indicator of the type of resource —
// for example, an IAM user or Amazon RDS database - followed by a slash (/) or a colon (:), followed by the
// resource name itself. Some services allows paths for resource names, as described in
// http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arns-paths.
Resource string
}
// Parse parses an ARN into its constituent parts.
//
// Some example ARNs:
// arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment
// arn:aws:iam::123456789012:user/David
// arn:aws:rds:eu-west-1:123456789012:db:mysql-db
// arn:aws:s3:::my_corporate_bucket/exampleobject.png
func Parse(arn string) (ARN, error) {
if !strings.HasPrefix(arn, arnPrefix) {
return ARN{}, errors.New(invalidPrefix)
}
sections := strings.SplitN(arn, arnDelimiter, arnSections)
if len(sections) != arnSections {
return ARN{}, errors.New(invalidSections)
}
return ARN{
Partition: sections[sectionPartition],
Service: sections[sectionService],
Region: sections[sectionRegion],
AccountID: sections[sectionAccountID],
Resource: sections[sectionResource],
}, nil
}
// IsARN returns whether the given string is an ARN by looking for
// whether the string starts with "arn:" and contains the correct number
// of sections delimited by colons(:).
func IsARN(arn string) bool {
return strings.HasPrefix(arn, arnPrefix) && strings.Count(arn, ":") >= arnSections-1
}
// String returns the canonical representation of the ARN
func (arn ARN) String() string {
return arnPrefix +
arn.Partition + arnDelimiter +
arn.Service + arnDelimiter +
arn.Region + arnDelimiter +
arn.AccountID + arnDelimiter +
arn.Resource
}

View file

@ -70,7 +70,7 @@ func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTer
value = value.FieldByNameFunc(func(name string) bool { value = value.FieldByNameFunc(func(name string) bool {
if c == name { if c == name {
return true return true
} else if !caseSensitive && strings.ToLower(name) == strings.ToLower(c) { } else if !caseSensitive && strings.EqualFold(name, c) {
return true return true
} }
return false return false

View file

@ -161,6 +161,17 @@ type Config struct {
// on GetObject API calls. // on GetObject API calls.
S3DisableContentMD5Validation *bool S3DisableContentMD5Validation *bool
// Set this to `true` to have the S3 service client to use the region specified
// in the ARN, when an ARN is provided as an argument to a bucket parameter.
S3UseARNRegion *bool
// Set this to `true` to enable the SDK to unmarshal API response header maps to
// normalized lower case map keys.
//
// For example S3's X-Amz-Meta prefixed header will be unmarshaled to lower case
// Metadata member's map keys. The value of the header in the map is unaffected.
LowerCaseHeaderMaps *bool
// Set this to `true` to disable the EC2Metadata client from overriding the // 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 // 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 // EC2Metadata client to create a new http.Client. This options is only
@ -249,6 +260,9 @@ type Config struct {
// STSRegionalEndpoint will enable regional or legacy endpoint resolving // STSRegionalEndpoint will enable regional or legacy endpoint resolving
STSRegionalEndpoint endpoints.STSRegionalEndpoint STSRegionalEndpoint endpoints.STSRegionalEndpoint
// S3UsEast1RegionalEndpoint will enable regional or legacy endpoint resolving
S3UsEast1RegionalEndpoint endpoints.S3UsEast1RegionalEndpoint
} }
// NewConfig returns a new Config pointer that can be chained with builder // NewConfig returns a new Config pointer that can be chained with builder
@ -382,6 +396,13 @@ func (c *Config) WithS3DisableContentMD5Validation(enable bool) *Config {
} }
// WithS3UseARNRegion sets a config S3UseARNRegion value and
// returning a Config pointer for chaining
func (c *Config) WithS3UseARNRegion(enable bool) *Config {
c.S3UseARNRegion = &enable
return c
}
// WithUseDualStack sets a config UseDualStack value returning a Config // WithUseDualStack sets a config UseDualStack value returning a Config
// pointer for chaining. // pointer for chaining.
func (c *Config) WithUseDualStack(enable bool) *Config { func (c *Config) WithUseDualStack(enable bool) *Config {
@ -430,6 +451,13 @@ func (c *Config) WithSTSRegionalEndpoint(sre endpoints.STSRegionalEndpoint) *Con
return c return c
} }
// WithS3UsEast1RegionalEndpoint will set whether or not to use regional endpoint flag
// when resolving the endpoint for a service
func (c *Config) WithS3UsEast1RegionalEndpoint(sre endpoints.S3UsEast1RegionalEndpoint) *Config {
c.S3UsEast1RegionalEndpoint = sre
return c
}
func mergeInConfig(dst *Config, other *Config) { func mergeInConfig(dst *Config, other *Config) {
if other == nil { if other == nil {
return return
@ -503,6 +531,10 @@ func mergeInConfig(dst *Config, other *Config) {
dst.S3DisableContentMD5Validation = other.S3DisableContentMD5Validation dst.S3DisableContentMD5Validation = other.S3DisableContentMD5Validation
} }
if other.S3UseARNRegion != nil {
dst.S3UseARNRegion = other.S3UseARNRegion
}
if other.UseDualStack != nil { if other.UseDualStack != nil {
dst.UseDualStack = other.UseDualStack dst.UseDualStack = other.UseDualStack
} }
@ -534,6 +566,10 @@ func mergeInConfig(dst *Config, other *Config) {
if other.STSRegionalEndpoint != endpoints.UnsetSTSEndpoint { if other.STSRegionalEndpoint != endpoints.UnsetSTSEndpoint {
dst.STSRegionalEndpoint = other.STSRegionalEndpoint dst.STSRegionalEndpoint = other.STSRegionalEndpoint
} }
if other.S3UsEast1RegionalEndpoint != endpoints.UnsetS3UsEast1Endpoint {
dst.S3UsEast1RegionalEndpoint = other.S3UsEast1RegionalEndpoint
}
} }
// Copy will return a shallow copy of the Config object. If any additional // Copy will return a shallow copy of the Config object. If any additional

View file

@ -2,42 +2,8 @@
package aws package aws
import "time" import (
"github.com/aws/aws-sdk-go/internal/context"
// An emptyCtx is a copy of the Go 1.7 context.emptyCtx type. This is copied to
// provide a 1.6 and 1.5 safe version of context that is compatible with Go
// 1.7's Context.
//
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
// struct{}, since vars of this type must have distinct addresses.
type emptyCtx int
func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
return
}
func (*emptyCtx) Done() <-chan struct{} {
return nil
}
func (*emptyCtx) Err() error {
return nil
}
func (*emptyCtx) Value(key interface{}) interface{} {
return nil
}
func (e *emptyCtx) String() string {
switch e {
case backgroundCtx:
return "aws.BackgroundContext"
}
return "unknown empty Context"
}
var (
backgroundCtx = new(emptyCtx)
) )
// BackgroundContext returns a context that will never be canceled, has no // BackgroundContext returns a context that will never be canceled, has no
@ -52,5 +18,5 @@ var (
// //
// See https://golang.org/pkg/context for more information on Contexts. // See https://golang.org/pkg/context for more information on Contexts.
func BackgroundContext() Context { func BackgroundContext() Context {
return backgroundCtx return context.BackgroundCtx
} }

View file

@ -161,7 +161,7 @@ func handleSendError(r *request.Request, err error) {
} }
// Catch all request errors, and let the default retrier determine // Catch all request errors, and let the default retrier determine
// if the error is retryable. // if the error is retryable.
r.Error = awserr.New("RequestError", "send request failed", err) r.Error = awserr.New(request.ErrCodeRequestError, "send request failed", err)
// Override the error with a context canceled error, if that was canceled. // Override the error with a context canceled error, if that was canceled.
ctx := r.Context() ctx := r.Context()

View file

@ -0,0 +1,22 @@
// +build !go1.7
package credentials
import (
"github.com/aws/aws-sdk-go/internal/context"
)
// backgroundContext returns a context that will never be canceled, has no
// values, and no deadline. This context is used by the SDK to provide
// backwards compatibility with non-context API operations and functionality.
//
// Go 1.6 and before:
// This context function is equivalent to context.Background in the Go stdlib.
//
// Go 1.7 and later:
// The context returned will be the value returned by context.Background()
//
// See https://golang.org/pkg/context for more information on Contexts.
func backgroundContext() Context {
return context.BackgroundCtx
}

View file

@ -0,0 +1,20 @@
// +build go1.7
package credentials
import "context"
// backgroundContext returns a context that will never be canceled, has no
// values, and no deadline. This context is used by the SDK to provide
// backwards compatibility with non-context API operations and functionality.
//
// Go 1.6 and before:
// This context function is equivalent to context.Background in the Go stdlib.
//
// Go 1.7 and later:
// The context returned will be the value returned by context.Background()
//
// See https://golang.org/pkg/context for more information on Contexts.
func backgroundContext() Context {
return context.Background()
}

View file

@ -0,0 +1,39 @@
// +build !go1.9
package credentials
import "time"
// Context is an copy of the Go v1.7 stdlib's context.Context interface.
// It is represented as a SDK interface to enable you to use the "WithContext"
// API methods with Go v1.6 and a Context type such as golang.org/x/net/context.
//
// This type, aws.Context, and context.Context are equivalent.
//
// See https://golang.org/pkg/context on how to use contexts.
type Context interface {
// Deadline returns the time when work done on behalf of this context
// should be canceled. Deadline returns ok==false when no deadline is
// set. Successive calls to Deadline return the same results.
Deadline() (deadline time.Time, ok bool)
// Done returns a channel that's closed when work done on behalf of this
// context should be canceled. Done may return nil if this context can
// never be canceled. Successive calls to Done return the same value.
Done() <-chan struct{}
// Err returns a non-nil error value after Done is closed. Err returns
// Canceled if the context was canceled or DeadlineExceeded if the
// context's deadline passed. No other values for Err are defined.
// After Done is closed, successive calls to Err return the same value.
Err() error
// Value returns the value associated with this context for key, or nil
// if no value is associated with key. Successive calls to Value with
// the same key returns the same result.
//
// Use context values only for request-scoped data that transits
// processes and API boundaries, not for passing optional parameters to
// functions.
Value(key interface{}) interface{}
}

View file

@ -0,0 +1,13 @@
// +build go1.9
package credentials
import "context"
// Context is an alias of the Go stdlib's context.Context interface.
// It can be used within the SDK's API operation "WithContext" methods.
//
// This type, aws.Context, and context.Context are equivalent.
//
// See https://golang.org/pkg/context on how to use contexts.
type Context = context.Context

View file

@ -50,10 +50,11 @@ package credentials
import ( import (
"fmt" "fmt"
"sync" "sync/atomic"
"time" "time"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/internal/sync/singleflight"
) )
// AnonymousCredentials is an empty Credential object that can be used as // AnonymousCredentials is an empty Credential object that can be used as
@ -197,20 +198,62 @@ func (e *Expiry) ExpiresAt() time.Time {
// first instance of the credentials Value. All calls to Get() after that // first instance of the credentials Value. All calls to Get() after that
// will return the cached credentials Value until IsExpired() returns true. // will return the cached credentials Value until IsExpired() returns true.
type Credentials struct { type Credentials struct {
creds Value creds atomic.Value
forceRefresh bool sf singleflight.Group
m sync.RWMutex
provider Provider provider Provider
} }
// NewCredentials returns a pointer to a new Credentials with the provider set. // NewCredentials returns a pointer to a new Credentials with the provider set.
func NewCredentials(provider Provider) *Credentials { func NewCredentials(provider Provider) *Credentials {
return &Credentials{ c := &Credentials{
provider: provider, provider: provider,
forceRefresh: true,
} }
c.creds.Store(Value{})
return c
}
// GetWithContext returns the credentials value, or error if the credentials
// Value failed to be retrieved. Will return early if the passed in context is
// canceled.
//
// Will return the cached credentials Value if it has not expired. If the
// credentials Value has expired the Provider's Retrieve() will be called
// to refresh the credentials.
//
// If Credentials.Expire() was called the credentials Value will be force
// expired, and the next call to Get() will cause them to be refreshed.
//
// Passed in Context is equivalent to aws.Context, and context.Context.
func (c *Credentials) GetWithContext(ctx Context) (Value, error) {
if curCreds := c.creds.Load(); !c.isExpired(curCreds) {
return curCreds.(Value), nil
}
// Cannot pass context down to the actual retrieve, because the first
// context would cancel the whole group when there is not direct
// association of items in the group.
resCh := c.sf.DoChan("", c.singleRetrieve)
select {
case res := <-resCh:
return res.Val.(Value), res.Err
case <-ctx.Done():
return Value{}, awserr.New("RequestCanceled",
"request context canceled", ctx.Err())
}
}
func (c *Credentials) singleRetrieve() (interface{}, error) {
if curCreds := c.creds.Load(); !c.isExpired(curCreds) {
return curCreds.(Value), nil
}
creds, err := c.provider.Retrieve()
if err == nil {
c.creds.Store(creds)
}
return creds, err
} }
// Get returns the credentials value, or error if the credentials Value failed // Get returns the credentials value, or error if the credentials Value failed
@ -223,30 +266,7 @@ func NewCredentials(provider Provider) *Credentials {
// If Credentials.Expire() was called the credentials Value will be force // If Credentials.Expire() was called the credentials Value will be force
// expired, and the next call to Get() will cause them to be refreshed. // expired, and the next call to Get() will cause them to be refreshed.
func (c *Credentials) Get() (Value, error) { func (c *Credentials) Get() (Value, error) {
// Check the cached credentials first with just the read lock. return c.GetWithContext(backgroundContext())
c.m.RLock()
if !c.isExpired() {
creds := c.creds
c.m.RUnlock()
return creds, nil
}
c.m.RUnlock()
// Credentials are expired need to retrieve the credentials taking the full
// lock.
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 // Expire expires the credentials and forces them to be retrieved on the
@ -255,10 +275,7 @@ func (c *Credentials) Get() (Value, error) {
// This will override the Provider's expired state, and force Credentials // This will override the Provider's expired state, and force Credentials
// to call the Provider's Retrieve(). // to call the Provider's Retrieve().
func (c *Credentials) Expire() { func (c *Credentials) Expire() {
c.m.Lock() c.creds.Store(Value{})
defer c.m.Unlock()
c.forceRefresh = true
} }
// IsExpired returns if the credentials are no longer valid, and need // IsExpired returns if the credentials are no longer valid, and need
@ -267,31 +284,25 @@ func (c *Credentials) Expire() {
// If the Credentials were forced to be expired with Expire() this will // If the Credentials were forced to be expired with Expire() this will
// reflect that override. // reflect that override.
func (c *Credentials) IsExpired() bool { func (c *Credentials) IsExpired() bool {
c.m.RLock() return c.isExpired(c.creds.Load())
defer c.m.RUnlock()
return c.isExpired()
} }
// isExpired helper method wrapping the definition of expired credentials. // isExpired helper method wrapping the definition of expired credentials.
func (c *Credentials) isExpired() bool { func (c *Credentials) isExpired(creds interface{}) bool {
return c.forceRefresh || c.provider.IsExpired() return creds == nil || creds.(Value) == Value{} || c.provider.IsExpired()
} }
// ExpiresAt provides access to the functionality of the Expirer interface of // ExpiresAt provides access to the functionality of the Expirer interface of
// the underlying Provider, if it supports that interface. Otherwise, it returns // the underlying Provider, if it supports that interface. Otherwise, it returns
// an error. // an error.
func (c *Credentials) ExpiresAt() (time.Time, error) { func (c *Credentials) ExpiresAt() (time.Time, error) {
c.m.RLock()
defer c.m.RUnlock()
expirer, ok := c.provider.(Expirer) expirer, ok := c.provider.(Expirer)
if !ok { if !ok {
return time.Time{}, awserr.New("ProviderNotExpirer", return time.Time{}, awserr.New("ProviderNotExpirer",
fmt.Sprintf("provider %s does not support ExpiresAt()", c.creds.ProviderName), fmt.Sprintf("provider %s does not support ExpiresAt()", c.creds.Load().(Value).ProviderName),
nil) nil)
} }
if c.forceRefresh { if c.creds.Load().(Value) == (Value{}) {
// set expiration time to the distant past // set expiration time to the distant past
return time.Time{}, nil return time.Time{}, nil
} }

View file

@ -90,6 +90,7 @@ import (
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/internal/sdkio"
) )
const ( const (
@ -142,7 +143,7 @@ const (
// DefaultBufSize limits buffer size from growing to an enormous // DefaultBufSize limits buffer size from growing to an enormous
// amount due to a faulty process. // amount due to a faulty process.
DefaultBufSize = 1024 DefaultBufSize = int(8 * sdkio.KibiByte)
// DefaultTimeout default limit on time a process can run. // DefaultTimeout default limit on time a process can run.
DefaultTimeout = time.Duration(1) * time.Minute DefaultTimeout = time.Duration(1) * time.Minute

View file

@ -144,6 +144,13 @@ type AssumeRoleProvider struct {
// Session name, if you wish to reuse the credentials elsewhere. // Session name, if you wish to reuse the credentials elsewhere.
RoleSessionName string RoleSessionName string
// Optional, you can pass tag key-value pairs to your session. These tags are called session tags.
Tags []*sts.Tag
// A list of keys for session tags that you want to set as transitive.
// If you set a tag key as transitive, the corresponding key and value passes to subsequent sessions in a role chain.
TransitiveTagKeys []*string
// Expiry duration of the STS credentials. Defaults to 15 minutes if not set. // Expiry duration of the STS credentials. Defaults to 15 minutes if not set.
Duration time.Duration Duration time.Duration
@ -269,10 +276,12 @@ func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) {
} }
jitter := time.Duration(sdkrand.SeededRand.Float64() * p.MaxJitterFrac * float64(p.Duration)) jitter := time.Duration(sdkrand.SeededRand.Float64() * p.MaxJitterFrac * float64(p.Duration))
input := &sts.AssumeRoleInput{ input := &sts.AssumeRoleInput{
DurationSeconds: aws.Int64(int64((p.Duration - jitter) / time.Second)), DurationSeconds: aws.Int64(int64((p.Duration - jitter) / time.Second)),
RoleArn: aws.String(p.RoleARN), RoleArn: aws.String(p.RoleARN),
RoleSessionName: aws.String(p.RoleSessionName), RoleSessionName: aws.String(p.RoleSessionName),
ExternalId: p.ExternalID, ExternalId: p.ExternalID,
Tags: p.Tags,
TransitiveTagKeys: p.TransitiveTagKeys,
} }
if p.Policy != nil { if p.Policy != nil {
input.Policy = p.Policy input.Policy = p.Policy

View file

@ -89,7 +89,7 @@ func getMetricException(err awserr.Error) metricException {
code := err.Code() code := err.Code()
switch code { switch code {
case "RequestError", case request.ErrCodeRequestError,
request.ErrCodeSerialization, request.ErrCodeSerialization,
request.CanceledErrorCode: request.CanceledErrorCode:
return sdkException{ return sdkException{

View file

@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"strconv"
"strings" "strings"
"time" "time"
@ -12,8 +13,41 @@ import (
"github.com/aws/aws-sdk-go/internal/sdkuri" "github.com/aws/aws-sdk-go/internal/sdkuri"
) )
// getToken uses the duration to return a token for EC2 metadata service,
// or an error if the request failed.
func (c *EC2Metadata) getToken(duration time.Duration) (tokenOutput, error) {
op := &request.Operation{
Name: "GetToken",
HTTPMethod: "PUT",
HTTPPath: "/api/token",
}
var output tokenOutput
req := c.NewRequest(op, nil, &output)
// remove the fetch token handler from the request handlers to avoid infinite recursion
req.Handlers.Sign.RemoveByName(fetchTokenHandlerName)
// Swap the unmarshalMetadataHandler with unmarshalTokenHandler on this request.
req.Handlers.Unmarshal.Swap(unmarshalMetadataHandlerName, unmarshalTokenHandler)
ttl := strconv.FormatInt(int64(duration/time.Second), 10)
req.HTTPRequest.Header.Set(ttlHeader, ttl)
err := req.Send()
// Errors with bad request status should be returned.
if err != nil {
err = awserr.NewRequestFailure(
awserr.New(req.HTTPResponse.Status, http.StatusText(req.HTTPResponse.StatusCode), err),
req.HTTPResponse.StatusCode, req.RequestID)
}
return output, err
}
// GetMetadata uses the path provided to request information from the EC2 // GetMetadata uses the path provided to request information from the EC2
// instance metdata service. The content will be returned as a string, or // instance metadata service. The content will be returned as a string, or
// error if the request failed. // error if the request failed.
func (c *EC2Metadata) GetMetadata(p string) (string, error) { func (c *EC2Metadata) GetMetadata(p string) (string, error) {
op := &request.Operation{ op := &request.Operation{
@ -21,11 +55,11 @@ func (c *EC2Metadata) GetMetadata(p string) (string, error) {
HTTPMethod: "GET", HTTPMethod: "GET",
HTTPPath: sdkuri.PathJoin("/meta-data", p), HTTPPath: sdkuri.PathJoin("/meta-data", p),
} }
output := &metadataOutput{} output := &metadataOutput{}
req := c.NewRequest(op, nil, output)
err := req.Send()
req := c.NewRequest(op, nil, output)
err := req.Send()
return output.Content, err return output.Content, err
} }
@ -41,13 +75,8 @@ func (c *EC2Metadata) GetUserData() (string, error) {
output := &metadataOutput{} output := &metadataOutput{}
req := c.NewRequest(op, nil, output) req := c.NewRequest(op, nil, output)
req.Handlers.UnmarshalError.PushBack(func(r *request.Request) {
if r.HTTPResponse.StatusCode == http.StatusNotFound {
r.Error = awserr.New("NotFoundError", "user-data not found", r.Error)
}
})
err := req.Send()
err := req.Send()
return output.Content, err return output.Content, err
} }
@ -63,8 +92,8 @@ func (c *EC2Metadata) GetDynamicData(p string) (string, error) {
output := &metadataOutput{} output := &metadataOutput{}
req := c.NewRequest(op, nil, output) req := c.NewRequest(op, nil, output)
err := req.Send()
err := req.Send()
return output.Content, err return output.Content, err
} }
@ -116,17 +145,17 @@ func (c *EC2Metadata) IAMInfo() (EC2IAMInfo, error) {
// Region returns the region the instance is running in. // Region returns the region the instance is running in.
func (c *EC2Metadata) Region() (string, error) { func (c *EC2Metadata) Region() (string, error) {
resp, err := c.GetMetadata("placement/availability-zone") ec2InstanceIdentityDocument, err := c.GetInstanceIdentityDocument()
if err != nil { if err != nil {
return "", err return "", err
} }
// extract region from the ec2InstanceIdentityDocument
if len(resp) == 0 { region := ec2InstanceIdentityDocument.Region
return "", awserr.New("EC2MetadataError", "invalid Region response", nil) if len(region) == 0 {
return "", awserr.New("EC2MetadataError", "invalid region received for ec2metadata instance", nil)
} }
// returns region
// returns region without the suffix. Eg: us-west-2a becomes us-west-2 return region, nil
return resp[:len(resp)-1], nil
} }
// Available returns if the application has access to the EC2 Metadata service. // Available returns if the application has access to the EC2 Metadata service.

View file

@ -13,6 +13,7 @@ import (
"io" "io"
"net/http" "net/http"
"os" "os"
"strconv"
"strings" "strings"
"time" "time"
@ -24,9 +25,25 @@ import (
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
) )
// ServiceName is the name of the service. const (
const ServiceName = "ec2metadata" // ServiceName is the name of the service.
const disableServiceEnvVar = "AWS_EC2_METADATA_DISABLED" ServiceName = "ec2metadata"
disableServiceEnvVar = "AWS_EC2_METADATA_DISABLED"
// Headers for Token and TTL
ttlHeader = "x-aws-ec2-metadata-token-ttl-seconds"
tokenHeader = "x-aws-ec2-metadata-token"
// Named Handler constants
fetchTokenHandlerName = "FetchTokenHandler"
unmarshalMetadataHandlerName = "unmarshalMetadataHandler"
unmarshalTokenHandlerName = "unmarshalTokenHandler"
enableTokenProviderHandlerName = "enableTokenProviderHandler"
// TTL constants
defaultTTL = 21600 * time.Second
ttlExpirationWindow = 30 * time.Second
)
// A EC2Metadata is an EC2 Metadata service Client. // A EC2Metadata is an EC2 Metadata service Client.
type EC2Metadata struct { type EC2Metadata struct {
@ -63,8 +80,10 @@ func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
// use a shorter timeout than default because the metadata // use a shorter timeout than default because the metadata
// service is local if it is running, and to fail faster // service is local if it is running, and to fail faster
// if not running on an ec2 instance. // if not running on an ec2 instance.
Timeout: 5 * time.Second, Timeout: 1 * time.Second,
} }
// max number of retries on the client operation
cfg.MaxRetries = aws.Int(2)
} }
svc := &EC2Metadata{ svc := &EC2Metadata{
@ -80,13 +99,27 @@ func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
), ),
} }
svc.Handlers.Unmarshal.PushBack(unmarshalHandler) // token provider instance
tp := newTokenProvider(svc, defaultTTL)
// NamedHandler for fetching token
svc.Handlers.Sign.PushBackNamed(request.NamedHandler{
Name: fetchTokenHandlerName,
Fn: tp.fetchTokenHandler,
})
// NamedHandler for enabling token provider
svc.Handlers.Complete.PushBackNamed(request.NamedHandler{
Name: enableTokenProviderHandlerName,
Fn: tp.enableTokenProviderHandler,
})
svc.Handlers.Unmarshal.PushBackNamed(unmarshalHandler)
svc.Handlers.UnmarshalError.PushBack(unmarshalError) svc.Handlers.UnmarshalError.PushBack(unmarshalError)
svc.Handlers.Validate.Clear() svc.Handlers.Validate.Clear()
svc.Handlers.Validate.PushBack(validateEndpointHandler) svc.Handlers.Validate.PushBack(validateEndpointHandler)
// Disable the EC2 Metadata service if the environment variable is set. // Disable the EC2 Metadata service if the environment variable is set.
// This shortcirctes the service's functionality to always fail to send // This short-circuits the service's functionality to always fail to send
// requests. // requests.
if strings.ToLower(os.Getenv(disableServiceEnvVar)) == "true" { if strings.ToLower(os.Getenv(disableServiceEnvVar)) == "true" {
svc.Handlers.Send.SwapNamed(request.NamedHandler{ svc.Handlers.Send.SwapNamed(request.NamedHandler{
@ -107,7 +140,6 @@ func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
for _, option := range opts { for _, option := range opts {
option(svc.Client) option(svc.Client)
} }
return svc return svc
} }
@ -119,30 +151,74 @@ type metadataOutput struct {
Content string Content string
} }
func unmarshalHandler(r *request.Request) { type tokenOutput struct {
defer r.HTTPResponse.Body.Close() Token string
b := &bytes.Buffer{} TTL time.Duration
if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { }
r.Error = awserr.New(request.ErrCodeSerialization, "unable to unmarshal EC2 metadata response", err)
return
}
if data, ok := r.Data.(*metadataOutput); ok { // unmarshal token handler is used to parse the response of a getToken operation
data.Content = b.String() var unmarshalTokenHandler = request.NamedHandler{
} Name: unmarshalTokenHandlerName,
Fn: func(r *request.Request) {
defer r.HTTPResponse.Body.Close()
var b bytes.Buffer
if _, err := io.Copy(&b, r.HTTPResponse.Body); err != nil {
r.Error = awserr.NewRequestFailure(awserr.New(request.ErrCodeSerialization,
"unable to unmarshal EC2 metadata response", err), r.HTTPResponse.StatusCode, r.RequestID)
return
}
v := r.HTTPResponse.Header.Get(ttlHeader)
data, ok := r.Data.(*tokenOutput)
if !ok {
return
}
data.Token = b.String()
// TTL is in seconds
i, err := strconv.ParseInt(v, 10, 64)
if err != nil {
r.Error = awserr.NewRequestFailure(awserr.New(request.ParamFormatErrCode,
"unable to parse EC2 token TTL response", err), r.HTTPResponse.StatusCode, r.RequestID)
return
}
t := time.Duration(i) * time.Second
data.TTL = t
},
}
var unmarshalHandler = request.NamedHandler{
Name: unmarshalMetadataHandlerName,
Fn: func(r *request.Request) {
defer r.HTTPResponse.Body.Close()
var b bytes.Buffer
if _, err := io.Copy(&b, r.HTTPResponse.Body); err != nil {
r.Error = awserr.NewRequestFailure(awserr.New(request.ErrCodeSerialization,
"unable to unmarshal EC2 metadata response", err), r.HTTPResponse.StatusCode, r.RequestID)
return
}
if data, ok := r.Data.(*metadataOutput); ok {
data.Content = b.String()
}
},
} }
func unmarshalError(r *request.Request) { func unmarshalError(r *request.Request) {
defer r.HTTPResponse.Body.Close() defer r.HTTPResponse.Body.Close()
b := &bytes.Buffer{} var b bytes.Buffer
if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
r.Error = awserr.New(request.ErrCodeSerialization, "unable to unmarshal EC2 metadata error response", err) if _, err := io.Copy(&b, r.HTTPResponse.Body); err != nil {
r.Error = awserr.NewRequestFailure(
awserr.New(request.ErrCodeSerialization, "unable to unmarshal EC2 metadata error response", err),
r.HTTPResponse.StatusCode, r.RequestID)
return return
} }
// Response body format is not consistent between metadata endpoints. // Response body format is not consistent between metadata endpoints.
// Grab the error message as a string and include that as the source error // 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())) r.Error = awserr.NewRequestFailure(awserr.New("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String())),
r.HTTPResponse.StatusCode, r.RequestID)
} }
func validateEndpointHandler(r *request.Request) { func validateEndpointHandler(r *request.Request) {

View file

@ -0,0 +1,92 @@
package ec2metadata
import (
"net/http"
"sync/atomic"
"time"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/request"
)
// A tokenProvider struct provides access to EC2Metadata client
// and atomic instance of a token, along with configuredTTL for it.
// tokenProvider also provides an atomic flag to disable the
// fetch token operation.
// The disabled member will use 0 as false, and 1 as true.
type tokenProvider struct {
client *EC2Metadata
token atomic.Value
configuredTTL time.Duration
disabled uint32
}
// A ec2Token struct helps use of token in EC2 Metadata service ops
type ec2Token struct {
token string
credentials.Expiry
}
// newTokenProvider provides a pointer to a tokenProvider instance
func newTokenProvider(c *EC2Metadata, duration time.Duration) *tokenProvider {
return &tokenProvider{client: c, configuredTTL: duration}
}
// fetchTokenHandler fetches token for EC2Metadata service client by default.
func (t *tokenProvider) fetchTokenHandler(r *request.Request) {
// short-circuits to insecure data flow if tokenProvider is disabled.
if v := atomic.LoadUint32(&t.disabled); v == 1 {
return
}
if ec2Token, ok := t.token.Load().(ec2Token); ok && !ec2Token.IsExpired() {
r.HTTPRequest.Header.Set(tokenHeader, ec2Token.token)
return
}
output, err := t.client.getToken(t.configuredTTL)
if err != nil {
// change the disabled flag on token provider to true,
// when error is request timeout error.
if requestFailureError, ok := err.(awserr.RequestFailure); ok {
switch requestFailureError.StatusCode() {
case http.StatusForbidden, http.StatusNotFound, http.StatusMethodNotAllowed:
atomic.StoreUint32(&t.disabled, 1)
case http.StatusBadRequest:
r.Error = requestFailureError
}
// Check if request timed out while waiting for response
if e, ok := requestFailureError.OrigErr().(awserr.Error); ok {
if e.Code() == request.ErrCodeRequestError {
atomic.StoreUint32(&t.disabled, 1)
}
}
}
return
}
newToken := ec2Token{
token: output.Token,
}
newToken.SetExpiration(time.Now().Add(output.TTL), ttlExpirationWindow)
t.token.Store(newToken)
// Inject token header to the request.
if ec2Token, ok := t.token.Load().(ec2Token); ok {
r.HTTPRequest.Header.Set(tokenHeader, ec2Token.token)
}
}
// enableTokenProviderHandler enables the token provider
func (t *tokenProvider) enableTokenProviderHandler(r *request.Request) {
// If the error code status is 401, we enable the token provider
if e, ok := r.Error.(awserr.RequestFailure); ok && e != nil &&
e.StatusCode() == http.StatusUnauthorized {
atomic.StoreUint32(&t.disabled, 0)
}
}

View file

@ -83,6 +83,7 @@ func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resol
p := &ps[i] p := &ps[i]
custAddEC2Metadata(p) custAddEC2Metadata(p)
custAddS3DualStack(p) custAddS3DualStack(p)
custRegionalS3(p)
custRmIotDataService(p) custRmIotDataService(p)
custFixAppAutoscalingChina(p) custFixAppAutoscalingChina(p)
custFixAppAutoscalingUsGov(p) custFixAppAutoscalingUsGov(p)
@ -100,6 +101,33 @@ func custAddS3DualStack(p *partition) {
custAddDualstack(p, "s3-control") custAddDualstack(p, "s3-control")
} }
func custRegionalS3(p *partition) {
if p.ID != "aws" {
return
}
service, ok := p.Services["s3"]
if !ok {
return
}
// If global endpoint already exists no customization needed.
if _, ok := service.Endpoints["aws-global"]; ok {
return
}
service.PartitionEndpoint = "aws-global"
service.Endpoints["us-east-1"] = endpoint{}
service.Endpoints["aws-global"] = endpoint{
Hostname: "s3.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
}
p.Services["s3"] = service
}
func custAddDualstack(p *partition, svcName string) { func custAddDualstack(p *partition, svcName string) {
s, ok := p.Services[svcName] s, ok := p.Services[svcName]
if !ok { if !ok {

View file

@ -169,7 +169,7 @@ var awsPartition = partition{
"us-east-1": endpoint{}, "us-east-1": endpoint{},
}, },
}, },
"acm": service{ "access-analyzer": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
@ -192,6 +192,59 @@ var awsPartition = partition{
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
"acm": service{
Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"ca-central-1-fips": endpoint{
Hostname: "acm-fips.ca-central-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "ca-central-1",
},
},
"eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{},
"us-east-1-fips": endpoint{
Hostname: "acm-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"us-east-2": endpoint{},
"us-east-2-fips": endpoint{
Hostname: "acm-fips.us-east-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-2",
},
},
"us-west-1": endpoint{},
"us-west-1-fips": endpoint{
Hostname: "acm-fips.us-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-1",
},
},
"us-west-2": endpoint{},
"us-west-2-fips": endpoint{
Hostname: "acm-fips.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
},
},
"acm-pca": service{ "acm-pca": service{
Defaults: endpoint{ Defaults: endpoint{
Protocols: []string{"https"}, Protocols: []string{"https"},
@ -209,12 +262,42 @@ var awsPartition = partition{
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"me-south-1": endpoint{}, "fips-ca-central-1": endpoint{
"sa-east-1": endpoint{}, Hostname: "acm-pca-fips.ca-central-1.amazonaws.com",
"us-east-1": endpoint{}, CredentialScope: credentialScope{
"us-east-2": endpoint{}, Region: "ca-central-1",
"us-west-1": endpoint{}, },
"us-west-2": endpoint{}, },
"fips-us-east-1": endpoint{
Hostname: "acm-pca-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"fips-us-east-2": endpoint{
Hostname: "acm-pca-fips.us-east-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-2",
},
},
"fips-us-west-1": endpoint{
Hostname: "acm-pca-fips.us-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-1",
},
},
"fips-us-west-2": endpoint{
Hostname: "acm-pca-fips.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
"me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"api.ecr": service{ "api.ecr": service{
@ -425,11 +508,7 @@ var awsPartition = partition{
}, },
"application-autoscaling": service{ "application-autoscaling": service{
Defaults: endpoint{ Defaults: endpoint{
Hostname: "autoscaling.{region}.amazonaws.com",
Protocols: []string{"http", "https"}, Protocols: []string{"http", "https"},
CredentialScope: credentialScope{
Service: "application-autoscaling",
},
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
@ -462,9 +541,12 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
@ -527,6 +609,7 @@ var awsPartition = partition{
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"me-south-1": endpoint{}, "me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
@ -560,11 +643,7 @@ var awsPartition = partition{
}, },
"autoscaling-plans": service{ "autoscaling-plans": service{
Defaults: endpoint{ Defaults: endpoint{
Hostname: "autoscaling.{region}.amazonaws.com",
Protocols: []string{"http", "https"}, Protocols: []string{"http", "https"},
CredentialScope: credentialScope{
Service: "autoscaling-plans",
},
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
@ -675,9 +754,15 @@ var awsPartition = partition{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
@ -864,6 +949,7 @@ var awsPartition = partition{
"codecommit": service{ "codecommit": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
@ -1029,6 +1115,9 @@ var awsPartition = partition{
Protocols: []string{"https"}, Protocols: []string{"https"},
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
@ -1079,8 +1168,10 @@ var awsPartition = partition{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-2": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
@ -1104,6 +1195,22 @@ var awsPartition = partition{
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
"dataexchange": service{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
},
},
"datapipeline": service{ "datapipeline": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -1117,12 +1224,15 @@ var awsPartition = partition{
"datasync": service{ "datasync": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
@ -1151,6 +1261,7 @@ var awsPartition = partition{
}, },
}, },
"me-south-1": endpoint{}, "me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
@ -1166,6 +1277,8 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"sa-east-1": endpoint{}, "sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
@ -1205,7 +1318,8 @@ var awsPartition = partition{
"discovery": service{ "discovery": service{
Endpoints: endpoints{ Endpoints: endpoints{
"us-west-2": endpoint{}, "eu-central-1": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"dms": service{ "dms": service{
@ -1264,6 +1378,12 @@ var awsPartition = partition{
Region: "ap-southeast-2", Region: "ap-southeast-2",
}, },
}, },
"ca-central-1": endpoint{
Hostname: "rds.ca-central-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "ca-central-1",
},
},
"eu-central-1": endpoint{ "eu-central-1": endpoint{
Hostname: "rds.eu-central-1.amazonaws.com", Hostname: "rds.eu-central-1.amazonaws.com",
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -1322,6 +1442,7 @@ var awsPartition = partition{
"eu-north-1": endpoint{}, "eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"sa-east-1": endpoint{}, "sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
@ -1505,6 +1626,7 @@ var awsPartition = partition{
"elasticfilesystem": service{ "elasticfilesystem": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
@ -1512,9 +1634,12 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
@ -1692,11 +1817,16 @@ var awsPartition = partition{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
@ -1707,6 +1837,7 @@ var awsPartition = partition{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
@ -1830,8 +1961,10 @@ var awsPartition = partition{
"groundstation": service{ "groundstation": service{
Endpoints: endpoints{ Endpoints: endpoints{
"us-east-2": endpoint{}, "eu-north-1": endpoint{},
"us-west-2": endpoint{}, "me-south-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"guardduty": service{ "guardduty": service{
@ -2053,6 +2186,29 @@ var awsPartition = partition{
}, },
}, },
}, },
"iotsecuredtunneling": service{
Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
},
},
"iotthingsgraph": service{ "iotthingsgraph": service{
Defaults: endpoint{ Defaults: endpoint{
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -2083,6 +2239,7 @@ var awsPartition = partition{
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"me-south-1": endpoint{},
"sa-east-1": endpoint{}, "sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
@ -2116,16 +2273,20 @@ var awsPartition = partition{
"kinesisanalytics": service{ "kinesisanalytics": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{}, "eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
@ -2134,11 +2295,20 @@ var awsPartition = partition{
"kinesisvideo": service{ "kinesisvideo": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
@ -2169,12 +2339,17 @@ var awsPartition = partition{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
@ -2272,6 +2447,12 @@ var awsPartition = partition{
"us-east-1": endpoint{}, "us-east-1": endpoint{},
}, },
}, },
"managedblockchain": service{
Endpoints: endpoints{
"us-east-1": endpoint{},
},
},
"marketplacecommerceanalytics": service{ "marketplacecommerceanalytics": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -2281,6 +2462,7 @@ var awsPartition = partition{
"mediaconnect": service{ "mediaconnect": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
@ -2398,7 +2580,8 @@ var awsPartition = partition{
"mgh": service{ "mgh": service{
Endpoints: endpoints{ Endpoints: endpoints{
"us-west-2": endpoint{}, "eu-central-1": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"mobileanalytics": service{ "mobileanalytics": service{
@ -2414,9 +2597,10 @@ var awsPartition = partition{
}, },
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"eu-west-1": endpoint{}, "ap-southeast-2": endpoint{},
"us-east-1": endpoint{}, "eu-west-1": endpoint{},
"us-west-2": endpoint{}, "us-east-1": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"monitoring": service{ "monitoring": service{
@ -2447,6 +2631,7 @@ var awsPartition = partition{
"mq": service{ "mq": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
@ -2454,6 +2639,7 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
@ -2481,10 +2667,12 @@ var awsPartition = partition{
Region: "us-west-2", Region: "us-west-2",
}, },
}, },
"us-east-1": endpoint{}, "me-south-1": endpoint{},
"us-east-2": endpoint{}, "sa-east-1": endpoint{},
"us-west-1": endpoint{}, "us-east-1": endpoint{},
"us-west-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"mturk-requester": service{ "mturk-requester": service{
@ -2692,6 +2880,27 @@ var awsPartition = partition{
}, },
}, },
}, },
"outposts": service{
Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"me-south-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
},
},
"pinpoint": service{ "pinpoint": service{
Defaults: endpoint{ Defaults: endpoint{
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -2703,13 +2912,36 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"us-east-1": endpoint{}, "fips-us-east-1": endpoint{
"us-west-2": endpoint{}, Hostname: "pinpoint-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"fips-us-west-2": endpoint{
Hostname: "pinpoint-fips.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
"us-east-1": endpoint{
Hostname: "pinpoint.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"us-west-2": endpoint{
Hostname: "pinpoint.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
}, },
}, },
"polly": service{ "polly": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
@ -2721,6 +2953,7 @@ var awsPartition = partition{
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"me-south-1": endpoint{},
"sa-east-1": endpoint{}, "sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
@ -2803,6 +3036,10 @@ var awsPartition = partition{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
@ -2812,6 +3049,7 @@ var awsPartition = partition{
"ram": service{ "ram": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
@ -2823,6 +3061,8 @@ var awsPartition = partition{
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
"me-south-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
@ -2977,6 +3217,7 @@ var awsPartition = partition{
Protocols: []string{"https"}, Protocols: []string{"https"},
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
@ -2984,6 +3225,7 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
@ -3000,9 +3242,10 @@ var awsPartition = partition{
}, },
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"eu-west-1": endpoint{}, "ap-southeast-2": endpoint{},
"us-east-1": endpoint{}, "eu-west-1": endpoint{},
"us-west-2": endpoint{}, "us-east-1": endpoint{},
"us-west-2": endpoint{},
}, },
}, },
"runtime.sagemaker": service{ "runtime.sagemaker": service{
@ -3053,7 +3296,7 @@ var awsPartition = partition{
}, },
}, },
"s3": service{ "s3": service{
PartitionEndpoint: "us-east-1", PartitionEndpoint: "aws-global",
IsRegionalized: boxedTrue, IsRegionalized: boxedTrue,
Defaults: endpoint{ Defaults: endpoint{
Protocols: []string{"http", "https"}, Protocols: []string{"http", "https"},
@ -3078,6 +3321,13 @@ var awsPartition = partition{
Hostname: "s3.ap-southeast-2.amazonaws.com", Hostname: "s3.ap-southeast-2.amazonaws.com",
SignatureVersions: []string{"s3", "s3v4"}, SignatureVersions: []string{"s3", "s3v4"},
}, },
"aws-global": endpoint{
Hostname: "s3.amazonaws.com",
SignatureVersions: []string{"s3", "s3v4"},
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{}, "eu-north-1": endpoint{},
@ -3100,7 +3350,7 @@ var awsPartition = partition{
SignatureVersions: []string{"s3", "s3v4"}, SignatureVersions: []string{"s3", "s3v4"},
}, },
"us-east-1": endpoint{ "us-east-1": endpoint{
Hostname: "s3.amazonaws.com", Hostname: "s3.us-east-1.amazonaws.com",
SignatureVersions: []string{"s3", "s3v4"}, SignatureVersions: []string{"s3", "s3v4"},
}, },
"us-east-2": endpoint{}, "us-east-2": endpoint{},
@ -3278,6 +3528,16 @@ var awsPartition = partition{
}, },
}, },
}, },
"schemas": service{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
},
},
"sdb": service{ "sdb": service{
Defaults: endpoint{ Defaults: endpoint{
Protocols: []string{"http", "https"}, Protocols: []string{"http", "https"},
@ -3499,6 +3759,10 @@ var awsPartition = partition{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
@ -3886,6 +4150,7 @@ var awsPartition = partition{
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{}, "ap-east-1": endpoint{},
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
@ -3940,13 +4205,18 @@ var awsPartition = partition{
Protocols: []string{"https"}, Protocols: []string{"https"},
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-1-fips": endpoint{ "us-east-1-fips": endpoint{
Hostname: "translate-fips.us-east-1.amazonaws.com", Hostname: "translate-fips.us-east-1.amazonaws.com",
@ -3961,6 +4231,7 @@ var awsPartition = partition{
Region: "us-east-2", Region: "us-east-2",
}, },
}, },
"us-west-1": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
"us-west-2-fips": endpoint{ "us-west-2-fips": endpoint{
Hostname: "translate-fips.us-west-2.amazonaws.com", Hostname: "translate-fips.us-west-2.amazonaws.com",
@ -4122,17 +4393,25 @@ var awscnPartition = partition{
}, },
"application-autoscaling": service{ "application-autoscaling": service{
Defaults: endpoint{ Defaults: endpoint{
Hostname: "autoscaling.{region}.amazonaws.com.cn",
Protocols: []string{"http", "https"}, Protocols: []string{"http", "https"},
CredentialScope: credentialScope{
Service: "application-autoscaling",
},
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"cn-north-1": endpoint{}, "cn-north-1": endpoint{},
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{},
}, },
}, },
"appsync": service{
Endpoints: endpoints{
"cn-north-1": endpoint{},
},
},
"athena": service{
Endpoints: endpoints{
"cn-northwest-1": endpoint{},
},
},
"autoscaling": service{ "autoscaling": service{
Defaults: endpoint{ Defaults: endpoint{
Protocols: []string{"http", "https"}, Protocols: []string{"http", "https"},
@ -4142,6 +4421,13 @@ var awscnPartition = partition{
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{},
}, },
}, },
"backup": service{
Endpoints: endpoints{
"cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
},
},
"batch": service{ "batch": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -4204,6 +4490,12 @@ var awscnPartition = partition{
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{},
}, },
}, },
"dax": service{
Endpoints: endpoints{
"cn-northwest-1": endpoint{},
},
},
"directconnect": service{ "directconnect": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -4275,6 +4567,13 @@ var awscnPartition = partition{
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{},
}, },
}, },
"elasticfilesystem": service{
Endpoints: endpoints{
"cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
},
},
"elasticloadbalancing": service{ "elasticloadbalancing": service{
Defaults: endpoint{ Defaults: endpoint{
Protocols: []string{"https"}, Protocols: []string{"https"},
@ -4344,6 +4643,13 @@ var awscnPartition = partition{
"cn-north-1": endpoint{}, "cn-north-1": endpoint{},
}, },
}, },
"health": service{
Endpoints: endpoints{
"cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
},
},
"iam": service{ "iam": service{
PartitionEndpoint: "aws-cn-global", PartitionEndpoint: "aws-cn-global",
IsRegionalized: boxedFalse, IsRegionalized: boxedFalse,
@ -4423,6 +4729,17 @@ var awscnPartition = partition{
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{},
}, },
}, },
"neptune": service{
Endpoints: endpoints{
"cn-northwest-1": endpoint{
Hostname: "rds.cn-northwest-1.amazonaws.com.cn",
CredentialScope: credentialScope{
Region: "cn-northwest-1",
},
},
},
},
"polly": service{ "polly": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -4475,6 +4792,26 @@ var awscnPartition = partition{
}, },
}, },
}, },
"secretsmanager": service{
Endpoints: endpoints{
"cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
},
},
"serverlessrepo": service{
Defaults: endpoint{
Protocols: []string{"https"},
},
Endpoints: endpoints{
"cn-north-1": endpoint{
Protocols: []string{"https"},
},
"cn-northwest-1": endpoint{
Protocols: []string{"https"},
},
},
},
"sms": service{ "sms": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -4524,7 +4861,8 @@ var awscnPartition = partition{
"storagegateway": service{ "storagegateway": service{
Endpoints: endpoints{ Endpoints: endpoints{
"cn-north-1": endpoint{}, "cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
}, },
}, },
"streams.dynamodb": service{ "streams.dynamodb": service{
@ -4591,6 +4929,19 @@ var awscnPartition = partition{
}, },
}, },
}, },
"workspaces": service{
Endpoints: endpoints{
"cn-northwest-1": endpoint{},
},
},
"xray": service{
Endpoints: endpoints{
"cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
},
},
}, },
} }
@ -4623,6 +4974,13 @@ var awsusgovPartition = partition{
}, },
}, },
Services: services{ Services: services{
"access-analyzer": service{
Endpoints: endpoints{
"us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{},
},
},
"acm": service{ "acm": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -4671,7 +5029,8 @@ var awsusgovPartition = partition{
}, },
"application-autoscaling": service{ "application-autoscaling": service{
Defaults: endpoint{ Defaults: endpoint{
Hostname: "autoscaling.{region}.amazonaws.com", Hostname: "autoscaling.{region}.amazonaws.com",
Protocols: []string{"http", "https"},
CredentialScope: credentialScope{ CredentialScope: credentialScope{
Service: "application-autoscaling", Service: "application-autoscaling",
}, },
@ -4714,6 +5073,22 @@ var awsusgovPartition = partition{
}, },
}, },
}, },
"autoscaling-plans": service{
Defaults: endpoint{
Protocols: []string{"http", "https"},
},
Endpoints: endpoints{
"us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{},
},
},
"batch": service{
Endpoints: endpoints{
"us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{},
},
},
"clouddirectory": service{ "clouddirectory": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -4792,6 +5167,12 @@ var awsusgovPartition = partition{
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
"comprehendmedical": service{
Endpoints: endpoints{
"us-gov-west-1": endpoint{},
},
},
"config": service{ "config": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -4808,6 +5189,7 @@ var awsusgovPartition = partition{
Region: "us-gov-west-1", Region: "us-gov-west-1",
}, },
}, },
"us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
@ -4899,6 +5281,7 @@ var awsusgovPartition = partition{
"elasticfilesystem": service{ "elasticfilesystem": service{
Endpoints: endpoints{ Endpoints: endpoints{
"us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
@ -5374,6 +5757,18 @@ var awsusgovPartition = partition{
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
"support": service{
PartitionEndpoint: "aws-us-gov-global",
Endpoints: endpoints{
"aws-us-gov-global": endpoint{
Hostname: "support.us-gov-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-west-1",
},
},
},
},
"swf": service{ "swf": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -5393,6 +5788,7 @@ var awsusgovPartition = partition{
Protocols: []string{"https"}, Protocols: []string{"https"},
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
@ -5476,11 +5872,7 @@ var awsisoPartition = partition{
}, },
"application-autoscaling": service{ "application-autoscaling": service{
Defaults: endpoint{ Defaults: endpoint{
Hostname: "autoscaling.{region}.amazonaws.com",
Protocols: []string{"http", "https"}, Protocols: []string{"http", "https"},
CredentialScope: credentialScope{
Service: "application-autoscaling",
},
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"us-iso-east-1": endpoint{}, "us-iso-east-1": endpoint{},
@ -5808,11 +6200,7 @@ var awsisobPartition = partition{
Services: services{ Services: services{
"application-autoscaling": service{ "application-autoscaling": service{
Defaults: endpoint{ Defaults: endpoint{
Hostname: "autoscaling.{region}.amazonaws.com",
Protocols: []string{"http", "https"}, Protocols: []string{"http", "https"},
CredentialScope: credentialScope{
Service: "application-autoscaling",
},
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"us-isob-east-1": endpoint{}, "us-isob-east-1": endpoint{},

View file

@ -50,12 +50,28 @@ type Options struct {
// STS Regional Endpoint flag helps with resolving the STS endpoint // STS Regional Endpoint flag helps with resolving the STS endpoint
STSRegionalEndpoint STSRegionalEndpoint STSRegionalEndpoint STSRegionalEndpoint
// S3 Regional Endpoint flag helps with resolving the S3 endpoint
S3UsEast1RegionalEndpoint S3UsEast1RegionalEndpoint
} }
// STSRegionalEndpoint is an enum type alias for int // STSRegionalEndpoint is an enum for the states of the STS Regional Endpoint
// It is used internally by the core sdk as STS Regional Endpoint flag value // options.
type STSRegionalEndpoint int type STSRegionalEndpoint int
func (e STSRegionalEndpoint) String() string {
switch e {
case LegacySTSEndpoint:
return "legacy"
case RegionalSTSEndpoint:
return "regional"
case UnsetSTSEndpoint:
return ""
default:
return "unknown"
}
}
const ( const (
// UnsetSTSEndpoint represents that STS Regional Endpoint flag is not specified. // UnsetSTSEndpoint represents that STS Regional Endpoint flag is not specified.
@ -86,6 +102,55 @@ func GetSTSRegionalEndpoint(s string) (STSRegionalEndpoint, error) {
} }
} }
// S3UsEast1RegionalEndpoint is an enum for the states of the S3 us-east-1
// Regional Endpoint options.
type S3UsEast1RegionalEndpoint int
func (e S3UsEast1RegionalEndpoint) String() string {
switch e {
case LegacyS3UsEast1Endpoint:
return "legacy"
case RegionalS3UsEast1Endpoint:
return "regional"
case UnsetS3UsEast1Endpoint:
return ""
default:
return "unknown"
}
}
const (
// UnsetS3UsEast1Endpoint represents that S3 Regional Endpoint flag is not
// specified.
UnsetS3UsEast1Endpoint S3UsEast1RegionalEndpoint = iota
// LegacyS3UsEast1Endpoint represents when S3 Regional Endpoint flag is
// specified to use legacy endpoints.
LegacyS3UsEast1Endpoint
// RegionalS3UsEast1Endpoint represents when S3 Regional Endpoint flag is
// specified to use regional endpoints.
RegionalS3UsEast1Endpoint
)
// GetS3UsEast1RegionalEndpoint function returns the S3UsEast1RegionalEndpointFlag based
// on the input string provided in env config or shared config by the user.
//
// `legacy`, `regional` are the only case-insensitive valid strings for
// resolving the S3 regional Endpoint flag.
func GetS3UsEast1RegionalEndpoint(s string) (S3UsEast1RegionalEndpoint, error) {
switch {
case strings.EqualFold(s, "legacy"):
return LegacyS3UsEast1Endpoint, nil
case strings.EqualFold(s, "regional"):
return RegionalS3UsEast1Endpoint, nil
default:
return UnsetS3UsEast1Endpoint,
fmt.Errorf("unable to resolve the value of S3UsEast1RegionalEndpoint for %v", s)
}
}
// Set combines all of the option functions together. // Set combines all of the option functions together.
func (o *Options) Set(optFns ...func(*Options)) { func (o *Options) Set(optFns ...func(*Options)) {
for _, fn := range optFns { for _, fn := range optFns {
@ -252,7 +317,7 @@ func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (
// Regions returns a map of Regions indexed by their ID. This is useful for // Regions returns a map of Regions indexed by their ID. This is useful for
// enumerating over the regions in a partition. // enumerating over the regions in a partition.
func (p Partition) Regions() map[string]Region { func (p Partition) Regions() map[string]Region {
rs := map[string]Region{} rs := make(map[string]Region, len(p.p.Regions))
for id, r := range p.p.Regions { for id, r := range p.p.Regions {
rs[id] = Region{ rs[id] = Region{
id: id, id: id,
@ -267,7 +332,7 @@ func (p Partition) Regions() map[string]Region {
// Services returns a map of Service indexed by their ID. This is useful for // Services returns a map of Service indexed by their ID. This is useful for
// enumerating over the services in a partition. // enumerating over the services in a partition.
func (p Partition) Services() map[string]Service { func (p Partition) Services() map[string]Service {
ss := map[string]Service{} ss := make(map[string]Service, len(p.p.Services))
for id := range p.p.Services { for id := range p.p.Services {
ss[id] = Service{ ss[id] = Service{
id: id, id: id,
@ -354,7 +419,7 @@ func (s Service) Regions() map[string]Region {
// A region is the AWS region the service exists in. Whereas a Endpoint is // A region is the AWS region the service exists in. Whereas a Endpoint is
// an URL that can be resolved to a instance of a service. // an URL that can be resolved to a instance of a service.
func (s Service) Endpoints() map[string]Endpoint { func (s Service) Endpoints() map[string]Endpoint {
es := map[string]Endpoint{} es := make(map[string]Endpoint, len(s.p.Services[s.id].Endpoints))
for id := range s.p.Services[s.id].Endpoints { for id := range s.p.Services[s.id].Endpoints {
es[id] = Endpoint{ es[id] = Endpoint{
id: id, id: id,

View file

@ -0,0 +1,24 @@
package endpoints
var legacyGlobalRegions = map[string]map[string]struct{}{
"sts": {
"ap-northeast-1": {},
"ap-south-1": {},
"ap-southeast-1": {},
"ap-southeast-2": {},
"ca-central-1": {},
"eu-central-1": {},
"eu-north-1": {},
"eu-west-1": {},
"eu-west-2": {},
"eu-west-3": {},
"sa-east-1": {},
"us-east-1": {},
"us-east-2": {},
"us-west-1": {},
"us-west-2": {},
},
"s3": {
"us-east-1": {},
},
}

View file

@ -1,19 +0,0 @@
package endpoints
var stsLegacyGlobalRegions = map[string]struct{}{
"ap-northeast-1": {},
"ap-south-1": {},
"ap-southeast-1": {},
"ap-southeast-2": {},
"ca-central-1": {},
"eu-central-1": {},
"eu-north-1": {},
"eu-west-1": {},
"eu-west-2": {},
"eu-west-3": {},
"sa-east-1": {},
"us-east-1": {},
"us-east-2": {},
"us-west-1": {},
"us-west-2": {},
}

View file

@ -110,8 +110,9 @@ func (p partition) EndpointFor(service, region string, opts ...func(*Options)) (
region = s.PartitionEndpoint region = s.PartitionEndpoint
} }
if service == "sts" && opt.STSRegionalEndpoint != RegionalSTSEndpoint { if (service == "sts" && opt.STSRegionalEndpoint != RegionalSTSEndpoint) ||
if _, ok := stsLegacyGlobalRegions[region]; ok { (service == "s3" && opt.S3UsEast1RegionalEndpoint != RegionalS3UsEast1Endpoint) {
if _, ok := legacyGlobalRegions[service][region]; ok {
region = "aws-global" region = "aws-global"
} }
} }
@ -240,20 +241,6 @@ func (e endpoint) resolve(service, partitionID, region, dnsSuffix string, defs [
merged.mergeIn(e) merged.mergeIn(e)
e = merged e = merged
hostname := e.Hostname
// Offset the hostname for dualstack if enabled
if opts.UseDualStack && e.HasDualStack == boxedTrue {
hostname = e.DualStackHostname
}
u := strings.Replace(hostname, "{service}", service, 1)
u = strings.Replace(u, "{region}", region, 1)
u = strings.Replace(u, "{dnsSuffix}", dnsSuffix, 1)
scheme := getEndpointScheme(e.Protocols, opts.DisableSSL)
u = fmt.Sprintf("%s://%s", scheme, u)
signingRegion := e.CredentialScope.Region signingRegion := e.CredentialScope.Region
if len(signingRegion) == 0 { if len(signingRegion) == 0 {
signingRegion = region signingRegion = region
@ -266,6 +253,20 @@ func (e endpoint) resolve(service, partitionID, region, dnsSuffix string, defs [
signingNameDerived = true signingNameDerived = true
} }
hostname := e.Hostname
// Offset the hostname for dualstack if enabled
if opts.UseDualStack && e.HasDualStack == boxedTrue {
hostname = e.DualStackHostname
region = signingRegion
}
u := strings.Replace(hostname, "{service}", service, 1)
u = strings.Replace(u, "{region}", region, 1)
u = strings.Replace(u, "{dnsSuffix}", dnsSuffix, 1)
scheme := getEndpointScheme(e.Protocols, opts.DisableSSL)
u = fmt.Sprintf("%s://%s", scheme, u)
return ResolvedEndpoint{ return ResolvedEndpoint{
URL: u, URL: u,
PartitionID: partitionID, PartitionID: partitionID,

View file

@ -10,6 +10,7 @@ import (
type Handlers struct { type Handlers struct {
Validate HandlerList Validate HandlerList
Build HandlerList Build HandlerList
BuildStream HandlerList
Sign HandlerList Sign HandlerList
Send HandlerList Send HandlerList
ValidateResponse HandlerList ValidateResponse HandlerList
@ -28,6 +29,7 @@ func (h *Handlers) Copy() Handlers {
return Handlers{ return Handlers{
Validate: h.Validate.copy(), Validate: h.Validate.copy(),
Build: h.Build.copy(), Build: h.Build.copy(),
BuildStream: h.BuildStream.copy(),
Sign: h.Sign.copy(), Sign: h.Sign.copy(),
Send: h.Send.copy(), Send: h.Send.copy(),
ValidateResponse: h.ValidateResponse.copy(), ValidateResponse: h.ValidateResponse.copy(),
@ -46,6 +48,7 @@ func (h *Handlers) Copy() Handlers {
func (h *Handlers) Clear() { func (h *Handlers) Clear() {
h.Validate.Clear() h.Validate.Clear()
h.Build.Clear() h.Build.Clear()
h.BuildStream.Clear()
h.Send.Clear() h.Send.Clear()
h.Sign.Clear() h.Sign.Clear()
h.Unmarshal.Clear() h.Unmarshal.Clear()
@ -67,6 +70,9 @@ func (h *Handlers) IsEmpty() bool {
if h.Build.Len() != 0 { if h.Build.Len() != 0 {
return false return false
} }
if h.BuildStream.Len() != 0 {
return false
}
if h.Send.Len() != 0 { if h.Send.Len() != 0 {
return false return false
} }
@ -320,3 +326,18 @@ func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) {
AddToUserAgent(r, s) AddToUserAgent(r, s)
} }
} }
// WithSetRequestHeaders updates the operation request's HTTP header to contain
// the header key value pairs provided. If the header key already exists in the
// request's HTTP header set, the existing value(s) will be replaced.
func WithSetRequestHeaders(h map[string]string) Option {
return withRequestHeader(h).SetRequestHeaders
}
type withRequestHeader map[string]string
func (h withRequestHeader) SetRequestHeaders(r *Request) {
for k, v := range h {
r.HTTPRequest.Header[k] = []string{v}
}
}

View file

@ -36,6 +36,10 @@ const (
// API request that was canceled. Requests given a aws.Context may // API request that was canceled. Requests given a aws.Context may
// return this error when canceled. // return this error when canceled.
CanceledErrorCode = "RequestCanceled" CanceledErrorCode = "RequestCanceled"
// ErrCodeRequestError is an error preventing the SDK from continuing to
// process the request.
ErrCodeRequestError = "RequestError"
) )
// A Request is the service request to be made. // A Request is the service request to be made.
@ -51,6 +55,7 @@ type Request struct {
HTTPRequest *http.Request HTTPRequest *http.Request
HTTPResponse *http.Response HTTPResponse *http.Response
Body io.ReadSeeker Body io.ReadSeeker
streamingBody io.ReadCloser
BodyStart int64 // offset from beginning of Body that the request body starts BodyStart int64 // offset from beginning of Body that the request body starts
Params interface{} Params interface{}
Error error Error error
@ -130,8 +135,6 @@ func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err) err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err)
} }
SanitizeHostForHeader(httpReq)
r := &Request{ r := &Request{
Config: cfg, Config: cfg,
ClientInfo: clientInfo, ClientInfo: clientInfo,
@ -295,6 +298,13 @@ func (r *Request) SetReaderBody(reader io.ReadSeeker) {
r.ResetBody() r.ResetBody()
} }
// SetStreamingBody set the reader to be used for the request that will stream
// bytes to the server. Request's Body must not be set to any reader.
func (r *Request) SetStreamingBody(reader io.ReadCloser) {
r.streamingBody = reader
r.SetReaderBody(aws.ReadSeekCloser(reader))
}
// Presign returns the request's signed URL. Error will be returned // Presign returns the request's signed URL. Error will be returned
// if the signing fails. The expire parameter is only used for presigned Amazon // if the signing fails. The expire parameter is only used for presigned Amazon
// S3 API requests. All other AWS services will use a fixed expiration // S3 API requests. All other AWS services will use a fixed expiration
@ -414,11 +424,17 @@ func (r *Request) Sign() error {
return r.Error return r.Error
} }
SanitizeHostForHeader(r.HTTPRequest)
r.Handlers.Sign.Run(r) r.Handlers.Sign.Run(r)
return r.Error return r.Error
} }
func (r *Request) getNextRequestBody() (body io.ReadCloser, err error) { func (r *Request) getNextRequestBody() (body io.ReadCloser, err error) {
if r.streamingBody != nil {
return r.streamingBody, nil
}
if r.safeBody != nil { if r.safeBody != nil {
r.safeBody.Close() r.safeBody.Close()
} }
@ -623,6 +639,10 @@ func getHost(r *http.Request) string {
return r.Host return r.Host
} }
if r.URL == nil {
return ""
}
return r.URL.Host return r.URL.Host
} }

View file

@ -17,11 +17,13 @@ import (
// does the pagination between API operations, and Paginator defines the // does the pagination between API operations, and Paginator defines the
// configuration that will be used per page request. // configuration that will be used per page request.
// //
// cont := true // for p.Next() {
// for p.Next() && cont {
// data := p.Page().(*s3.ListObjectsOutput) // data := p.Page().(*s3.ListObjectsOutput)
// // process the page's data // // process the page's data
// // ...
// // break out of loop to stop fetching additional pages
// } // }
//
// return p.Err() // return p.Err()
// //
// See service client API operation Pages methods for examples how the SDK will // See service client API operation Pages methods for examples how the SDK will

View file

@ -75,7 +75,7 @@ func (d noOpRetryer) RetryRules(_ *Request) time.Duration {
// retryableCodes is a collection of service response codes which are retry-able // retryableCodes is a collection of service response codes which are retry-able
// without any further action. // without any further action.
var retryableCodes = map[string]struct{}{ var retryableCodes = map[string]struct{}{
"RequestError": {}, ErrCodeRequestError: {},
"RequestTimeout": {}, "RequestTimeout": {},
ErrCodeResponseTimeout: {}, ErrCodeResponseTimeout: {},
"RequestTimeoutException": {}, // Glacier's flavor of RequestTimeout "RequestTimeoutException": {}, // Glacier's flavor of RequestTimeout
@ -83,6 +83,7 @@ var retryableCodes = map[string]struct{}{
var throttleCodes = map[string]struct{}{ var throttleCodes = map[string]struct{}{
"ProvisionedThroughputExceededException": {}, "ProvisionedThroughputExceededException": {},
"ThrottledException": {}, // SNS, XRay, ResourceGroupsTagging API
"Throttling": {}, "Throttling": {},
"ThrottlingException": {}, "ThrottlingException": {},
"RequestLimitExceeded": {}, "RequestLimitExceeded": {},
@ -91,6 +92,7 @@ var throttleCodes = map[string]struct{}{
"TooManyRequestsException": {}, // Lambda functions "TooManyRequestsException": {}, // Lambda functions
"PriorRequestNotComplete": {}, // Route53 "PriorRequestNotComplete": {}, // Route53
"TransactionInProgressException": {}, "TransactionInProgressException": {},
"EC2ThrottledException": {}, // EC2
} }
// credsExpiredCodes is a collection of error codes which signify the credentials // credsExpiredCodes is a collection of error codes which signify the credentials
@ -176,8 +178,8 @@ func shouldRetryError(origErr error) bool {
origErr := err.OrigErr() origErr := err.OrigErr()
var shouldRetry bool var shouldRetry bool
if origErr != nil { if origErr != nil {
shouldRetry := shouldRetryError(origErr) shouldRetry = shouldRetryError(origErr)
if err.Code() == "RequestError" && !shouldRetry { if err.Code() == ErrCodeRequestError && !shouldRetry {
return false return false
} }
} }

View file

@ -47,10 +47,10 @@ func resolveCredentials(cfg *aws.Config,
} }
// WebIdentityEmptyRoleARNErr will occur if 'AWS_WEB_IDENTITY_TOKEN_FILE' was set but // WebIdentityEmptyRoleARNErr will occur if 'AWS_WEB_IDENTITY_TOKEN_FILE' was set but
// 'AWS_IAM_ROLE_ARN' was not set. // 'AWS_ROLE_ARN' was not set.
var WebIdentityEmptyRoleARNErr = awserr.New(stscreds.ErrCodeWebIdentity, "role ARN is not set", nil) var WebIdentityEmptyRoleARNErr = awserr.New(stscreds.ErrCodeWebIdentity, "role ARN is not set", nil)
// WebIdentityEmptyTokenFilePathErr will occur if 'AWS_IAM_ROLE_ARN' was set but // WebIdentityEmptyTokenFilePathErr will occur if 'AWS_ROLE_ARN' was set but
// 'AWS_WEB_IDENTITY_TOKEN_FILE' was not set. // 'AWS_WEB_IDENTITY_TOKEN_FILE' was not set.
var WebIdentityEmptyTokenFilePathErr = awserr.New(stscreds.ErrCodeWebIdentity, "token file path is not set", nil) var WebIdentityEmptyTokenFilePathErr = awserr.New(stscreds.ErrCodeWebIdentity, "token file path is not set", nil)

View file

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"os" "os"
"strconv" "strconv"
"strings"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
@ -128,11 +129,25 @@ type envConfig struct {
// AWS_ROLE_SESSION_NAME=session_name // AWS_ROLE_SESSION_NAME=session_name
RoleSessionName string RoleSessionName string
// Specifies the Regional Endpoint flag for the sdk to resolve the endpoint for a service // Specifies the STS Regional Endpoint flag for the SDK to resolve the endpoint
// for a service.
// //
// AWS_STS_REGIONAL_ENDPOINTS =sts_regional_endpoint // AWS_STS_REGIONAL_ENDPOINTS=regional
// This can take value as `regional` or `legacy` // This can take value as `regional` or `legacy`
STSRegionalEndpoint endpoints.STSRegionalEndpoint STSRegionalEndpoint endpoints.STSRegionalEndpoint
// Specifies the S3 Regional Endpoint flag for the SDK to resolve the
// endpoint for a service.
//
// AWS_S3_US_EAST_1_REGIONAL_ENDPOINT=regional
// This can take value as `regional` or `legacy`
S3UsEast1RegionalEndpoint endpoints.S3UsEast1RegionalEndpoint
// Specifies if the S3 service should allow ARNs to direct the region
// the client's requests are sent to.
//
// AWS_S3_USE_ARN_REGION=true
S3UseARNRegion bool
} }
var ( var (
@ -190,6 +205,12 @@ var (
stsRegionalEndpointKey = []string{ stsRegionalEndpointKey = []string{
"AWS_STS_REGIONAL_ENDPOINTS", "AWS_STS_REGIONAL_ENDPOINTS",
} }
s3UsEast1RegionalEndpoint = []string{
"AWS_S3_US_EAST_1_REGIONAL_ENDPOINT",
}
s3UseARNRegionEnvKey = []string{
"AWS_S3_USE_ARN_REGION",
}
) )
// loadEnvConfig retrieves the SDK's environment configuration. // loadEnvConfig retrieves the SDK's environment configuration.
@ -275,14 +296,39 @@ func envConfigLoad(enableSharedConfig bool) (envConfig, error) {
cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE") cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE")
var err error
// STS Regional Endpoint variable // STS Regional Endpoint variable
for _, k := range stsRegionalEndpointKey { for _, k := range stsRegionalEndpointKey {
if v := os.Getenv(k); len(v) != 0 { if v := os.Getenv(k); len(v) != 0 {
STSRegionalEndpoint, err := endpoints.GetSTSRegionalEndpoint(v) cfg.STSRegionalEndpoint, err = endpoints.GetSTSRegionalEndpoint(v)
if err != nil { if err != nil {
return cfg, fmt.Errorf("failed to load, %v from env config, %v", k, err) return cfg, fmt.Errorf("failed to load, %v from env config, %v", k, err)
} }
cfg.STSRegionalEndpoint = STSRegionalEndpoint }
}
// S3 Regional Endpoint variable
for _, k := range s3UsEast1RegionalEndpoint {
if v := os.Getenv(k); len(v) != 0 {
cfg.S3UsEast1RegionalEndpoint, err = endpoints.GetS3UsEast1RegionalEndpoint(v)
if err != nil {
return cfg, fmt.Errorf("failed to load, %v from env config, %v", k, err)
}
}
}
var s3UseARNRegion string
setFromEnvVal(&s3UseARNRegion, s3UseARNRegionEnvKey)
if len(s3UseARNRegion) != 0 {
switch {
case strings.EqualFold(s3UseARNRegion, "false"):
cfg.S3UseARNRegion = false
case strings.EqualFold(s3UseARNRegion, "true"):
cfg.S3UseARNRegion = true
default:
return envConfig{}, fmt.Errorf(
"invalid value for environment variable, %s=%s, need true or false",
s3UseARNRegionEnvKey[0], s3UseARNRegion)
} }
} }

View file

@ -555,7 +555,20 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config,
} }
// Regional Endpoint flag for STS endpoint resolving // Regional Endpoint flag for STS endpoint resolving
mergeSTSRegionalEndpointConfig(cfg, envCfg, sharedCfg) mergeSTSRegionalEndpointConfig(cfg, []endpoints.STSRegionalEndpoint{
userCfg.STSRegionalEndpoint,
envCfg.STSRegionalEndpoint,
sharedCfg.STSRegionalEndpoint,
endpoints.LegacySTSEndpoint,
})
// Regional Endpoint flag for S3 endpoint resolving
mergeS3UsEast1RegionalEndpointConfig(cfg, []endpoints.S3UsEast1RegionalEndpoint{
userCfg.S3UsEast1RegionalEndpoint,
envCfg.S3UsEast1RegionalEndpoint,
sharedCfg.S3UsEast1RegionalEndpoint,
endpoints.LegacyS3UsEast1Endpoint,
})
// Configure credentials if not already set by the user when creating the // Configure credentials if not already set by the user when creating the
// Session. // Session.
@ -567,23 +580,33 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config,
cfg.Credentials = creds cfg.Credentials = creds
} }
cfg.S3UseARNRegion = userCfg.S3UseARNRegion
if cfg.S3UseARNRegion == nil {
cfg.S3UseARNRegion = &envCfg.S3UseARNRegion
}
if cfg.S3UseARNRegion == nil {
cfg.S3UseARNRegion = &sharedCfg.S3UseARNRegion
}
return nil return nil
} }
// mergeSTSRegionalEndpointConfig function merges the STSRegionalEndpoint into cfg from func mergeSTSRegionalEndpointConfig(cfg *aws.Config, values []endpoints.STSRegionalEndpoint) {
// envConfig and SharedConfig with envConfig being given precedence over SharedConfig for _, v := range values {
func mergeSTSRegionalEndpointConfig(cfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig) error { if v != endpoints.UnsetSTSEndpoint {
cfg.STSRegionalEndpoint = v
cfg.STSRegionalEndpoint = envCfg.STSRegionalEndpoint break
}
if cfg.STSRegionalEndpoint == endpoints.UnsetSTSEndpoint {
cfg.STSRegionalEndpoint = sharedCfg.STSRegionalEndpoint
} }
}
if cfg.STSRegionalEndpoint == endpoints.UnsetSTSEndpoint { func mergeS3UsEast1RegionalEndpointConfig(cfg *aws.Config, values []endpoints.S3UsEast1RegionalEndpoint) {
cfg.STSRegionalEndpoint = endpoints.LegacySTSEndpoint for _, v := range values {
if v != endpoints.UnsetS3UsEast1Endpoint {
cfg.S3UsEast1RegionalEndpoint = v
break
}
} }
return nil
} }
func initHandlers(s *Session) { func initHandlers(s *Session) {
@ -619,15 +642,22 @@ func (s *Session) ClientConfig(service string, cfgs ...*aws.Config) client.Confi
region := aws.StringValue(s.Config.Region) region := aws.StringValue(s.Config.Region)
resolved, err := s.resolveEndpoint(service, region, s.Config) resolved, err := s.resolveEndpoint(service, region, s.Config)
if err != nil && s.Config.Logger != nil { if err != nil {
s.Config.Logger.Log(fmt.Sprintf( s.Handlers.Validate.PushBack(func(r *request.Request) {
"ERROR: unable to resolve endpoint for service %q, region %q, err: %v", if len(r.ClientInfo.Endpoint) != 0 {
service, region, err)) // Error occurred while resolving endpoint, but the request
// being invoked has had an endpoint specified after the client
// was created.
return
}
r.Error = err
})
} }
return client.Config{ return client.Config{
Config: s.Config, Config: s.Config,
Handlers: s.Handlers, Handlers: s.Handlers,
PartitionID: resolved.PartitionID,
Endpoint: resolved.URL, Endpoint: resolved.URL,
SigningRegion: resolved.SigningRegion, SigningRegion: resolved.SigningRegion,
SigningNameDerived: resolved.SigningNameDerived, SigningNameDerived: resolved.SigningNameDerived,
@ -653,6 +683,11 @@ func (s *Session) resolveEndpoint(service, region string, cfg *aws.Config) (endp
// precedence. // precedence.
opt.STSRegionalEndpoint = cfg.STSRegionalEndpoint opt.STSRegionalEndpoint = cfg.STSRegionalEndpoint
// Support for S3UsEast1RegionalEndpoint where the S3UsEast1RegionalEndpoint is
// provided in envConfig or sharedConfig with envConfig getting
// precedence.
opt.S3UsEast1RegionalEndpoint = cfg.S3UsEast1RegionalEndpoint
// Support the condition where the service is modeled but its // Support the condition where the service is modeled but its
// endpoint metadata is not available. // endpoint metadata is not available.
opt.ResolveUnknownService = true opt.ResolveUnknownService = true

View file

@ -44,10 +44,16 @@ const (
// Additional config fields for regional or legacy endpoints // Additional config fields for regional or legacy endpoints
stsRegionalEndpointSharedKey = `sts_regional_endpoints` stsRegionalEndpointSharedKey = `sts_regional_endpoints`
// Additional config fields for regional or legacy endpoints
s3UsEast1RegionalSharedKey = `s3_us_east_1_regional_endpoint`
// DefaultSharedConfigProfile is the default profile to be used when // DefaultSharedConfigProfile is the default profile to be used when
// loading configuration from the config files if another profile name // loading configuration from the config files if another profile name
// is not provided. // is not provided.
DefaultSharedConfigProfile = `default` DefaultSharedConfigProfile = `default`
// S3 ARN Region Usage
s3UseARNRegionKey = "s3_use_arn_region"
) )
// sharedConfig represents the configuration fields of the SDK config files. // sharedConfig represents the configuration fields of the SDK config files.
@ -86,17 +92,30 @@ type sharedConfig struct {
// //
// endpoint_discovery_enabled = true // endpoint_discovery_enabled = true
EnableEndpointDiscovery *bool EnableEndpointDiscovery *bool
// CSM Options // CSM Options
CSMEnabled *bool CSMEnabled *bool
CSMHost string CSMHost string
CSMPort string CSMPort string
CSMClientID string CSMClientID string
// Specifies the Regional Endpoint flag for the sdk to resolve the endpoint for a service // Specifies the Regional Endpoint flag for the SDK to resolve the endpoint for a service
// //
// sts_regional_endpoints = sts_regional_endpoint // sts_regional_endpoints = regional
// This can take value as `LegacySTSEndpoint` or `RegionalSTSEndpoint` // This can take value as `LegacySTSEndpoint` or `RegionalSTSEndpoint`
STSRegionalEndpoint endpoints.STSRegionalEndpoint STSRegionalEndpoint endpoints.STSRegionalEndpoint
// Specifies the Regional Endpoint flag for the SDK to resolve the endpoint for a service
//
// s3_us_east_1_regional_endpoint = regional
// This can take value as `LegacyS3UsEast1Endpoint` or `RegionalS3UsEast1Endpoint`
S3UsEast1RegionalEndpoint endpoints.S3UsEast1RegionalEndpoint
// Specifies if the S3 service should allow ARNs to direct the region
// the client's requests are sent to.
//
// s3_use_arn_region=true
S3UseARNRegion bool
} }
type sharedConfigFile struct { type sharedConfigFile struct {
@ -259,10 +278,19 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e
sre, err := endpoints.GetSTSRegionalEndpoint(v) sre, err := endpoints.GetSTSRegionalEndpoint(v)
if err != nil { if err != nil {
return fmt.Errorf("failed to load %s from shared config, %s, %v", return fmt.Errorf("failed to load %s from shared config, %s, %v",
stsRegionalEndpointKey, file.Filename, err) stsRegionalEndpointSharedKey, file.Filename, err)
} }
cfg.STSRegionalEndpoint = sre cfg.STSRegionalEndpoint = sre
} }
if v := section.String(s3UsEast1RegionalSharedKey); len(v) != 0 {
sre, err := endpoints.GetS3UsEast1RegionalEndpoint(v)
if err != nil {
return fmt.Errorf("failed to load %s from shared config, %s, %v",
s3UsEast1RegionalSharedKey, file.Filename, err)
}
cfg.S3UsEast1RegionalEndpoint = sre
}
} }
updateString(&cfg.CredentialProcess, section, credentialProcessKey) updateString(&cfg.CredentialProcess, section, credentialProcessKey)
@ -288,6 +316,8 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e
updateString(&cfg.CSMPort, section, csmPortKey) updateString(&cfg.CSMPort, section, csmPortKey)
updateString(&cfg.CSMClientID, section, csmClientIDKey) updateString(&cfg.CSMClientID, section, csmClientIDKey)
updateBool(&cfg.S3UseARNRegion, section, s3UseARNRegionKey)
return nil return nil
} }
@ -380,6 +410,15 @@ func updateString(dst *string, section ini.Section, key string) {
*dst = section.String(key) *dst = section.String(key)
} }
// updateBool will only update the dst with the value in the section key, key
// is present in the section.
func updateBool(dst *bool, section ini.Section, key string) {
if !section.Has(key) {
return
}
*dst = section.Bool(key)
}
// updateBoolPtr will only update the dst with the value in the section key, // updateBoolPtr will only update the dst with the value in the section key,
// key is present in the section. // key is present in the section.
func updateBoolPtr(dst **bool, section ini.Section, key string) { func updateBoolPtr(dst **bool, section ini.Section, key string) {

View file

@ -1,8 +1,7 @@
package v4 package v4
import ( import (
"net/http" "github.com/aws/aws-sdk-go/internal/strings"
"strings"
) )
// validator houses a set of rule needed for validation of a // validator houses a set of rule needed for validation of a
@ -61,7 +60,7 @@ type patterns []string
// been found // been found
func (p patterns) IsValid(value string) bool { func (p patterns) IsValid(value string) bool {
for _, pattern := range p { for _, pattern := range p {
if strings.HasPrefix(http.CanonicalHeaderKey(value), pattern) { if strings.HasPrefixFold(value, pattern) {
return true return true
} }
} }

View file

@ -0,0 +1,13 @@
// +build !go1.7
package v4
import (
"net/http"
"github.com/aws/aws-sdk-go/aws"
)
func requestContext(r *http.Request) aws.Context {
return aws.BackgroundContext()
}

View file

@ -0,0 +1,13 @@
// +build go1.7
package v4
import (
"net/http"
"github.com/aws/aws-sdk-go/aws"
)
func requestContext(r *http.Request) aws.Context {
return r.Context()
}

View file

@ -0,0 +1,63 @@
package v4
import (
"encoding/hex"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws/credentials"
)
type credentialValueProvider interface {
Get() (credentials.Value, error)
}
// StreamSigner implements signing of event stream encoded payloads
type StreamSigner struct {
region string
service string
credentials credentialValueProvider
prevSig []byte
}
// NewStreamSigner creates a SigV4 signer used to sign Event Stream encoded messages
func NewStreamSigner(region, service string, seedSignature []byte, credentials *credentials.Credentials) *StreamSigner {
return &StreamSigner{
region: region,
service: service,
credentials: credentials,
prevSig: seedSignature,
}
}
// GetSignature takes an event stream encoded headers and payload and returns a signature
func (s *StreamSigner) GetSignature(headers, payload []byte, date time.Time) ([]byte, error) {
credValue, err := s.credentials.Get()
if err != nil {
return nil, err
}
sigKey := deriveSigningKey(s.region, s.service, credValue.SecretAccessKey, date)
keyPath := buildSigningScope(s.region, s.service, date)
stringToSign := buildEventStreamStringToSign(headers, payload, s.prevSig, keyPath, date)
signature := hmacSHA256(sigKey, []byte(stringToSign))
s.prevSig = signature
return signature, nil
}
func buildEventStreamStringToSign(headers, payload, prevSig []byte, scope string, date time.Time) string {
return strings.Join([]string{
"AWS4-HMAC-SHA256-PAYLOAD",
formatTime(date),
scope,
hex.EncodeToString(prevSig),
hex.EncodeToString(hashSHA256(headers)),
hex.EncodeToString(hashSHA256(payload)),
}, "\n")
}

View file

@ -76,9 +76,14 @@ import (
) )
const ( const (
authorizationHeader = "Authorization"
authHeaderSignatureElem = "Signature="
signatureQueryKey = "X-Amz-Signature"
authHeaderPrefix = "AWS4-HMAC-SHA256" authHeaderPrefix = "AWS4-HMAC-SHA256"
timeFormat = "20060102T150405Z" timeFormat = "20060102T150405Z"
shortTimeFormat = "20060102" shortTimeFormat = "20060102"
awsV4Request = "aws4_request"
// emptyStringSHA256 is a SHA256 of an empty string // emptyStringSHA256 is a SHA256 of an empty string
emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855` emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`
@ -87,9 +92,9 @@ const (
var ignoredHeaders = rules{ var ignoredHeaders = rules{
blacklist{ blacklist{
mapRule{ mapRule{
"Authorization": struct{}{}, authorizationHeader: struct{}{},
"User-Agent": struct{}{}, "User-Agent": struct{}{},
"X-Amzn-Trace-Id": struct{}{}, "X-Amzn-Trace-Id": struct{}{},
}, },
}, },
} }
@ -229,11 +234,9 @@ type signingCtx struct {
DisableURIPathEscaping bool DisableURIPathEscaping bool
credValues credentials.Value credValues credentials.Value
isPresign bool isPresign bool
formattedTime string unsignedPayload bool
formattedShortTime string
unsignedPayload bool
bodyDigest string bodyDigest string
signedHeaders string signedHeaders string
@ -337,7 +340,7 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
} }
var err error var err error
ctx.credValues, err = v4.Credentials.Get() ctx.credValues, err = v4.Credentials.GetWithContext(requestContext(r))
if err != nil { if err != nil {
return http.Header{}, err return http.Header{}, err
} }
@ -532,39 +535,56 @@ func (ctx *signingCtx) build(disableHeaderHoisting bool) error {
ctx.buildSignature() // depends on string to sign ctx.buildSignature() // depends on string to sign
if ctx.isPresign { if ctx.isPresign {
ctx.Request.URL.RawQuery += "&X-Amz-Signature=" + ctx.signature ctx.Request.URL.RawQuery += "&" + signatureQueryKey + "=" + ctx.signature
} else { } else {
parts := []string{ parts := []string{
authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString, authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString,
"SignedHeaders=" + ctx.signedHeaders, "SignedHeaders=" + ctx.signedHeaders,
"Signature=" + ctx.signature, authHeaderSignatureElem + ctx.signature,
} }
ctx.Request.Header.Set("Authorization", strings.Join(parts, ", ")) ctx.Request.Header.Set(authorizationHeader, strings.Join(parts, ", "))
} }
return nil return nil
} }
func (ctx *signingCtx) buildTime() { // GetSignedRequestSignature attempts to extract the signature of the request.
ctx.formattedTime = ctx.Time.UTC().Format(timeFormat) // Returning an error if the request is unsigned, or unable to extract the
ctx.formattedShortTime = ctx.Time.UTC().Format(shortTimeFormat) // signature.
func GetSignedRequestSignature(r *http.Request) ([]byte, error) {
if auth := r.Header.Get(authorizationHeader); len(auth) != 0 {
ps := strings.Split(auth, ", ")
for _, p := range ps {
if idx := strings.Index(p, authHeaderSignatureElem); idx >= 0 {
sig := p[len(authHeaderSignatureElem):]
if len(sig) == 0 {
return nil, fmt.Errorf("invalid request signature authorization header")
}
return hex.DecodeString(sig)
}
}
}
if sig := r.URL.Query().Get("X-Amz-Signature"); len(sig) != 0 {
return hex.DecodeString(sig)
}
return nil, fmt.Errorf("request not signed")
}
func (ctx *signingCtx) buildTime() {
if ctx.isPresign { if ctx.isPresign {
duration := int64(ctx.ExpireTime / time.Second) duration := int64(ctx.ExpireTime / time.Second)
ctx.Query.Set("X-Amz-Date", ctx.formattedTime) ctx.Query.Set("X-Amz-Date", formatTime(ctx.Time))
ctx.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10)) ctx.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10))
} else { } else {
ctx.Request.Header.Set("X-Amz-Date", ctx.formattedTime) ctx.Request.Header.Set("X-Amz-Date", formatTime(ctx.Time))
} }
} }
func (ctx *signingCtx) buildCredentialString() { func (ctx *signingCtx) buildCredentialString() {
ctx.credentialString = strings.Join([]string{ ctx.credentialString = buildSigningScope(ctx.Region, ctx.ServiceName, ctx.Time)
ctx.formattedShortTime,
ctx.Region,
ctx.ServiceName,
"aws4_request",
}, "/")
if ctx.isPresign { if ctx.isPresign {
ctx.Query.Set("X-Amz-Credential", ctx.credValues.AccessKeyID+"/"+ctx.credentialString) ctx.Query.Set("X-Amz-Credential", ctx.credValues.AccessKeyID+"/"+ctx.credentialString)
@ -588,8 +608,7 @@ func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) {
var headers []string var headers []string
headers = append(headers, "host") headers = append(headers, "host")
for k, v := range header { for k, v := range header {
canonicalKey := http.CanonicalHeaderKey(k) if !r.IsValid(k) {
if !r.IsValid(canonicalKey) {
continue // ignored header continue // ignored header
} }
if ctx.SignedHeaderVals == nil { if ctx.SignedHeaderVals == nil {
@ -653,19 +672,15 @@ func (ctx *signingCtx) buildCanonicalString() {
func (ctx *signingCtx) buildStringToSign() { func (ctx *signingCtx) buildStringToSign() {
ctx.stringToSign = strings.Join([]string{ ctx.stringToSign = strings.Join([]string{
authHeaderPrefix, authHeaderPrefix,
ctx.formattedTime, formatTime(ctx.Time),
ctx.credentialString, ctx.credentialString,
hex.EncodeToString(makeSha256([]byte(ctx.canonicalString))), hex.EncodeToString(hashSHA256([]byte(ctx.canonicalString))),
}, "\n") }, "\n")
} }
func (ctx *signingCtx) buildSignature() { func (ctx *signingCtx) buildSignature() {
secret := ctx.credValues.SecretAccessKey creds := deriveSigningKey(ctx.Region, ctx.ServiceName, ctx.credValues.SecretAccessKey, ctx.Time)
date := makeHmac([]byte("AWS4"+secret), []byte(ctx.formattedShortTime)) signature := hmacSHA256(creds, []byte(ctx.stringToSign))
region := makeHmac(date, []byte(ctx.Region))
service := makeHmac(region, []byte(ctx.ServiceName))
credentials := makeHmac(service, []byte("aws4_request"))
signature := makeHmac(credentials, []byte(ctx.stringToSign))
ctx.signature = hex.EncodeToString(signature) ctx.signature = hex.EncodeToString(signature)
} }
@ -726,13 +741,13 @@ func (ctx *signingCtx) removePresign() {
ctx.Query.Del("X-Amz-SignedHeaders") ctx.Query.Del("X-Amz-SignedHeaders")
} }
func makeHmac(key []byte, data []byte) []byte { func hmacSHA256(key []byte, data []byte) []byte {
hash := hmac.New(sha256.New, key) hash := hmac.New(sha256.New, key)
hash.Write(data) hash.Write(data)
return hash.Sum(nil) return hash.Sum(nil)
} }
func makeSha256(data []byte) []byte { func hashSHA256(data []byte) []byte {
hash := sha256.New() hash := sha256.New()
hash.Write(data) hash.Write(data)
return hash.Sum(nil) return hash.Sum(nil)
@ -804,3 +819,28 @@ func stripExcessSpaces(vals []string) {
vals[i] = string(buf[:m]) vals[i] = string(buf[:m])
} }
} }
func buildSigningScope(region, service string, dt time.Time) string {
return strings.Join([]string{
formatShortTime(dt),
region,
service,
awsV4Request,
}, "/")
}
func deriveSigningKey(region, service, secretKey string, dt time.Time) []byte {
kDate := hmacSHA256([]byte("AWS4"+secretKey), []byte(formatShortTime(dt)))
kRegion := hmacSHA256(kDate, []byte(region))
kService := hmacSHA256(kRegion, []byte(service))
signingKey := hmacSHA256(kService, []byte(awsV4Request))
return signingKey
}
func formatShortTime(dt time.Time) string {
return dt.UTC().Format(shortTimeFormat)
}
func formatTime(dt time.Time) string {
return dt.UTC().Format(timeFormat)
}

View file

@ -2,6 +2,7 @@ package aws
import ( import (
"io" "io"
"strings"
"sync" "sync"
"github.com/aws/aws-sdk-go/internal/sdkio" "github.com/aws/aws-sdk-go/internal/sdkio"
@ -205,3 +206,36 @@ func (b *WriteAtBuffer) Bytes() []byte {
defer b.m.Unlock() defer b.m.Unlock()
return b.buf return b.buf
} }
// MultiCloser is a utility to close multiple io.Closers within a single
// statement.
type MultiCloser []io.Closer
// Close closes all of the io.Closers making up the MultiClosers. Any
// errors that occur while closing will be returned in the order they
// occur.
func (m MultiCloser) Close() error {
var errs errors
for _, c := range m {
err := c.Close()
if err != nil {
errs = append(errs, err)
}
}
if len(errs) != 0 {
return errs
}
return nil
}
type errors []error
func (es errors) Error() string {
var parts []string
for _, e := range es {
parts = append(parts, e.Error())
}
return strings.Join(parts, "\n")
}

View file

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

View file

@ -0,0 +1,40 @@
// +build !go1.7
package context
import "time"
// An emptyCtx is a copy of the Go 1.7 context.emptyCtx type. This is copied to
// provide a 1.6 and 1.5 safe version of context that is compatible with Go
// 1.7's Context.
//
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
// struct{}, since vars of this type must have distinct addresses.
type emptyCtx int
func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
return
}
func (*emptyCtx) Done() <-chan struct{} {
return nil
}
func (*emptyCtx) Err() error {
return nil
}
func (*emptyCtx) Value(key interface{}) interface{} {
return nil
}
func (e *emptyCtx) String() string {
switch e {
case BackgroundCtx:
return "aws.BackgroundContext"
}
return "unknown empty Context"
}
// BackgroundCtx is the common base context.
var BackgroundCtx = new(emptyCtx)

View file

@ -0,0 +1,11 @@
package strings
import (
"strings"
)
// HasPrefixFold tests whether the string s begins with prefix, interpreted as UTF-8 strings,
// under Unicode case-folding.
func HasPrefixFold(s, prefix string) bool {
return len(s) >= len(prefix) && strings.EqualFold(s[0:len(prefix)], prefix)
}

View file

@ -0,0 +1,27 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,120 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package singleflight provides a duplicate function call suppression
// mechanism.
package singleflight
import "sync"
// call is an in-flight or completed singleflight.Do call
type call struct {
wg sync.WaitGroup
// These fields are written once before the WaitGroup is done
// and are only read after the WaitGroup is done.
val interface{}
err error
// forgotten indicates whether Forget was called with this call's key
// while the call was still in flight.
forgotten bool
// These fields are read and written with the singleflight
// mutex held before the WaitGroup is done, and are read but
// not written after the WaitGroup is done.
dups int
chans []chan<- Result
}
// Group represents a class of work and forms a namespace in
// which units of work can be executed with duplicate suppression.
type Group struct {
mu sync.Mutex // protects m
m map[string]*call // lazily initialized
}
// Result holds the results of Do, so they can be passed
// on a channel.
type Result struct {
Val interface{}
Err error
Shared bool
}
// Do executes and returns the results of the given function, making
// sure that only one execution is in-flight for a given key at a
// time. If a duplicate comes in, the duplicate caller waits for the
// original to complete and receives the same results.
// The return value shared indicates whether v was given to multiple callers.
func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool) {
g.mu.Lock()
if g.m == nil {
g.m = make(map[string]*call)
}
if c, ok := g.m[key]; ok {
c.dups++
g.mu.Unlock()
c.wg.Wait()
return c.val, c.err, true
}
c := new(call)
c.wg.Add(1)
g.m[key] = c
g.mu.Unlock()
g.doCall(c, key, fn)
return c.val, c.err, c.dups > 0
}
// DoChan is like Do but returns a channel that will receive the
// results when they are ready.
func (g *Group) DoChan(key string, fn func() (interface{}, error)) <-chan Result {
ch := make(chan Result, 1)
g.mu.Lock()
if g.m == nil {
g.m = make(map[string]*call)
}
if c, ok := g.m[key]; ok {
c.dups++
c.chans = append(c.chans, ch)
g.mu.Unlock()
return ch
}
c := &call{chans: []chan<- Result{ch}}
c.wg.Add(1)
g.m[key] = c
g.mu.Unlock()
go g.doCall(c, key, fn)
return ch
}
// doCall handles the single call for a key.
func (g *Group) doCall(c *call, key string, fn func() (interface{}, error)) {
c.val, c.err = fn()
c.wg.Done()
g.mu.Lock()
if !c.forgotten {
delete(g.m, key)
}
for _, ch := range c.chans {
ch <- Result{c.val, c.err, c.dups > 0}
}
g.mu.Unlock()
}
// Forget tells the singleflight to forget about a key. Future calls
// to Do for this key will call the function rather than waiting for
// an earlier call to complete.
func (g *Group) Forget(key string) {
g.mu.Lock()
if c, ok := g.m[key]; ok {
c.forgotten = true
}
delete(g.m, key)
g.mu.Unlock()
}

View file

@ -101,7 +101,7 @@ func (hs *decodedHeaders) UnmarshalJSON(b []byte) error {
} }
headers.Set(h.Name, value) headers.Set(h.Name, value)
} }
(*hs) = decodedHeaders(headers) *hs = decodedHeaders(headers)
return nil return nil
} }

View file

@ -21,10 +21,24 @@ type Decoder struct {
// NewDecoder initializes and returns a Decoder for decoding event // NewDecoder initializes and returns a Decoder for decoding event
// stream messages from the reader provided. // stream messages from the reader provided.
func NewDecoder(r io.Reader) *Decoder { func NewDecoder(r io.Reader, opts ...func(*Decoder)) *Decoder {
return &Decoder{ d := &Decoder{
r: r, r: r,
} }
for _, opt := range opts {
opt(d)
}
return d
}
// DecodeWithLogger adds a logger to be used by the decoder when decoding
// stream events.
func DecodeWithLogger(logger aws.Logger) func(*Decoder) {
return func(d *Decoder) {
d.logger = logger
}
} }
// Decode attempts to decode a single message from the event stream reader. // Decode attempts to decode a single message from the event stream reader.
@ -40,6 +54,15 @@ func (d *Decoder) Decode(payloadBuf []byte) (m Message, err error) {
}() }()
} }
m, err = Decode(reader, payloadBuf)
return m, err
}
// Decode attempts to decode a single message from the event stream reader.
// Will return the event stream message, or error if Decode fails to read
// the message from the reader.
func Decode(reader io.Reader, payloadBuf []byte) (m Message, err error) {
crc := crc32.New(crc32IEEETable) crc := crc32.New(crc32IEEETable)
hashReader := io.TeeReader(reader, crc) hashReader := io.TeeReader(reader, crc)
@ -72,12 +95,6 @@ func (d *Decoder) Decode(payloadBuf []byte) (m Message, err error) {
return m, nil return m, nil
} }
// UseLogger specifies the Logger that that the decoder should use to log the
// message decode to.
func (d *Decoder) UseLogger(logger aws.Logger) {
d.logger = logger
}
func logMessageDecode(logger aws.Logger, msgBuf *bytes.Buffer, msg Message, decodeErr error) { func logMessageDecode(logger aws.Logger, msgBuf *bytes.Buffer, msg Message, decodeErr error) {
w := bytes.NewBuffer(nil) w := bytes.NewBuffer(nil)
defer func() { logger.Log(w.String()) }() defer func() { logger.Log(w.String()) }()

View file

@ -3,61 +3,107 @@ package eventstream
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"encoding/hex"
"encoding/json"
"fmt"
"hash" "hash"
"hash/crc32" "hash/crc32"
"io" "io"
"github.com/aws/aws-sdk-go/aws"
) )
// Encoder provides EventStream message encoding. // Encoder provides EventStream message encoding.
type Encoder struct { type Encoder struct {
w io.Writer w io.Writer
logger aws.Logger
headersBuf *bytes.Buffer headersBuf *bytes.Buffer
} }
// NewEncoder initializes and returns an Encoder to encode Event Stream // NewEncoder initializes and returns an Encoder to encode Event Stream
// messages to an io.Writer. // messages to an io.Writer.
func NewEncoder(w io.Writer) *Encoder { func NewEncoder(w io.Writer, opts ...func(*Encoder)) *Encoder {
return &Encoder{ e := &Encoder{
w: w, w: w,
headersBuf: bytes.NewBuffer(nil), headersBuf: bytes.NewBuffer(nil),
} }
for _, opt := range opts {
opt(e)
}
return e
}
// EncodeWithLogger adds a logger to be used by the encode when decoding
// stream events.
func EncodeWithLogger(logger aws.Logger) func(*Encoder) {
return func(d *Encoder) {
d.logger = logger
}
} }
// Encode encodes a single EventStream message to the io.Writer the Encoder // Encode encodes a single EventStream message to the io.Writer the Encoder
// was created with. An error is returned if writing the message fails. // was created with. An error is returned if writing the message fails.
func (e *Encoder) Encode(msg Message) error { func (e *Encoder) Encode(msg Message) (err error) {
e.headersBuf.Reset() e.headersBuf.Reset()
err := encodeHeaders(e.headersBuf, msg.Headers) writer := e.w
if err != nil { if e.logger != nil {
encodeMsgBuf := bytes.NewBuffer(nil)
writer = io.MultiWriter(writer, encodeMsgBuf)
defer func() {
logMessageEncode(e.logger, encodeMsgBuf, msg, err)
}()
}
if err = EncodeHeaders(e.headersBuf, msg.Headers); err != nil {
return err return err
} }
crc := crc32.New(crc32IEEETable) crc := crc32.New(crc32IEEETable)
hashWriter := io.MultiWriter(e.w, crc) hashWriter := io.MultiWriter(writer, crc)
headersLen := uint32(e.headersBuf.Len()) headersLen := uint32(e.headersBuf.Len())
payloadLen := uint32(len(msg.Payload)) payloadLen := uint32(len(msg.Payload))
if err := encodePrelude(hashWriter, crc, headersLen, payloadLen); err != nil { if err = encodePrelude(hashWriter, crc, headersLen, payloadLen); err != nil {
return err return err
} }
if headersLen > 0 { if headersLen > 0 {
if _, err := io.Copy(hashWriter, e.headersBuf); err != nil { if _, err = io.Copy(hashWriter, e.headersBuf); err != nil {
return err return err
} }
} }
if payloadLen > 0 { if payloadLen > 0 {
if _, err := hashWriter.Write(msg.Payload); err != nil { if _, err = hashWriter.Write(msg.Payload); err != nil {
return err return err
} }
} }
msgCRC := crc.Sum32() msgCRC := crc.Sum32()
return binary.Write(e.w, binary.BigEndian, msgCRC) return binary.Write(writer, binary.BigEndian, msgCRC)
}
func logMessageEncode(logger aws.Logger, msgBuf *bytes.Buffer, msg Message, encodeErr error) {
w := bytes.NewBuffer(nil)
defer func() { logger.Log(w.String()) }()
fmt.Fprintf(w, "Message to encode:\n")
encoder := json.NewEncoder(w)
if err := encoder.Encode(msg); err != nil {
fmt.Fprintf(w, "Failed to get encoded message, %v\n", err)
}
if encodeErr != nil {
fmt.Fprintf(w, "Encode error: %v\n", encodeErr)
return
}
fmt.Fprintf(w, "Raw message:\n%s\n", hex.Dump(msgBuf.Bytes()))
} }
func encodePrelude(w io.Writer, crc hash.Hash32, headersLen, payloadLen uint32) error { func encodePrelude(w io.Writer, crc hash.Hash32, headersLen, payloadLen uint32) error {
@ -86,7 +132,9 @@ func encodePrelude(w io.Writer, crc hash.Hash32, headersLen, payloadLen uint32)
return nil return nil
} }
func encodeHeaders(w io.Writer, headers Headers) error { // EncodeHeaders writes the header values to the writer encoded in the event
// stream format. Returns an error if a header fails to encode.
func EncodeHeaders(w io.Writer, headers Headers) error {
for _, h := range headers { for _, h := range headers {
hn := headerName{ hn := headerName{
Len: uint8(len(h.Name)), Len: uint8(len(h.Name)),

View file

@ -1,6 +1,9 @@
package eventstreamapi package eventstreamapi
import "fmt" import (
"fmt"
"sync"
)
type messageError struct { type messageError struct {
code string code string
@ -22,3 +25,53 @@ func (e messageError) Error() string {
func (e messageError) OrigErr() error { func (e messageError) OrigErr() error {
return nil return nil
} }
// OnceError wraps the behavior of recording an error
// once and signal on a channel when this has occurred.
// Signaling is done by closing of the channel.
//
// Type is safe for concurrent usage.
type OnceError struct {
mu sync.RWMutex
err error
ch chan struct{}
}
// NewOnceError return a new OnceError
func NewOnceError() *OnceError {
return &OnceError{
ch: make(chan struct{}, 1),
}
}
// Err acquires a read-lock and returns an
// error if one has been set.
func (e *OnceError) Err() error {
e.mu.RLock()
err := e.err
e.mu.RUnlock()
return err
}
// SetError acquires a write-lock and will set
// the underlying error value if one has not been set.
func (e *OnceError) SetError(err error) {
if err == nil {
return
}
e.mu.Lock()
if e.err == nil {
e.err = err
close(e.ch)
}
e.mu.Unlock()
}
// ErrorSet returns a channel that will be used to signal
// that an error has been set. This channel will be closed
// when the error value has been set for OnceError.
func (e *OnceError) ErrorSet() <-chan struct{} {
return e.ch
}

View file

@ -2,9 +2,7 @@ package eventstreamapi
import ( import (
"fmt" "fmt"
"io"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/private/protocol" "github.com/aws/aws-sdk-go/private/protocol"
"github.com/aws/aws-sdk-go/private/protocol/eventstream" "github.com/aws/aws-sdk-go/private/protocol/eventstream"
) )
@ -15,27 +13,8 @@ type Unmarshaler interface {
UnmarshalEvent(protocol.PayloadUnmarshaler, eventstream.Message) error UnmarshalEvent(protocol.PayloadUnmarshaler, eventstream.Message) error
} }
// EventStream headers with specific meaning to async API functionality.
const (
MessageTypeHeader = `:message-type` // Identifies type of message.
EventMessageType = `event`
ErrorMessageType = `error`
ExceptionMessageType = `exception`
// Message Events
EventTypeHeader = `:event-type` // Identifies message event type e.g. "Stats".
// Message Error
ErrorCodeHeader = `:error-code`
ErrorMessageHeader = `:error-message`
// Message Exception
ExceptionTypeHeader = `:exception-type`
)
// EventReader provides reading from the EventStream of an reader. // EventReader provides reading from the EventStream of an reader.
type EventReader struct { type EventReader struct {
reader io.ReadCloser
decoder *eventstream.Decoder decoder *eventstream.Decoder
unmarshalerForEventType func(string) (Unmarshaler, error) unmarshalerForEventType func(string) (Unmarshaler, error)
@ -47,27 +26,18 @@ type EventReader struct {
// NewEventReader returns a EventReader built from the reader and unmarshaler // NewEventReader returns a EventReader built from the reader and unmarshaler
// provided. Use ReadStream method to start reading from the EventStream. // provided. Use ReadStream method to start reading from the EventStream.
func NewEventReader( func NewEventReader(
reader io.ReadCloser, decoder *eventstream.Decoder,
payloadUnmarshaler protocol.PayloadUnmarshaler, payloadUnmarshaler protocol.PayloadUnmarshaler,
unmarshalerForEventType func(string) (Unmarshaler, error), unmarshalerForEventType func(string) (Unmarshaler, error),
) *EventReader { ) *EventReader {
return &EventReader{ return &EventReader{
reader: reader, decoder: decoder,
decoder: eventstream.NewDecoder(reader),
payloadUnmarshaler: payloadUnmarshaler, payloadUnmarshaler: payloadUnmarshaler,
unmarshalerForEventType: unmarshalerForEventType, unmarshalerForEventType: unmarshalerForEventType,
payloadBuf: make([]byte, 10*1024), payloadBuf: make([]byte, 10*1024),
} }
} }
// UseLogger instructs the EventReader to use the logger and log level
// specified.
func (r *EventReader) UseLogger(logger aws.Logger, logLevel aws.LogLevelType) {
if logger != nil && logLevel.Matches(aws.LogDebugWithEventStreamBody) {
r.decoder.UseLogger(logger)
}
}
// ReadEvent attempts to read a message from the EventStream and return the // ReadEvent attempts to read a message from the EventStream and return the
// unmarshaled event value that the message is for. // unmarshaled event value that the message is for.
// //
@ -95,8 +65,7 @@ func (r *EventReader) ReadEvent() (event interface{}, err error) {
case EventMessageType: case EventMessageType:
return r.unmarshalEventMessage(msg) return r.unmarshalEventMessage(msg)
case ExceptionMessageType: case ExceptionMessageType:
err = r.unmarshalEventException(msg) return nil, r.unmarshalEventException(msg)
return nil, err
case ErrorMessageType: case ErrorMessageType:
return nil, r.unmarshalErrorMessage(msg) return nil, r.unmarshalErrorMessage(msg)
default: default:
@ -174,11 +143,6 @@ func (r *EventReader) unmarshalErrorMessage(msg eventstream.Message) (err error)
return msgErr return msgErr
} }
// Close closes the EventReader's EventStream reader.
func (r *EventReader) Close() error {
return r.reader.Close()
}
// GetHeaderString returns the value of the header as a string. If the header // GetHeaderString returns the value of the header as a string. If the header
// is not set or the value is not a string an error will be returned. // is not set or the value is not a string an error will be returned.
func GetHeaderString(msg eventstream.Message, headerName string) (string, error) { func GetHeaderString(msg eventstream.Message, headerName string) (string, error) {

View file

@ -0,0 +1,23 @@
package eventstreamapi
// EventStream headers with specific meaning to async API functionality.
const (
ChunkSignatureHeader = `:chunk-signature` // chunk signature for message
DateHeader = `:date` // Date header for signature
// Message header and values
MessageTypeHeader = `:message-type` // Identifies type of message.
EventMessageType = `event`
ErrorMessageType = `error`
ExceptionMessageType = `exception`
// Message Events
EventTypeHeader = `:event-type` // Identifies message event type e.g. "Stats".
// Message Error
ErrorCodeHeader = `:error-code`
ErrorMessageHeader = `:error-message`
// Message Exception
ExceptionTypeHeader = `:exception-type`
)

View file

@ -0,0 +1,123 @@
package eventstreamapi
import (
"bytes"
"strings"
"time"
"github.com/aws/aws-sdk-go/private/protocol/eventstream"
)
var timeNow = time.Now
// StreamSigner defines an interface for the implementation of signing of event stream payloads
type StreamSigner interface {
GetSignature(headers, payload []byte, date time.Time) ([]byte, error)
}
// SignEncoder envelopes event stream messages
// into an event stream message payload with included
// signature headers using the provided signer and encoder.
type SignEncoder struct {
signer StreamSigner
encoder Encoder
bufEncoder *BufferEncoder
closeErr error
closed bool
}
// NewSignEncoder returns a new SignEncoder using the provided stream signer and
// event stream encoder.
func NewSignEncoder(signer StreamSigner, encoder Encoder) *SignEncoder {
// TODO: Need to pass down logging
return &SignEncoder{
signer: signer,
encoder: encoder,
bufEncoder: NewBufferEncoder(),
}
}
// Close encodes a final event stream signing envelope with an empty event stream
// payload. This final end-frame is used to mark the conclusion of the stream.
func (s *SignEncoder) Close() error {
if s.closed {
return s.closeErr
}
if err := s.encode([]byte{}); err != nil {
if strings.Contains(err.Error(), "on closed pipe") {
return nil
}
s.closeErr = err
s.closed = true
return s.closeErr
}
return nil
}
// Encode takes the provided message and add envelopes the message
// with the required signature.
func (s *SignEncoder) Encode(msg eventstream.Message) error {
payload, err := s.bufEncoder.Encode(msg)
if err != nil {
return err
}
return s.encode(payload)
}
func (s SignEncoder) encode(payload []byte) error {
date := timeNow()
var msg eventstream.Message
msg.Headers.Set(DateHeader, eventstream.TimestampValue(date))
msg.Payload = payload
var headers bytes.Buffer
if err := eventstream.EncodeHeaders(&headers, msg.Headers); err != nil {
return err
}
sig, err := s.signer.GetSignature(headers.Bytes(), msg.Payload, date)
if err != nil {
return err
}
msg.Headers.Set(ChunkSignatureHeader, eventstream.BytesValue(sig))
return s.encoder.Encode(msg)
}
// BufferEncoder is a utility that provides a buffered
// event stream encoder
type BufferEncoder struct {
encoder Encoder
buffer *bytes.Buffer
}
// NewBufferEncoder returns a new BufferEncoder initialized
// with a 1024 byte buffer.
func NewBufferEncoder() *BufferEncoder {
buf := bytes.NewBuffer(make([]byte, 1024))
return &BufferEncoder{
encoder: eventstream.NewEncoder(buf),
buffer: buf,
}
}
// Encode returns the encoded message as a byte slice.
// The returned byte slice will be modified on the next encode call
// and should not be held onto.
func (e *BufferEncoder) Encode(msg eventstream.Message) ([]byte, error) {
e.buffer.Reset()
if err := e.encoder.Encode(msg); err != nil {
return nil, err
}
return e.buffer.Bytes(), nil
}

View file

@ -0,0 +1,129 @@
package eventstreamapi
import (
"fmt"
"io"
"sync"
"github.com/aws/aws-sdk-go/aws"
)
// StreamWriter provides concurrent safe writing to an event stream.
type StreamWriter struct {
eventWriter *EventWriter
stream chan eventWriteAsyncReport
done chan struct{}
closeOnce sync.Once
err *OnceError
streamCloser io.Closer
}
// NewStreamWriter returns a StreamWriter for the event writer, and stream
// closer provided.
func NewStreamWriter(eventWriter *EventWriter, streamCloser io.Closer) *StreamWriter {
w := &StreamWriter{
eventWriter: eventWriter,
streamCloser: streamCloser,
stream: make(chan eventWriteAsyncReport),
done: make(chan struct{}),
err: NewOnceError(),
}
go w.writeStream()
return w
}
// Close terminates the writers ability to write new events to the stream. Any
// future call to Send will fail with an error.
func (w *StreamWriter) Close() error {
w.closeOnce.Do(w.safeClose)
return w.Err()
}
func (w *StreamWriter) safeClose() {
close(w.done)
}
// ErrorSet returns a channel which will be closed
// if an error occurs.
func (w *StreamWriter) ErrorSet() <-chan struct{} {
return w.err.ErrorSet()
}
// Err returns any error that occurred while attempting to write an event to the
// stream.
func (w *StreamWriter) Err() error {
return w.err.Err()
}
// Send writes a single event to the stream returning an error if the write
// failed.
//
// Send may be called concurrently. Events will be written to the stream
// safely.
func (w *StreamWriter) Send(ctx aws.Context, event Marshaler) error {
if err := w.Err(); err != nil {
return err
}
resultCh := make(chan error)
wrapped := eventWriteAsyncReport{
Event: event,
Result: resultCh,
}
select {
case w.stream <- wrapped:
case <-ctx.Done():
return ctx.Err()
case <-w.done:
return fmt.Errorf("stream closed, unable to send event")
}
select {
case err := <-resultCh:
return err
case <-ctx.Done():
return ctx.Err()
case <-w.done:
return fmt.Errorf("stream closed, unable to send event")
}
}
func (w *StreamWriter) writeStream() {
defer w.Close()
for {
select {
case wrapper := <-w.stream:
err := w.eventWriter.WriteEvent(wrapper.Event)
wrapper.ReportResult(w.done, err)
if err != nil {
w.err.SetError(err)
return
}
case <-w.done:
if err := w.streamCloser.Close(); err != nil {
w.err.SetError(err)
}
return
}
}
}
type eventWriteAsyncReport struct {
Event Marshaler
Result chan<- error
}
func (e eventWriteAsyncReport) ReportResult(cancel <-chan struct{}, err error) bool {
select {
case e.Result <- err:
return true
case <-cancel:
return false
}
}

View file

@ -0,0 +1,109 @@
package eventstreamapi
import (
"github.com/aws/aws-sdk-go/private/protocol"
"github.com/aws/aws-sdk-go/private/protocol/eventstream"
)
// Marshaler provides a marshaling interface for event types to event stream
// messages.
type Marshaler interface {
MarshalEvent(protocol.PayloadMarshaler) (eventstream.Message, error)
}
// Encoder is an stream encoder that will encode an event stream message for
// the transport.
type Encoder interface {
Encode(eventstream.Message) error
}
// EventWriter provides a wrapper around the underlying event stream encoder
// for an io.WriteCloser.
type EventWriter struct {
encoder Encoder
payloadMarshaler protocol.PayloadMarshaler
eventTypeFor func(Marshaler) (string, error)
}
// NewEventWriter returns a new event stream writer, that will write to the
// writer provided. Use the WriteEvent method to write an event to the stream.
func NewEventWriter(encoder Encoder, pm protocol.PayloadMarshaler, eventTypeFor func(Marshaler) (string, error),
) *EventWriter {
return &EventWriter{
encoder: encoder,
payloadMarshaler: pm,
eventTypeFor: eventTypeFor,
}
}
// WriteEvent writes an event to the stream. Returns an error if the event
// fails to marshal into a message, or writing to the underlying writer fails.
func (w *EventWriter) WriteEvent(event Marshaler) error {
msg, err := w.marshal(event)
if err != nil {
return err
}
return w.encoder.Encode(msg)
}
func (w *EventWriter) marshal(event Marshaler) (eventstream.Message, error) {
eventType, err := w.eventTypeFor(event)
if err != nil {
return eventstream.Message{}, err
}
msg, err := event.MarshalEvent(w.payloadMarshaler)
if err != nil {
return eventstream.Message{}, err
}
msg.Headers.Set(EventTypeHeader, eventstream.StringValue(eventType))
return msg, nil
}
//type EventEncoder struct {
// encoder Encoder
// ppayloadMarshaler protocol.PayloadMarshaler
// eventTypeFor func(Marshaler) (string, error)
//}
//
//func (e EventEncoder) Encode(event Marshaler) error {
// msg, err := e.marshal(event)
// if err != nil {
// return err
// }
//
// return w.encoder.Encode(msg)
//}
//
//func (e EventEncoder) marshal(event Marshaler) (eventstream.Message, error) {
// eventType, err := w.eventTypeFor(event)
// if err != nil {
// return eventstream.Message{}, err
// }
//
// msg, err := event.MarshalEvent(w.payloadMarshaler)
// if err != nil {
// return eventstream.Message{}, err
// }
//
// msg.Headers.Set(EventTypeHeader, eventstream.StringValue(eventType))
// return msg, nil
//}
//
//func (w *EventWriter) marshal(event Marshaler) (eventstream.Message, error) {
// eventType, err := w.eventTypeFor(event)
// if err != nil {
// return eventstream.Message{}, err
// }
//
// msg, err := event.MarshalEvent(w.payloadMarshaler)
// if err != nil {
// return eventstream.Message{}, err
// }
//
// msg.Headers.Set(EventTypeHeader, eventstream.StringValue(eventType))
// return msg, nil
//}
//

View file

@ -461,6 +461,11 @@ func (v *TimestampValue) decode(r io.Reader) error {
return nil return nil
} }
// MarshalJSON implements the json.Marshaler interface
func (v TimestampValue) MarshalJSON() ([]byte, error) {
return []byte(v.String()), nil
}
func timeFromEpochMilli(t int64) time.Time { func timeFromEpochMilli(t int64) time.Time {
secs := t / 1e3 secs := t / 1e3
msec := t % 1e3 msec := t % 1e3

View file

@ -27,7 +27,7 @@ func (m *Message) rawMessage() (rawMessage, error) {
if len(m.Headers) > 0 { if len(m.Headers) > 0 {
var headers bytes.Buffer var headers bytes.Buffer
if err := encodeHeaders(&headers, m.Headers); err != nil { if err := EncodeHeaders(&headers, m.Headers); err != nil {
return rawMessage{}, err return rawMessage{}, err
} }
raw.Headers = headers.Bytes() raw.Headers = headers.Bytes()

View file

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"io" "io"
"reflect" "reflect"
"strings"
"time" "time"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
@ -45,10 +46,31 @@ func UnmarshalJSON(v interface{}, stream io.Reader) error {
return err return err
} }
return unmarshalAny(reflect.ValueOf(v), out, "") return unmarshaler{}.unmarshalAny(reflect.ValueOf(v), out, "")
} }
func unmarshalAny(value reflect.Value, data interface{}, tag reflect.StructTag) error { // UnmarshalJSONCaseInsensitive reads a stream and unmarshals the result into the
// object v. Ignores casing for structure members.
func UnmarshalJSONCaseInsensitive(v interface{}, stream io.Reader) error {
var out interface{}
err := json.NewDecoder(stream).Decode(&out)
if err == io.EOF {
return nil
} else if err != nil {
return err
}
return unmarshaler{
caseInsensitive: true,
}.unmarshalAny(reflect.ValueOf(v), out, "")
}
type unmarshaler struct {
caseInsensitive bool
}
func (u unmarshaler) unmarshalAny(value reflect.Value, data interface{}, tag reflect.StructTag) error {
vtype := value.Type() vtype := value.Type()
if vtype.Kind() == reflect.Ptr { if vtype.Kind() == reflect.Ptr {
vtype = vtype.Elem() // check kind of actual element type vtype = vtype.Elem() // check kind of actual element type
@ -80,17 +102,17 @@ func unmarshalAny(value reflect.Value, data interface{}, tag reflect.StructTag)
if field, ok := vtype.FieldByName("_"); ok { if field, ok := vtype.FieldByName("_"); ok {
tag = field.Tag tag = field.Tag
} }
return unmarshalStruct(value, data, tag) return u.unmarshalStruct(value, data, tag)
case "list": case "list":
return unmarshalList(value, data, tag) return u.unmarshalList(value, data, tag)
case "map": case "map":
return unmarshalMap(value, data, tag) return u.unmarshalMap(value, data, tag)
default: default:
return unmarshalScalar(value, data, tag) return u.unmarshalScalar(value, data, tag)
} }
} }
func unmarshalStruct(value reflect.Value, data interface{}, tag reflect.StructTag) error { func (u unmarshaler) unmarshalStruct(value reflect.Value, data interface{}, tag reflect.StructTag) error {
if data == nil { if data == nil {
return nil return nil
} }
@ -114,7 +136,7 @@ func unmarshalStruct(value reflect.Value, data interface{}, tag reflect.StructTa
// unwrap any payloads // unwrap any payloads
if payload := tag.Get("payload"); payload != "" { if payload := tag.Get("payload"); payload != "" {
field, _ := t.FieldByName(payload) field, _ := t.FieldByName(payload)
return unmarshalAny(value.FieldByName(payload), data, field.Tag) return u.unmarshalAny(value.FieldByName(payload), data, field.Tag)
} }
for i := 0; i < t.NumField(); i++ { for i := 0; i < t.NumField(); i++ {
@ -128,9 +150,19 @@ func unmarshalStruct(value reflect.Value, data interface{}, tag reflect.StructTa
if locName := field.Tag.Get("locationName"); locName != "" { if locName := field.Tag.Get("locationName"); locName != "" {
name = locName name = locName
} }
if u.caseInsensitive {
if _, ok := mapData[name]; !ok {
// Fallback to uncased name search if the exact name didn't match.
for kn, v := range mapData {
if strings.EqualFold(kn, name) {
mapData[name] = v
}
}
}
}
member := value.FieldByIndex(field.Index) member := value.FieldByIndex(field.Index)
err := unmarshalAny(member, mapData[name], field.Tag) err := u.unmarshalAny(member, mapData[name], field.Tag)
if err != nil { if err != nil {
return err return err
} }
@ -138,7 +170,7 @@ func unmarshalStruct(value reflect.Value, data interface{}, tag reflect.StructTa
return nil return nil
} }
func unmarshalList(value reflect.Value, data interface{}, tag reflect.StructTag) error { func (u unmarshaler) unmarshalList(value reflect.Value, data interface{}, tag reflect.StructTag) error {
if data == nil { if data == nil {
return nil return nil
} }
@ -153,7 +185,7 @@ func unmarshalList(value reflect.Value, data interface{}, tag reflect.StructTag)
} }
for i, c := range listData { for i, c := range listData {
err := unmarshalAny(value.Index(i), c, "") err := u.unmarshalAny(value.Index(i), c, "")
if err != nil { if err != nil {
return err return err
} }
@ -162,7 +194,7 @@ func unmarshalList(value reflect.Value, data interface{}, tag reflect.StructTag)
return nil return nil
} }
func unmarshalMap(value reflect.Value, data interface{}, tag reflect.StructTag) error { func (u unmarshaler) unmarshalMap(value reflect.Value, data interface{}, tag reflect.StructTag) error {
if data == nil { if data == nil {
return nil return nil
} }
@ -179,14 +211,14 @@ func unmarshalMap(value reflect.Value, data interface{}, tag reflect.StructTag)
kvalue := reflect.ValueOf(k) kvalue := reflect.ValueOf(k)
vvalue := reflect.New(value.Type().Elem()).Elem() vvalue := reflect.New(value.Type().Elem()).Elem()
unmarshalAny(vvalue, v, "") u.unmarshalAny(vvalue, v, "")
value.SetMapIndex(kvalue, vvalue) value.SetMapIndex(kvalue, vvalue)
} }
return nil return nil
} }
func unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTag) error { func (u unmarshaler) unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTag) error {
switch d := data.(type) { switch d := data.(type) {
case nil: case nil:

View file

@ -64,7 +64,7 @@ func (h HandlerPayloadMarshal) MarshalPayload(w io.Writer, v interface{}) error
metadata.ClientInfo{}, metadata.ClientInfo{},
request.Handlers{}, request.Handlers{},
nil, nil,
&request.Operation{HTTPMethod: "GET"}, &request.Operation{HTTPMethod: "PUT"},
v, v,
nil, nil,
) )

View file

@ -0,0 +1,49 @@
package protocol
import (
"fmt"
"strings"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
)
// RequireHTTPMinProtocol request handler is used to enforce that
// the target endpoint supports the given major and minor HTTP protocol version.
type RequireHTTPMinProtocol struct {
Major, Minor int
}
// Handler will mark the request.Request with an error if the
// target endpoint did not connect with the required HTTP protocol
// major and minor version.
func (p RequireHTTPMinProtocol) Handler(r *request.Request) {
if r.Error != nil || r.HTTPResponse == nil {
return
}
if !strings.HasPrefix(r.HTTPResponse.Proto, "HTTP") {
r.Error = newMinHTTPProtoError(p.Major, p.Minor, r)
}
if r.HTTPResponse.ProtoMajor < p.Major || r.HTTPResponse.ProtoMinor < p.Minor {
r.Error = newMinHTTPProtoError(p.Major, p.Minor, r)
}
}
// ErrCodeMinimumHTTPProtocolError error code is returned when the target endpoint
// did not match the required HTTP major and minor protocol version.
const ErrCodeMinimumHTTPProtocolError = "MinimumHTTPProtocolError"
func newMinHTTPProtoError(major, minor int, r *request.Request) error {
return awserr.NewRequestFailure(
awserr.New("MinimumHTTPProtocolError",
fmt.Sprintf(
"operation requires minimum HTTP protocol of HTTP/%d.%d, but was %s",
major, minor, r.HTTPResponse.Proto,
),
nil,
),
r.HTTPResponse.StatusCode, r.RequestID,
)
}

View file

@ -1,7 +1,7 @@
// Package query provides serialization of AWS query requests, and responses. // Package query provides serialization of AWS query requests, and responses.
package query package query
//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/query.json build_test.go //go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/input/query.json build_test.go
import ( import (
"net/url" "net/url"

View file

@ -1,6 +1,6 @@
package query package query
//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/query.json unmarshal_test.go //go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/output/query.json unmarshal_test.go
import ( import (
"encoding/xml" "encoding/xml"

View file

@ -15,6 +15,7 @@ import (
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
awsStrings "github.com/aws/aws-sdk-go/internal/strings"
"github.com/aws/aws-sdk-go/private/protocol" "github.com/aws/aws-sdk-go/private/protocol"
) )
@ -28,7 +29,9 @@ var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.rest.UnmarshalMeta
func Unmarshal(r *request.Request) { func Unmarshal(r *request.Request) {
if r.DataFilled() { if r.DataFilled() {
v := reflect.Indirect(reflect.ValueOf(r.Data)) v := reflect.Indirect(reflect.ValueOf(r.Data))
unmarshalBody(r, v) if err := unmarshalBody(r, v); err != nil {
r.Error = err
}
} }
} }
@ -40,12 +43,21 @@ func UnmarshalMeta(r *request.Request) {
r.RequestID = r.HTTPResponse.Header.Get("X-Amz-Request-Id") r.RequestID = r.HTTPResponse.Header.Get("X-Amz-Request-Id")
} }
if r.DataFilled() { if r.DataFilled() {
v := reflect.Indirect(reflect.ValueOf(r.Data)) if err := UnmarshalResponse(r.HTTPResponse, r.Data, aws.BoolValue(r.Config.LowerCaseHeaderMaps)); err != nil {
unmarshalLocationElements(r, v) r.Error = err
}
} }
} }
func unmarshalBody(r *request.Request, v reflect.Value) { // UnmarshalResponse attempts to unmarshal the REST response headers to
// the data type passed in. The type must be a pointer. An error is returned
// with any error unmarshaling the response into the target datatype.
func UnmarshalResponse(resp *http.Response, data interface{}, lowerCaseHeaderMaps bool) error {
v := reflect.Indirect(reflect.ValueOf(data))
return unmarshalLocationElements(resp, v, lowerCaseHeaderMaps)
}
func unmarshalBody(r *request.Request, v reflect.Value) error {
if field, ok := v.Type().FieldByName("_"); ok { if field, ok := v.Type().FieldByName("_"); ok {
if payloadName := field.Tag.Get("payload"); payloadName != "" { if payloadName := field.Tag.Get("payload"); payloadName != "" {
pfield, _ := v.Type().FieldByName(payloadName) pfield, _ := v.Type().FieldByName(payloadName)
@ -57,35 +69,38 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
defer r.HTTPResponse.Body.Close() defer r.HTTPResponse.Body.Close()
b, err := ioutil.ReadAll(r.HTTPResponse.Body) b, err := ioutil.ReadAll(r.HTTPResponse.Body)
if err != nil { if err != nil {
r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) return awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
} else {
payload.Set(reflect.ValueOf(b))
} }
payload.Set(reflect.ValueOf(b))
case *string: case *string:
defer r.HTTPResponse.Body.Close() defer r.HTTPResponse.Body.Close()
b, err := ioutil.ReadAll(r.HTTPResponse.Body) b, err := ioutil.ReadAll(r.HTTPResponse.Body)
if err != nil { if err != nil {
r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) return awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
} else {
str := string(b)
payload.Set(reflect.ValueOf(&str))
} }
str := string(b)
payload.Set(reflect.ValueOf(&str))
default: default:
switch payload.Type().String() { switch payload.Type().String() {
case "io.ReadCloser": case "io.ReadCloser":
payload.Set(reflect.ValueOf(r.HTTPResponse.Body)) payload.Set(reflect.ValueOf(r.HTTPResponse.Body))
case "io.ReadSeeker": case "io.ReadSeeker":
b, err := ioutil.ReadAll(r.HTTPResponse.Body) b, err := ioutil.ReadAll(r.HTTPResponse.Body)
if err != nil { if err != nil {
r.Error = awserr.New(request.ErrCodeSerialization, return awserr.New(request.ErrCodeSerialization,
"failed to read response body", err) "failed to read response body", err)
return
} }
payload.Set(reflect.ValueOf(ioutil.NopCloser(bytes.NewReader(b)))) payload.Set(reflect.ValueOf(ioutil.NopCloser(bytes.NewReader(b))))
default: default:
io.Copy(ioutil.Discard, r.HTTPResponse.Body) io.Copy(ioutil.Discard, r.HTTPResponse.Body)
defer r.HTTPResponse.Body.Close() r.HTTPResponse.Body.Close()
r.Error = awserr.New(request.ErrCodeSerialization, return awserr.New(request.ErrCodeSerialization,
"failed to decode REST response", "failed to decode REST response",
fmt.Errorf("unknown payload type %s", payload.Type())) fmt.Errorf("unknown payload type %s", payload.Type()))
} }
@ -94,9 +109,11 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
} }
} }
} }
return nil
} }
func unmarshalLocationElements(r *request.Request, v reflect.Value) { func unmarshalLocationElements(resp *http.Response, v reflect.Value, lowerCaseHeaderMaps bool) error {
for i := 0; i < v.NumField(); i++ { for i := 0; i < v.NumField(); i++ {
m, field := v.Field(i), v.Type().Field(i) m, field := v.Field(i), v.Type().Field(i)
if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) { if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) {
@ -111,26 +128,25 @@ func unmarshalLocationElements(r *request.Request, v reflect.Value) {
switch field.Tag.Get("location") { switch field.Tag.Get("location") {
case "statusCode": case "statusCode":
unmarshalStatusCode(m, r.HTTPResponse.StatusCode) unmarshalStatusCode(m, resp.StatusCode)
case "header": case "header":
err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name), field.Tag) err := unmarshalHeader(m, resp.Header.Get(name), field.Tag)
if err != nil { if err != nil {
r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) return awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
break
} }
case "headers": case "headers":
prefix := field.Tag.Get("locationName") prefix := field.Tag.Get("locationName")
err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix) err := unmarshalHeaderMap(m, resp.Header, prefix, lowerCaseHeaderMaps)
if err != nil { if err != nil {
r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
break
} }
} }
} }
if r.Error != nil {
return
}
} }
return nil
} }
func unmarshalStatusCode(v reflect.Value, statusCode int) { func unmarshalStatusCode(v reflect.Value, statusCode int) {
@ -145,7 +161,7 @@ func unmarshalStatusCode(v reflect.Value, statusCode int) {
} }
} }
func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string) error { func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string, normalize bool) error {
if len(headers) == 0 { if len(headers) == 0 {
return nil return nil
} }
@ -153,8 +169,12 @@ func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string) err
case map[string]*string: // we only support string map value types case map[string]*string: // we only support string map value types
out := map[string]*string{} out := map[string]*string{}
for k, v := range headers { for k, v := range headers {
k = http.CanonicalHeaderKey(k) if awsStrings.HasPrefixFold(k, prefix) {
if strings.HasPrefix(strings.ToLower(k), strings.ToLower(prefix)) { if normalize == true {
k = strings.ToLower(k)
} else {
k = http.CanonicalHeaderKey(k)
}
out[k[len(prefix):]] = &v[0] out[k[len(prefix):]] = &v[0]
} }
} }

View file

@ -2,8 +2,8 @@
// requests and responses. // requests and responses.
package restxml package restxml
//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/rest-xml.json build_test.go //go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/input/rest-xml.json build_test.go
//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/rest-xml.json unmarshal_test.go //go:generate go run -tags codegen ../../../private/model/cli/gen-protocol-tests ../../../models/protocol_tests/output/rest-xml.json unmarshal_test.go
import ( import (
"bytes" "bytes"

View file

@ -19,3 +19,9 @@ func UnmarshalDiscardBody(r *request.Request) {
io.Copy(ioutil.Discard, r.HTTPResponse.Body) io.Copy(ioutil.Discard, r.HTTPResponse.Body)
r.HTTPResponse.Body.Close() r.HTTPResponse.Body.Close()
} }
// ResponseMetadata provides the SDK response metadata attributes.
type ResponseMetadata struct {
StatusCode int
RequestID string
}

View file

@ -0,0 +1,65 @@
package protocol
import (
"net/http"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
)
// UnmarshalErrorHandler provides unmarshaling errors API response errors for
// both typed and untyped errors.
type UnmarshalErrorHandler struct {
unmarshaler ErrorUnmarshaler
}
// ErrorUnmarshaler is an abstract interface for concrete implementations to
// unmarshal protocol specific response errors.
type ErrorUnmarshaler interface {
UnmarshalError(*http.Response, ResponseMetadata) (error, error)
}
// NewUnmarshalErrorHandler returns an UnmarshalErrorHandler
// initialized for the set of exception names to the error unmarshalers
func NewUnmarshalErrorHandler(unmarshaler ErrorUnmarshaler) *UnmarshalErrorHandler {
return &UnmarshalErrorHandler{
unmarshaler: unmarshaler,
}
}
// UnmarshalErrorHandlerName is the name of the named handler.
const UnmarshalErrorHandlerName = "awssdk.protocol.UnmarshalError"
// NamedHandler returns a NamedHandler for the unmarshaler using the set of
// errors the unmarshaler was initialized for.
func (u *UnmarshalErrorHandler) NamedHandler() request.NamedHandler {
return request.NamedHandler{
Name: UnmarshalErrorHandlerName,
Fn: u.UnmarshalError,
}
}
// UnmarshalError will attempt to unmarshal the API response's error message
// into either a generic SDK error type, or a typed error corresponding to the
// errors exception name.
func (u *UnmarshalErrorHandler) UnmarshalError(r *request.Request) {
defer r.HTTPResponse.Body.Close()
respMeta := ResponseMetadata{
StatusCode: r.HTTPResponse.StatusCode,
RequestID: r.RequestID,
}
v, err := u.unmarshaler.UnmarshalError(r.HTTPResponse, respMeta)
if err != nil {
r.Error = awserr.NewRequestFailure(
awserr.New(request.ErrCodeSerialization,
"failed to unmarshal response error", err),
respMeta.StatusCode,
respMeta.RequestID,
)
return
}
r.Error = v
}

File diff suppressed because it is too large Load diff

View file

@ -4,6 +4,7 @@ import (
"github.com/aws/aws-sdk-go/aws/client" "github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/s3err" "github.com/aws/aws-sdk-go/internal/s3err"
"github.com/aws/aws-sdk-go/service/s3/internal/arn"
) )
func init() { func init() {
@ -13,7 +14,7 @@ func init() {
func defaultInitClientFn(c *client.Client) { func defaultInitClientFn(c *client.Client) {
// Support building custom endpoints based on config // Support building custom endpoints based on config
c.Handlers.Build.PushFront(updateEndpointForS3Config) c.Handlers.Build.PushFront(endpointHandler)
// Require SSL when using SSE keys // Require SSL when using SSE keys
c.Handlers.Validate.PushBack(validateSSERequiresSSL) c.Handlers.Validate.PushBack(validateSSERequiresSSL)
@ -27,7 +28,7 @@ func defaultInitClientFn(c *client.Client) {
} }
func defaultInitRequestFn(r *request.Request) { func defaultInitRequestFn(r *request.Request) {
// Add reuest handlers for specific platforms. // Add request handlers for specific platforms.
// e.g. 100-continue support for PUT requests using Go 1.6 // e.g. 100-continue support for PUT requests using Go 1.6
platformRequestHandlers(r) platformRequestHandlers(r)
@ -73,3 +74,8 @@ type sseCustomerKeyGetter interface {
type copySourceSSECustomerKeyGetter interface { type copySourceSSECustomerKeyGetter interface {
getCopySourceSSECustomerKey() string getCopySourceSSECustomerKey() string
} }
type endpointARNGetter interface {
getEndpointARN() (arn.Resource, error)
hasEndpointARN() bool
}

233
vendor/github.com/aws/aws-sdk-go/service/s3/endpoint.go generated vendored Normal file
View file

@ -0,0 +1,233 @@
package s3
import (
"net/url"
"strings"
"github.com/aws/aws-sdk-go/aws"
awsarn "github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol"
"github.com/aws/aws-sdk-go/service/s3/internal/arn"
)
// Used by shapes with members decorated as endpoint ARN.
func parseEndpointARN(v string) (arn.Resource, error) {
return arn.ParseResource(v, accessPointResourceParser)
}
func accessPointResourceParser(a awsarn.ARN) (arn.Resource, error) {
resParts := arn.SplitResource(a.Resource)
switch resParts[0] {
case "accesspoint":
return arn.ParseAccessPointResource(a, resParts[1:])
default:
return nil, arn.InvalidARNError{ARN: a, Reason: "unknown resource type"}
}
}
func endpointHandler(req *request.Request) {
endpoint, ok := req.Params.(endpointARNGetter)
if !ok || !endpoint.hasEndpointARN() {
updateBucketEndpointFromParams(req)
return
}
resource, err := endpoint.getEndpointARN()
if err != nil {
req.Error = newInvalidARNError(nil, err)
return
}
resReq := resourceRequest{
Resource: resource,
Request: req,
}
if resReq.IsCrossPartition() {
req.Error = newClientPartitionMismatchError(resource,
req.ClientInfo.PartitionID, aws.StringValue(req.Config.Region), nil)
return
}
if !resReq.AllowCrossRegion() && resReq.IsCrossRegion() {
req.Error = newClientRegionMismatchError(resource,
req.ClientInfo.PartitionID, aws.StringValue(req.Config.Region), nil)
return
}
if resReq.HasCustomEndpoint() {
req.Error = newInvalidARNWithCustomEndpointError(resource, nil)
return
}
switch tv := resource.(type) {
case arn.AccessPointARN:
err = updateRequestAccessPointEndpoint(req, tv)
if err != nil {
req.Error = err
}
default:
req.Error = newInvalidARNError(resource, nil)
}
}
type resourceRequest struct {
Resource arn.Resource
Request *request.Request
}
func (r resourceRequest) ARN() awsarn.ARN {
return r.Resource.GetARN()
}
func (r resourceRequest) AllowCrossRegion() bool {
return aws.BoolValue(r.Request.Config.S3UseARNRegion)
}
func (r resourceRequest) UseFIPS() bool {
return isFIPS(aws.StringValue(r.Request.Config.Region))
}
func (r resourceRequest) IsCrossPartition() bool {
return r.Request.ClientInfo.PartitionID != r.Resource.GetARN().Partition
}
func (r resourceRequest) IsCrossRegion() bool {
return isCrossRegion(r.Request, r.Resource.GetARN().Region)
}
func (r resourceRequest) HasCustomEndpoint() bool {
return len(aws.StringValue(r.Request.Config.Endpoint)) > 0
}
func isFIPS(clientRegion string) bool {
return strings.HasPrefix(clientRegion, "fips-") || strings.HasSuffix(clientRegion, "-fips")
}
func isCrossRegion(req *request.Request, otherRegion string) bool {
return req.ClientInfo.SigningRegion != otherRegion
}
func updateBucketEndpointFromParams(r *request.Request) {
bucket, ok := bucketNameFromReqParams(r.Params)
if !ok {
// Ignore operation requests if the bucket name was not provided
// if this is an input validation error the validation handler
// will report it.
return
}
updateEndpointForS3Config(r, bucket)
}
func updateRequestAccessPointEndpoint(req *request.Request, accessPoint arn.AccessPointARN) error {
// Accelerate not supported
if aws.BoolValue(req.Config.S3UseAccelerate) {
return newClientConfiguredForAccelerateError(accessPoint,
req.ClientInfo.PartitionID, aws.StringValue(req.Config.Region), nil)
}
// Ignore the disable host prefix for access points since custom endpoints
// are not supported.
req.Config.DisableEndpointHostPrefix = aws.Bool(false)
if err := accessPointEndpointBuilder(accessPoint).Build(req); err != nil {
return err
}
removeBucketFromPath(req.HTTPRequest.URL)
return nil
}
func removeBucketFromPath(u *url.URL) {
u.Path = strings.Replace(u.Path, "/{Bucket}", "", -1)
if u.Path == "" {
u.Path = "/"
}
}
type accessPointEndpointBuilder arn.AccessPointARN
const (
accessPointPrefixLabel = "accesspoint"
accountIDPrefixLabel = "accountID"
accesPointPrefixTemplate = "{" + accessPointPrefixLabel + "}-{" + accountIDPrefixLabel + "}."
)
func (a accessPointEndpointBuilder) Build(req *request.Request) error {
resolveRegion := arn.AccessPointARN(a).Region
cfgRegion := aws.StringValue(req.Config.Region)
if isFIPS(cfgRegion) {
if aws.BoolValue(req.Config.S3UseARNRegion) && isCrossRegion(req, resolveRegion) {
// FIPS with cross region is not supported, the SDK must fail
// because there is no well defined method for SDK to construct a
// correct FIPS endpoint.
return newClientConfiguredForCrossRegionFIPSError(arn.AccessPointARN(a),
req.ClientInfo.PartitionID, cfgRegion, nil)
}
resolveRegion = cfgRegion
}
endpoint, err := resolveRegionalEndpoint(req, resolveRegion)
if err != nil {
return newFailedToResolveEndpointError(arn.AccessPointARN(a),
req.ClientInfo.PartitionID, cfgRegion, err)
}
if err = updateRequestEndpoint(req, endpoint.URL); err != nil {
return err
}
const serviceEndpointLabel = "s3-accesspoint"
// dualstack provided by endpoint resolver
cfgHost := req.HTTPRequest.URL.Host
if strings.HasPrefix(cfgHost, "s3") {
req.HTTPRequest.URL.Host = serviceEndpointLabel + cfgHost[2:]
}
protocol.HostPrefixBuilder{
Prefix: accesPointPrefixTemplate,
LabelsFn: a.hostPrefixLabelValues,
}.Build(req)
req.ClientInfo.SigningName = endpoint.SigningName
req.ClientInfo.SigningRegion = endpoint.SigningRegion
err = protocol.ValidateEndpointHost(req.Operation.Name, req.HTTPRequest.URL.Host)
if err != nil {
return newInvalidARNError(arn.AccessPointARN(a), err)
}
return nil
}
func (a accessPointEndpointBuilder) hostPrefixLabelValues() map[string]string {
return map[string]string{
accessPointPrefixLabel: arn.AccessPointARN(a).AccessPointName,
accountIDPrefixLabel: arn.AccessPointARN(a).AccountID,
}
}
func resolveRegionalEndpoint(r *request.Request, region string) (endpoints.ResolvedEndpoint, error) {
return r.Config.EndpointResolver.EndpointFor(EndpointsID, region, func(opts *endpoints.Options) {
opts.DisableSSL = aws.BoolValue(r.Config.DisableSSL)
opts.UseDualStack = aws.BoolValue(r.Config.UseDualStack)
opts.S3UsEast1RegionalEndpoint = endpoints.RegionalS3UsEast1Endpoint
})
}
func updateRequestEndpoint(r *request.Request, endpoint string) (err error) {
endpoint = endpoints.AddScheme(endpoint, aws.BoolValue(r.Config.DisableSSL))
r.HTTPRequest.URL, err = url.Parse(endpoint + r.Operation.HTTPPath)
if err != nil {
return awserr.New(request.ErrCodeSerialization,
"failed to parse endpoint URL", err)
}
return nil
}

View file

@ -0,0 +1,151 @@
package s3
import (
"fmt"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/s3/internal/arn"
)
const (
invalidARNErrorErrCode = "InvalidARNError"
configurationErrorErrCode = "ConfigurationError"
)
type invalidARNError struct {
message string
resource arn.Resource
origErr error
}
func (e invalidARNError) Error() string {
var extra string
if e.resource != nil {
extra = "ARN: " + e.resource.String()
}
return awserr.SprintError(e.Code(), e.Message(), extra, e.origErr)
}
func (e invalidARNError) Code() string {
return invalidARNErrorErrCode
}
func (e invalidARNError) Message() string {
return e.message
}
func (e invalidARNError) OrigErr() error {
return e.origErr
}
func newInvalidARNError(resource arn.Resource, err error) invalidARNError {
return invalidARNError{
message: "invalid ARN",
origErr: err,
resource: resource,
}
}
func newInvalidARNWithCustomEndpointError(resource arn.Resource, err error) invalidARNError {
return invalidARNError{
message: "resource ARN not supported with custom client endpoints",
origErr: err,
resource: resource,
}
}
// ARN not supported for the target partition
func newInvalidARNWithUnsupportedPartitionError(resource arn.Resource, err error) invalidARNError {
return invalidARNError{
message: "resource ARN not supported for the target ARN partition",
origErr: err,
resource: resource,
}
}
type configurationError struct {
message string
resource arn.Resource
clientPartitionID string
clientRegion string
origErr error
}
func (e configurationError) Error() string {
extra := fmt.Sprintf("ARN: %s, client partition: %s, client region: %s",
e.resource, e.clientPartitionID, e.clientRegion)
return awserr.SprintError(e.Code(), e.Message(), extra, e.origErr)
}
func (e configurationError) Code() string {
return configurationErrorErrCode
}
func (e configurationError) Message() string {
return e.message
}
func (e configurationError) OrigErr() error {
return e.origErr
}
func newClientPartitionMismatchError(resource arn.Resource, clientPartitionID, clientRegion string, err error) configurationError {
return configurationError{
message: "client partition does not match provided ARN partition",
origErr: err,
resource: resource,
clientPartitionID: clientPartitionID,
clientRegion: clientRegion,
}
}
func newClientRegionMismatchError(resource arn.Resource, clientPartitionID, clientRegion string, err error) configurationError {
return configurationError{
message: "client region does not match provided ARN region",
origErr: err,
resource: resource,
clientPartitionID: clientPartitionID,
clientRegion: clientRegion,
}
}
func newFailedToResolveEndpointError(resource arn.Resource, clientPartitionID, clientRegion string, err error) configurationError {
return configurationError{
message: "endpoint resolver failed to find an endpoint for the provided ARN region",
origErr: err,
resource: resource,
clientPartitionID: clientPartitionID,
clientRegion: clientRegion,
}
}
func newClientConfiguredForFIPSError(resource arn.Resource, clientPartitionID, clientRegion string, err error) configurationError {
return configurationError{
message: "client configured for fips but cross-region resource ARN provided",
origErr: err,
resource: resource,
clientPartitionID: clientPartitionID,
clientRegion: clientRegion,
}
}
func newClientConfiguredForAccelerateError(resource arn.Resource, clientPartitionID, clientRegion string, err error) configurationError {
return configurationError{
message: "client configured for S3 Accelerate but is supported with resource ARN",
origErr: err,
resource: resource,
clientPartitionID: clientPartitionID,
clientRegion: clientRegion,
}
}
func newClientConfiguredForCrossRegionFIPSError(resource arn.Resource, clientPartitionID, clientRegion string, err error) configurationError {
return configurationError{
message: "client configured for FIPS with cross-region enabled but is supported with cross-region resource ARN",
origErr: err,
resource: resource,
clientPartitionID: clientPartitionID,
clientRegion: clientRegion,
}
}

View file

@ -13,6 +13,12 @@ const (
// ErrCodeBucketAlreadyOwnedByYou for service response error code // ErrCodeBucketAlreadyOwnedByYou for service response error code
// "BucketAlreadyOwnedByYou". // "BucketAlreadyOwnedByYou".
//
// The bucket you tried to create already exists, and you own it. Amazon S3
// returns this error in all AWS Regions except in the North Virginia Region.
// For legacy compatibility, if you re-create an existing bucket that you already
// own in the North Virginia Region, Amazon S3 returns 200 OK and resets the
// bucket access control lists (ACLs).
ErrCodeBucketAlreadyOwnedByYou = "BucketAlreadyOwnedByYou" ErrCodeBucketAlreadyOwnedByYou = "BucketAlreadyOwnedByYou"
// ErrCodeNoSuchBucket for service response error code // ErrCodeNoSuchBucket for service response error code
@ -36,13 +42,13 @@ const (
// ErrCodeObjectAlreadyInActiveTierError for service response error code // ErrCodeObjectAlreadyInActiveTierError for service response error code
// "ObjectAlreadyInActiveTierError". // "ObjectAlreadyInActiveTierError".
// //
// This operation is not allowed against this storage tier // This operation is not allowed against this storage tier.
ErrCodeObjectAlreadyInActiveTierError = "ObjectAlreadyInActiveTierError" ErrCodeObjectAlreadyInActiveTierError = "ObjectAlreadyInActiveTierError"
// ErrCodeObjectNotInActiveTierError for service response error code // ErrCodeObjectNotInActiveTierError for service response error code
// "ObjectNotInActiveTierError". // "ObjectNotInActiveTierError".
// //
// The source object of the COPY operation is not in the active tier and is // The source object of the COPY operation is not in the active tier and is
// only stored in Amazon Glacier. // only stored in Amazon S3 Glacier.
ErrCodeObjectNotInActiveTierError = "ObjectNotInActiveTierError" ErrCodeObjectNotInActiveTierError = "ObjectNotInActiveTierError"
) )

View file

@ -30,10 +30,10 @@ var accelerateOpBlacklist = operationBlacklist{
opListBuckets, opCreateBucket, opDeleteBucket, opListBuckets, opCreateBucket, opDeleteBucket,
} }
// Request handler to automatically add the bucket name to the endpoint domain // Automatically add the bucket name to the endpoint domain
// if possible. This style of bucket is valid for all bucket names which are // if possible. This style of bucket is valid for all bucket names which are
// DNS compatible and do not contain "." // DNS compatible and do not contain "."
func updateEndpointForS3Config(r *request.Request) { func updateEndpointForS3Config(r *request.Request, bucketName string) {
forceHostStyle := aws.BoolValue(r.Config.S3ForcePathStyle) forceHostStyle := aws.BoolValue(r.Config.S3ForcePathStyle)
accelerate := aws.BoolValue(r.Config.S3UseAccelerate) accelerate := aws.BoolValue(r.Config.S3UseAccelerate)
@ -43,45 +43,29 @@ func updateEndpointForS3Config(r *request.Request) {
r.Config.Logger.Log("ERROR: aws.Config.S3UseAccelerate is not compatible with aws.Config.S3ForcePathStyle, ignoring S3ForcePathStyle.") r.Config.Logger.Log("ERROR: aws.Config.S3UseAccelerate is not compatible with aws.Config.S3ForcePathStyle, ignoring S3ForcePathStyle.")
} }
} }
updateEndpointForAccelerate(r) updateEndpointForAccelerate(r, bucketName)
} else if !forceHostStyle && r.Operation.Name != opGetBucketLocation { } else if !forceHostStyle && r.Operation.Name != opGetBucketLocation {
updateEndpointForHostStyle(r) updateEndpointForHostStyle(r, bucketName)
} }
} }
func updateEndpointForHostStyle(r *request.Request) { func updateEndpointForHostStyle(r *request.Request, bucketName string) {
bucket, ok := bucketNameFromReqParams(r.Params) if !hostCompatibleBucketName(r.HTTPRequest.URL, bucketName) {
if !ok {
// Ignore operation requests if the bucketname was not provided
// if this is an input validation error the validation handler
// will report it.
return
}
if !hostCompatibleBucketName(r.HTTPRequest.URL, bucket) {
// bucket name must be valid to put into the host // bucket name must be valid to put into the host
return return
} }
moveBucketToHost(r.HTTPRequest.URL, bucket) moveBucketToHost(r.HTTPRequest.URL, bucketName)
} }
var ( var (
accelElem = []byte("s3-accelerate.dualstack.") accelElem = []byte("s3-accelerate.dualstack.")
) )
func updateEndpointForAccelerate(r *request.Request) { func updateEndpointForAccelerate(r *request.Request, bucketName string) {
bucket, ok := bucketNameFromReqParams(r.Params) if !hostCompatibleBucketName(r.HTTPRequest.URL, bucketName) {
if !ok {
// Ignore operation requests if the bucketname was not provided
// if this is an input validation error the validation handler
// will report it.
return
}
if !hostCompatibleBucketName(r.HTTPRequest.URL, bucket) {
r.Error = awserr.New("InvalidParameterException", r.Error = awserr.New("InvalidParameterException",
fmt.Sprintf("bucket name %s is not compatible with S3 Accelerate", bucket), fmt.Sprintf("bucket name %s is not compatible with S3 Accelerate", bucketName),
nil) nil)
return return
} }
@ -106,7 +90,7 @@ func updateEndpointForAccelerate(r *request.Request) {
r.HTTPRequest.URL.Host = strings.Join(parts, ".") r.HTTPRequest.URL.Host = strings.Join(parts, ".")
moveBucketToHost(r.HTTPRequest.URL, bucket) moveBucketToHost(r.HTTPRequest.URL, bucketName)
} }
// Attempts to retrieve the bucket name from the request input parameters. // Attempts to retrieve the bucket name from the request input parameters.
@ -148,8 +132,5 @@ func dnsCompatibleBucketName(bucket string) bool {
// moveBucketToHost moves the bucket name from the URI path to URL host. // moveBucketToHost moves the bucket name from the URI path to URL host.
func moveBucketToHost(u *url.URL, bucket string) { func moveBucketToHost(u *url.URL, bucket string) {
u.Host = bucket + "." + u.Host u.Host = bucket + "." + u.Host
u.Path = strings.Replace(u.Path, "/{Bucket}", "", -1) removeBucketFromPath(u)
if u.Path == "" {
u.Path = "/"
}
} }

View file

@ -0,0 +1,45 @@
package arn
import (
"strings"
"github.com/aws/aws-sdk-go/aws/arn"
)
// AccessPointARN provides representation
type AccessPointARN struct {
arn.ARN
AccessPointName string
}
// GetARN returns the base ARN for the Access Point resource
func (a AccessPointARN) GetARN() arn.ARN {
return a.ARN
}
// ParseAccessPointResource attempts to parse the ARN's resource as an
// AccessPoint resource.
func ParseAccessPointResource(a arn.ARN, resParts []string) (AccessPointARN, error) {
if len(a.Region) == 0 {
return AccessPointARN{}, InvalidARNError{a, "region not set"}
}
if len(a.AccountID) == 0 {
return AccessPointARN{}, InvalidARNError{a, "account-id not set"}
}
if len(resParts) == 0 {
return AccessPointARN{}, InvalidARNError{a, "resource-id not set"}
}
if len(resParts) > 1 {
return AccessPointARN{}, InvalidARNError{a, "sub resource not supported"}
}
resID := resParts[0]
if len(strings.TrimSpace(resID)) == 0 {
return AccessPointARN{}, InvalidARNError{a, "resource-id not set"}
}
return AccessPointARN{
ARN: a,
AccessPointName: resID,
}, nil
}

View file

@ -0,0 +1,71 @@
package arn
import (
"strings"
"github.com/aws/aws-sdk-go/aws/arn"
)
// Resource provides the interfaces abstracting ARNs of specific resource
// types.
type Resource interface {
GetARN() arn.ARN
String() string
}
// ResourceParser provides the function for parsing an ARN's resource
// component into a typed resource.
type ResourceParser func(arn.ARN) (Resource, error)
// ParseResource parses an AWS ARN into a typed resource for the S3 API.
func ParseResource(s string, resParser ResourceParser) (resARN Resource, err error) {
a, err := arn.Parse(s)
if err != nil {
return nil, err
}
if len(a.Partition) == 0 {
return nil, InvalidARNError{a, "partition not set"}
}
if a.Service != "s3" {
return nil, InvalidARNError{a, "service is not S3"}
}
if len(a.Resource) == 0 {
return nil, InvalidARNError{a, "resource not set"}
}
return resParser(a)
}
// SplitResource splits the resource components by the ARN resource delimiters.
func SplitResource(v string) []string {
var parts []string
var offset int
for offset <= len(v) {
idx := strings.IndexAny(v[offset:], "/:")
if idx < 0 {
parts = append(parts, v[offset:])
break
}
parts = append(parts, v[offset:idx+offset])
offset += idx + 1
}
return parts
}
// IsARN returns whether the given string is an ARN
func IsARN(s string) bool {
return arn.IsARN(s)
}
// InvalidARNError provides the error for an invalid ARN error.
type InvalidARNError struct {
ARN arn.ARN
Reason string
}
func (e InvalidARNError) Error() string {
return "invalid Amazon S3 ARN, " + e.Reason + ", " + e.ARN.String()
}

View file

@ -31,7 +31,7 @@ var initRequest func(*request.Request)
const ( const (
ServiceName = "s3" // Name of service. ServiceName = "s3" // Name of service.
EndpointsID = ServiceName // ID to lookup a service endpoint with. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "S3" // ServiceID is a unique identifer of a specific service. ServiceID = "S3" // ServiceID is a unique identifier of a specific service.
) )
// New creates a new instance of the S3 client with a session. // New creates a new instance of the S3 client with a session.
@ -39,6 +39,8 @@ const (
// aws.Config parameter to add your extra config. // aws.Config parameter to add your extra config.
// //
// Example: // Example:
// mySession := session.Must(session.NewSession())
//
// // Create a S3 client from just a session. // // Create a S3 client from just a session.
// svc := s3.New(mySession) // svc := s3.New(mySession)
// //
@ -76,6 +78,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint,
svc.Handlers.UnmarshalMeta.PushBackNamed(restxml.UnmarshalMetaHandler) svc.Handlers.UnmarshalMeta.PushBackNamed(restxml.UnmarshalMetaHandler)
svc.Handlers.UnmarshalError.PushBackNamed(restxml.UnmarshalErrorHandler) svc.Handlers.UnmarshalError.PushBackNamed(restxml.UnmarshalErrorHandler)
svc.Handlers.BuildStream.PushBackNamed(restxml.BuildHandler)
svc.Handlers.UnmarshalStream.PushBackNamed(restxml.UnmarshalHandler) svc.Handlers.UnmarshalStream.PushBackNamed(restxml.UnmarshalHandler)
// Run custom client initialization if present // Run custom client initialization if present

View file

@ -78,6 +78,8 @@ func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, o
// IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) // IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)
// in the IAM User Guide. // in the IAM User Guide.
// //
// Session Duration
//
// By default, the temporary security credentials created by AssumeRole last // By default, the temporary security credentials created by AssumeRole last
// for one hour. However, you can use the optional DurationSeconds parameter // for one hour. However, you can use the optional DurationSeconds parameter
// to specify the duration of your session. You can provide a value from 900 // to specify the duration of your session. You can provide a value from 900
@ -91,6 +93,8 @@ func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, o
// URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) // URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html)
// in the IAM User Guide. // in the IAM User Guide.
// //
// Permissions
//
// The temporary security credentials created by AssumeRole can be used to make // The temporary security credentials created by AssumeRole can be used to make
// API calls to any AWS service with the following exception: You cannot call // API calls to any AWS service with the following exception: You cannot call
// the AWS STS GetFederationToken or GetSessionToken API operations. // the AWS STS GetFederationToken or GetSessionToken API operations.
@ -99,7 +103,7 @@ func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, o
// to this operation. You can pass a single JSON policy document to use as an // to this operation. You can pass a single JSON policy document to use as an
// inline session policy. You can also specify up to 10 managed policies to // inline session policy. You can also specify up to 10 managed policies to
// use as managed session policies. The plain text that you use for both inline // use as managed session policies. The plain text that you use for both inline
// and managed session policies shouldn't exceed 2048 characters. Passing policies // and managed session policies can't exceed 2,048 characters. Passing policies
// to this operation returns new temporary credentials. The resulting session's // to this operation returns new temporary credentials. The resulting session's
// permissions are the intersection of the role's identity-based policy and // permissions are the intersection of the role's identity-based policy and
// the session policies. You can use the role's temporary credentials in subsequent // the session policies. You can use the role's temporary credentials in subsequent
@ -131,6 +135,24 @@ func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, o
// see IAM Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html) // see IAM Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)
// in the IAM User Guide. // in the IAM User Guide.
// //
// Tags
//
// (Optional) You can pass tag key-value pairs to your session. These tags are
// called session tags. For more information about session tags, see Passing
// Session Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// An administrator must grant you the permissions necessary to pass session
// tags. The administrator can also create granular permissions to allow you
// to pass only specific session tags. For more information, see Tutorial: Using
// Tags for Attribute-Based Access Control (https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html)
// in the IAM User Guide.
//
// You can set the session tags as transitive. Transitive tags persist during
// role chaining. For more information, see Chaining Roles with Session Tags
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining)
// in the IAM User Guide.
//
// Using MFA with AssumeRole // Using MFA with AssumeRole
// //
// (Optional) You can include multi-factor authentication (MFA) information // (Optional) You can include multi-factor authentication (MFA) information
@ -165,9 +187,18 @@ func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, o
// message describes the specific error. // message describes the specific error.
// //
// * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge" // * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge"
// The request was rejected because the policy document was too large. The error // The request was rejected because the total packed size of the session policies
// message describes how big the policy document is, in packed form, as a percentage // and session tags combined was too large. An AWS conversion compresses the
// of what the API allows. // session policy document, session policy ARNs, and session tags into a packed
// binary format that has a separate limit. The error message indicates by percentage
// how close the policies and tags are to the upper size limit. For more information,
// see Passing Session Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// You could receive this error even though you meet other defined session policy
// and session tag limits. For more information, see IAM and STS Entity Character
// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
// in the IAM User Guide.
// //
// * ErrCodeRegionDisabledException "RegionDisabledException" // * ErrCodeRegionDisabledException "RegionDisabledException"
// STS is not activated in the requested region for the account that is being // STS is not activated in the requested region for the account that is being
@ -256,6 +287,8 @@ func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *re
// an access key ID, a secret access key, and a security token. Applications // an access key ID, a secret access key, and a security token. Applications
// can use these temporary security credentials to sign calls to AWS services. // can use these temporary security credentials to sign calls to AWS services.
// //
// Session Duration
//
// By default, the temporary security credentials created by AssumeRoleWithSAML // By default, the temporary security credentials created by AssumeRoleWithSAML
// last for one hour. However, you can use the optional DurationSeconds parameter // last for one hour. However, you can use the optional DurationSeconds parameter
// to specify the duration of your session. Your role session lasts for the // to specify the duration of your session. Your role session lasts for the
@ -271,6 +304,8 @@ func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *re
// URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) // URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html)
// in the IAM User Guide. // in the IAM User Guide.
// //
// Permissions
//
// The temporary security credentials created by AssumeRoleWithSAML can be used // The temporary security credentials created by AssumeRoleWithSAML can be used
// to make API calls to any AWS service with the following exception: you cannot // to make API calls to any AWS service with the following exception: you cannot
// call the STS GetFederationToken or GetSessionToken API operations. // call the STS GetFederationToken or GetSessionToken API operations.
@ -279,7 +314,7 @@ func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *re
// to this operation. You can pass a single JSON policy document to use as an // to this operation. You can pass a single JSON policy document to use as an
// inline session policy. You can also specify up to 10 managed policies to // inline session policy. You can also specify up to 10 managed policies to
// use as managed session policies. The plain text that you use for both inline // use as managed session policies. The plain text that you use for both inline
// and managed session policies shouldn't exceed 2048 characters. Passing policies // and managed session policies can't exceed 2,048 characters. Passing policies
// to this operation returns new temporary credentials. The resulting session's // to this operation returns new temporary credentials. The resulting session's
// permissions are the intersection of the role's identity-based policy and // permissions are the intersection of the role's identity-based policy and
// the session policies. You can use the role's temporary credentials in subsequent // the session policies. You can use the role's temporary credentials in subsequent
@ -289,12 +324,6 @@ func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *re
// information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) // information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// in the IAM User Guide. // in the IAM User Guide.
// //
// Before your application can call AssumeRoleWithSAML, you must configure your
// SAML identity provider (IdP) to issue the claims required by AWS. Additionally,
// you must use AWS Identity and Access Management (IAM) to create a SAML provider
// entity in your AWS account that represents your identity provider. You must
// also create an IAM role that specifies this SAML provider in its trust policy.
//
// Calling AssumeRoleWithSAML does not require the use of AWS security credentials. // Calling AssumeRoleWithSAML does not require the use of AWS security credentials.
// The identity of the caller is validated by using keys in the metadata document // The identity of the caller is validated by using keys in the metadata document
// that is uploaded for the SAML provider entity for your identity provider. // that is uploaded for the SAML provider entity for your identity provider.
@ -302,8 +331,50 @@ func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *re
// Calling AssumeRoleWithSAML can result in an entry in your AWS CloudTrail // Calling AssumeRoleWithSAML can result in an entry in your AWS CloudTrail
// logs. The entry includes the value in the NameID element of the SAML assertion. // logs. The entry includes the value in the NameID element of the SAML assertion.
// We recommend that you use a NameIDType that is not associated with any personally // We recommend that you use a NameIDType that is not associated with any personally
// identifiable information (PII). For example, you could instead use the Persistent // identifiable information (PII). For example, you could instead use the persistent
// Identifier (urn:oasis:names:tc:SAML:2.0:nameid-format:persistent). // identifier (urn:oasis:names:tc:SAML:2.0:nameid-format:persistent).
//
// Tags
//
// (Optional) You can configure your IdP to pass attributes into your SAML assertion
// as session tags. Each session tag consists of a key name and an associated
// value. For more information about session tags, see Passing Session Tags
// in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// You can pass up to 50 session tags. The plain text session tag keys cant
// exceed 128 characters and the values cant exceed 256 characters. For these
// and additional limits, see IAM and STS Character Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length)
// in the IAM User Guide.
//
// An AWS conversion compresses the passed session policies and session tags
// into a packed binary format that has a separate limit. Your request can fail
// for this limit even if your plain text meets the other requirements. The
// PackedPolicySize response element indicates by percentage how close the policies
// and tags for your request are to the upper size limit.
//
// You can pass a session tag with the same key as a tag that is attached to
// the role. When you do, session tags override the role's tags with the same
// key.
//
// An administrator must grant you the permissions necessary to pass session
// tags. The administrator can also create granular permissions to allow you
// to pass only specific session tags. For more information, see Tutorial: Using
// Tags for Attribute-Based Access Control (https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html)
// in the IAM User Guide.
//
// You can set the session tags as transitive. Transitive tags persist during
// role chaining. For more information, see Chaining Roles with Session Tags
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining)
// in the IAM User Guide.
//
// SAML Configuration
//
// Before your application can call AssumeRoleWithSAML, you must configure your
// SAML identity provider (IdP) to issue the claims required by AWS. Additionally,
// you must use AWS Identity and Access Management (IAM) to create a SAML provider
// entity in your AWS account that represents your identity provider. You must
// also create an IAM role that specifies this SAML provider in its trust policy.
// //
// For more information, see the following resources: // For more information, see the following resources:
// //
@ -332,9 +403,18 @@ func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *re
// message describes the specific error. // message describes the specific error.
// //
// * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge" // * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge"
// The request was rejected because the policy document was too large. The error // The request was rejected because the total packed size of the session policies
// message describes how big the policy document is, in packed form, as a percentage // and session tags combined was too large. An AWS conversion compresses the
// of what the API allows. // session policy document, session policy ARNs, and session tags into a packed
// binary format that has a separate limit. The error message indicates by percentage
// how close the policies and tags are to the upper size limit. For more information,
// see Passing Session Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// You could receive this error even though you meet other defined session policy
// and session tag limits. For more information, see IAM and STS Entity Character
// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
// in the IAM User Guide.
// //
// * ErrCodeIDPRejectedClaimException "IDPRejectedClaim" // * ErrCodeIDPRejectedClaimException "IDPRejectedClaim"
// The identity provider (IdP) reported that authentication failed. This might // The identity provider (IdP) reported that authentication failed. This might
@ -456,6 +536,8 @@ func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityI
// key ID, a secret access key, and a security token. Applications can use these // key ID, a secret access key, and a security token. Applications can use these
// temporary security credentials to sign calls to AWS service API operations. // temporary security credentials to sign calls to AWS service API operations.
// //
// Session Duration
//
// By default, the temporary security credentials created by AssumeRoleWithWebIdentity // By default, the temporary security credentials created by AssumeRoleWithWebIdentity
// last for one hour. However, you can use the optional DurationSeconds parameter // last for one hour. However, you can use the optional DurationSeconds parameter
// to specify the duration of your session. You can provide a value from 900 // to specify the duration of your session. You can provide a value from 900
@ -469,6 +551,8 @@ func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityI
// URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) // URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html)
// in the IAM User Guide. // in the IAM User Guide.
// //
// Permissions
//
// The temporary security credentials created by AssumeRoleWithWebIdentity can // The temporary security credentials created by AssumeRoleWithWebIdentity can
// be used to make API calls to any AWS service with the following exception: // be used to make API calls to any AWS service with the following exception:
// you cannot call the STS GetFederationToken or GetSessionToken API operations. // you cannot call the STS GetFederationToken or GetSessionToken API operations.
@ -477,7 +561,7 @@ func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityI
// to this operation. You can pass a single JSON policy document to use as an // to this operation. You can pass a single JSON policy document to use as an
// inline session policy. You can also specify up to 10 managed policies to // inline session policy. You can also specify up to 10 managed policies to
// use as managed session policies. The plain text that you use for both inline // use as managed session policies. The plain text that you use for both inline
// and managed session policies shouldn't exceed 2048 characters. Passing policies // and managed session policies can't exceed 2,048 characters. Passing policies
// to this operation returns new temporary credentials. The resulting session's // to this operation returns new temporary credentials. The resulting session's
// permissions are the intersection of the role's identity-based policy and // permissions are the intersection of the role's identity-based policy and
// the session policies. You can use the role's temporary credentials in subsequent // the session policies. You can use the role's temporary credentials in subsequent
@ -487,6 +571,42 @@ func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityI
// information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) // information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// in the IAM User Guide. // in the IAM User Guide.
// //
// Tags
//
// (Optional) You can configure your IdP to pass attributes into your web identity
// token as session tags. Each session tag consists of a key name and an associated
// value. For more information about session tags, see Passing Session Tags
// in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// You can pass up to 50 session tags. The plain text session tag keys cant
// exceed 128 characters and the values cant exceed 256 characters. For these
// and additional limits, see IAM and STS Character Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length)
// in the IAM User Guide.
//
// An AWS conversion compresses the passed session policies and session tags
// into a packed binary format that has a separate limit. Your request can fail
// for this limit even if your plain text meets the other requirements. The
// PackedPolicySize response element indicates by percentage how close the policies
// and tags for your request are to the upper size limit.
//
// You can pass a session tag with the same key as a tag that is attached to
// the role. When you do, the session tag overrides the role tag with the same
// key.
//
// An administrator must grant you the permissions necessary to pass session
// tags. The administrator can also create granular permissions to allow you
// to pass only specific session tags. For more information, see Tutorial: Using
// Tags for Attribute-Based Access Control (https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html)
// in the IAM User Guide.
//
// You can set the session tags as transitive. Transitive tags persist during
// role chaining. For more information, see Chaining Roles with Session Tags
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining)
// in the IAM User Guide.
//
// Identities
//
// Before your application can call AssumeRoleWithWebIdentity, you must have // Before your application can call AssumeRoleWithWebIdentity, you must have
// an identity token from a supported identity provider and create a role that // an identity token from a supported identity provider and create a role that
// the application can assume. The role that your application assumes must trust // the application can assume. The role that your application assumes must trust
@ -514,8 +634,8 @@ func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityI
// * AWS SDK for iOS Developer Guide (http://aws.amazon.com/sdkforios/) and // * AWS SDK for iOS Developer Guide (http://aws.amazon.com/sdkforios/) and
// AWS SDK for Android Developer Guide (http://aws.amazon.com/sdkforandroid/). // AWS SDK for Android Developer Guide (http://aws.amazon.com/sdkforandroid/).
// These toolkits contain sample apps that show how to invoke the identity // These toolkits contain sample apps that show how to invoke the identity
// providers, and then how to use the information from these providers to // providers. The toolkits then show how to use the information from these
// get and use temporary security credentials. // providers to get and use temporary security credentials.
// //
// * Web Identity Federation with Mobile Applications (http://aws.amazon.com/articles/web-identity-federation-with-mobile-applications). // * Web Identity Federation with Mobile Applications (http://aws.amazon.com/articles/web-identity-federation-with-mobile-applications).
// This article discusses web identity federation and shows an example of // This article discusses web identity federation and shows an example of
@ -535,9 +655,18 @@ func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityI
// message describes the specific error. // message describes the specific error.
// //
// * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge" // * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge"
// The request was rejected because the policy document was too large. The error // The request was rejected because the total packed size of the session policies
// message describes how big the policy document is, in packed form, as a percentage // and session tags combined was too large. An AWS conversion compresses the
// of what the API allows. // session policy document, session policy ARNs, and session tags into a packed
// binary format that has a separate limit. The error message indicates by percentage
// how close the policies and tags are to the upper size limit. For more information,
// see Passing Session Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// You could receive this error even though you meet other defined session policy
// and session tag limits. For more information, see IAM and STS Entity Character
// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
// in the IAM User Guide.
// //
// * ErrCodeIDPRejectedClaimException "IDPRejectedClaim" // * ErrCodeIDPRejectedClaimException "IDPRejectedClaim"
// The identity provider (IdP) reported that authentication failed. This might // The identity provider (IdP) reported that authentication failed. This might
@ -547,11 +676,11 @@ func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityI
// can also mean that the claim has expired or has been explicitly revoked. // can also mean that the claim has expired or has been explicitly revoked.
// //
// * ErrCodeIDPCommunicationErrorException "IDPCommunicationError" // * ErrCodeIDPCommunicationErrorException "IDPCommunicationError"
// The request could not be fulfilled because the non-AWS identity provider // The request could not be fulfilled because the identity provider (IDP) that
// (IDP) that was asked to verify the incoming identity token could not be reached. // was asked to verify the incoming identity token could not be reached. This
// This is often a transient error caused by network conditions. Retry the request // is often a transient error caused by network conditions. Retry the request
// a limited number of times so that you don't exceed the request rate. If the // a limited number of times so that you don't exceed the request rate. If the
// error persists, the non-AWS identity provider might be down or not responding. // error persists, the identity provider might be down or not responding.
// //
// * ErrCodeInvalidIdentityTokenException "InvalidIdentityToken" // * ErrCodeInvalidIdentityTokenException "InvalidIdentityToken"
// The web identity token that was passed could not be validated by AWS. Get // The web identity token that was passed could not be validated by AWS. Get
@ -676,9 +805,9 @@ func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessag
// //
// Returned Error Codes: // Returned Error Codes:
// * ErrCodeInvalidAuthorizationMessageException "InvalidAuthorizationMessageException" // * ErrCodeInvalidAuthorizationMessageException "InvalidAuthorizationMessageException"
// This error is returned if the message passed to DecodeAuthorizationMessage // The error returned if the message passed to DecodeAuthorizationMessage was
// was invalid. This can happen if the token contains invalid characters, such // invalid. This can happen if the token contains invalid characters, such as
// as linebreaks. // linebreaks.
// //
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage // See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage
func (c *STS) DecodeAuthorizationMessage(input *DecodeAuthorizationMessageInput) (*DecodeAuthorizationMessageOutput, error) { func (c *STS) DecodeAuthorizationMessage(input *DecodeAuthorizationMessageInput) (*DecodeAuthorizationMessageOutput, error) {
@ -763,7 +892,8 @@ func (c *STS) GetAccessKeyInfoRequest(input *GetAccessKeyInfoInput) (req *reques
// pull a credentials report (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_getting-report.html) // pull a credentials report (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_getting-report.html)
// to learn which IAM user owns the keys. To learn who requested the temporary // to learn which IAM user owns the keys. To learn who requested the temporary
// credentials for an ASIA access key, view the STS events in your CloudTrail // credentials for an ASIA access key, view the STS events in your CloudTrail
// logs (https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html). // logs (https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html)
// in the IAM User Guide.
// //
// This operation does not indicate the state of the access key. The key might // This operation does not indicate the state of the access key. The key might
// be active, inactive, or deleted. Active keys might not have permissions to // be active, inactive, or deleted. Active keys might not have permissions to
@ -850,7 +980,8 @@ func (c *STS) GetCallerIdentityRequest(input *GetCallerIdentityInput) (req *requ
// sts:GetCallerIdentity action, you can still perform this operation. Permissions // sts:GetCallerIdentity action, you can still perform this operation. Permissions
// are not required because the same information is returned when an IAM user // are not required because the same information is returned when an IAM user
// or role is denied access. To view an example response, see I Am Not Authorized // or role is denied access. To view an example response, see I Am Not Authorized
// to Perform: iam:DeleteVirtualMFADevice (https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_access-denied-delete-mfa). // to Perform: iam:DeleteVirtualMFADevice (https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_access-denied-delete-mfa)
// in the IAM User Guide.
// //
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions // 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 // with awserr.Error's Code and Message methods to get detailed information about
@ -942,7 +1073,8 @@ func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *re
// or an OpenID Connect-compatible identity provider. In this case, we recommend // or an OpenID Connect-compatible identity provider. In this case, we recommend
// that you use Amazon Cognito (http://aws.amazon.com/cognito/) or AssumeRoleWithWebIdentity. // that you use Amazon Cognito (http://aws.amazon.com/cognito/) or AssumeRoleWithWebIdentity.
// For more information, see Federation Through a Web-based Identity Provider // For more information, see Federation Through a Web-based Identity Provider
// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity). // (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity)
// in the IAM User Guide.
// //
// You can also call GetFederationToken using the security credentials of an // You can also call GetFederationToken using the security credentials of an
// AWS account root user, but we do not recommend it. Instead, we recommend // AWS account root user, but we do not recommend it. Instead, we recommend
@ -952,41 +1084,67 @@ func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *re
// Practices (https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) // Practices (https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)
// in the IAM User Guide. // in the IAM User Guide.
// //
// Session duration
//
// The temporary credentials are valid for the specified duration, from 900 // The temporary credentials are valid for the specified duration, from 900
// seconds (15 minutes) up to a maximum of 129,600 seconds (36 hours). The default // seconds (15 minutes) up to a maximum of 129,600 seconds (36 hours). The default
// is 43,200 seconds (12 hours). Temporary credentials that are obtained by // session duration is 43,200 seconds (12 hours). Temporary credentials that
// using AWS account root user credentials have a maximum duration of 3,600 // are obtained by using AWS account root user credentials have a maximum duration
// seconds (1 hour). // of 3,600 seconds (1 hour).
//
// The temporary security credentials created by GetFederationToken can be used
// to make API calls to any AWS service with the following exceptions:
//
// * You cannot use these credentials to call any IAM API operations.
//
// * You cannot call any STS API operations except GetCallerIdentity.
// //
// Permissions // Permissions
// //
// You can use the temporary credentials created by GetFederationToken in any
// AWS service except the following:
//
// * You cannot call any IAM operations using the AWS CLI or the AWS API.
//
// * You cannot call any STS operations except GetCallerIdentity.
//
// You must pass an inline or managed session policy (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) // You must pass an inline or managed session policy (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// to this operation. You can pass a single JSON policy document to use as an // to this operation. You can pass a single JSON policy document to use as an
// inline session policy. You can also specify up to 10 managed policies to // inline session policy. You can also specify up to 10 managed policies to
// use as managed session policies. The plain text that you use for both inline // use as managed session policies. The plain text that you use for both inline
// and managed session policies shouldn't exceed 2048 characters. // and managed session policies can't exceed 2,048 characters.
// //
// Though the session policy parameters are optional, if you do not pass a policy, // Though the session policy parameters are optional, if you do not pass a policy,
// then the resulting federated user session has no permissions. The only exception // then the resulting federated user session has no permissions. When you pass
// is when the credentials are used to access a resource that has a resource-based // session policies, the session permissions are the intersection of the IAM
// policy that specifically references the federated user session in the Principal // user policies and the session policies that you pass. This gives you a way
// element of the policy. When you pass session policies, the session permissions // to further restrict the permissions for a federated user. You cannot use
// are the intersection of the IAM user policies and the session policies that // session policies to grant more permissions than those that are defined in
// you pass. This gives you a way to further restrict the permissions for a // the permissions policy of the IAM user. For more information, see Session
// federated user. You cannot use session policies to grant more permissions // Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// than those that are defined in the permissions policy of the IAM user. For
// more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// in the IAM User Guide. For information about using GetFederationToken to // in the IAM User Guide. For information about using GetFederationToken to
// create temporary security credentials, see GetFederationToken—Federation // create temporary security credentials, see GetFederationToken—Federation
// Through a Custom Identity Broker (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getfederationtoken). // Through a Custom Identity Broker (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getfederationtoken).
// //
// You can use the credentials to access a resource that has a resource-based
// policy. If that policy specifically references the federated user session
// in the Principal element of the policy, the session has the permissions allowed
// by the policy. These permissions are granted in addition to the permissions
// granted by the session policies.
//
// Tags
//
// (Optional) You can pass tag key-value pairs to your session. These are called
// session tags. For more information about session tags, see Passing Session
// Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// An administrator must grant you the permissions necessary to pass session
// tags. The administrator can also create granular permissions to allow you
// to pass only specific session tags. For more information, see Tutorial: Using
// Tags for Attribute-Based Access Control (https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html)
// in the IAM User Guide.
//
// Tag keyvalue pairs are not case sensitive, but case is preserved. This
// means that you cannot have separate Department and department tag keys. Assume
// that the user that you are federating has the Department=Marketing tag and
// you pass the department=engineering session tag. Department and department
// are not saved as separate tags, and the session tag passed in the request
// takes precedence over the user tag.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions // 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 // with awserr.Error's Code and Message methods to get detailed information about
// the error. // the error.
@ -1000,9 +1158,18 @@ func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *re
// message describes the specific error. // message describes the specific error.
// //
// * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge" // * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge"
// The request was rejected because the policy document was too large. The error // The request was rejected because the total packed size of the session policies
// message describes how big the policy document is, in packed form, as a percentage // and session tags combined was too large. An AWS conversion compresses the
// of what the API allows. // session policy document, session policy ARNs, and session tags into a packed
// binary format that has a separate limit. The error message indicates by percentage
// how close the policies and tags are to the upper size limit. For more information,
// see Passing Session Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// You could receive this error even though you meet other defined session policy
// and session tag limits. For more information, see IAM and STS Entity Character
// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
// in the IAM User Guide.
// //
// * ErrCodeRegionDisabledException "RegionDisabledException" // * ErrCodeRegionDisabledException "RegionDisabledException"
// STS is not activated in the requested region for the account that is being // STS is not activated in the requested region for the account that is being
@ -1091,6 +1258,8 @@ func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request.
// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) // and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison)
// in the IAM User Guide. // in the IAM User Guide.
// //
// Session Duration
//
// The GetSessionToken operation must be called by using the long-term AWS security // The GetSessionToken operation must be called by using the long-term AWS security
// credentials of the AWS account root user or an IAM user. Credentials that // credentials of the AWS account root user or an IAM user. Credentials that
// are created by IAM users are valid for the duration that you specify. This // are created by IAM users are valid for the duration that you specify. This
@ -1099,6 +1268,8 @@ func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request.
// based on account credentials can range from 900 seconds (15 minutes) up to // based on account credentials can range from 900 seconds (15 minutes) up to
// 3,600 seconds (1 hour), with a default of 1 hour. // 3,600 seconds (1 hour), with a default of 1 hour.
// //
// Permissions
//
// The temporary security credentials created by GetSessionToken can be used // The temporary security credentials created by GetSessionToken can be used
// to make API calls to any AWS service with the following exceptions: // to make API calls to any AWS service with the following exceptions:
// //
@ -1213,16 +1384,16 @@ type AssumeRoleInput struct {
// in the IAM User Guide. // in the IAM User Guide.
// //
// The plain text that you use for both inline and managed session policies // The plain text that you use for both inline and managed session policies
// shouldn't exceed 2048 characters. The JSON policy characters can be any ASCII // can't exceed 2,048 characters. The JSON policy characters can be any ASCII
// character from the space character to the end of the valid character list // character from the space character to the end of the valid character list
// (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), // (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A),
// and carriage return (\u000D) characters. // and carriage return (\u000D) characters.
// //
// The characters in this parameter count towards the 2048 character session // An AWS conversion compresses the passed session policies and session tags
// policy guideline. However, an AWS conversion compresses the session policies // into a packed binary format that has a separate limit. Your request can fail
// into a packed binary format that has a separate limit. This is the enforced // for this limit even if your plain text meets the other requirements. The
// limit. The PackedPolicySize response element indicates by percentage how // PackedPolicySize response element indicates by percentage how close the policies
// close the policy is to the upper size limit. // and tags for your request are to the upper size limit.
Policy *string `min:"1" type:"string"` Policy *string `min:"1" type:"string"`
// The Amazon Resource Names (ARNs) of the IAM managed policies that you want // The Amazon Resource Names (ARNs) of the IAM managed policies that you want
@ -1231,15 +1402,15 @@ type AssumeRoleInput struct {
// //
// This parameter is optional. You can provide up to 10 managed policy ARNs. // This parameter is optional. You can provide up to 10 managed policy ARNs.
// However, the plain text that you use for both inline and managed session // However, the plain text that you use for both inline and managed session
// policies shouldn't exceed 2048 characters. For more information about ARNs, // policies can't exceed 2,048 characters. For more information about ARNs,
// see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) // see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
// in the AWS General Reference. // in the AWS General Reference.
// //
// The characters in this parameter count towards the 2048 character session // An AWS conversion compresses the passed session policies and session tags
// policy guideline. However, an AWS conversion compresses the session policies // into a packed binary format that has a separate limit. Your request can fail
// into a packed binary format that has a separate limit. This is the enforced // for this limit even if your plain text meets the other requirements. The
// limit. The PackedPolicySize response element indicates by percentage how // PackedPolicySize response element indicates by percentage how close the policies
// close the policy is to the upper size limit. // and tags for your request are to the upper size limit.
// //
// Passing policies to this operation returns new temporary credentials. The // Passing policies to this operation returns new temporary credentials. The
// resulting session's permissions are the intersection of the role's identity-based // resulting session's permissions are the intersection of the role's identity-based
@ -1284,6 +1455,41 @@ type AssumeRoleInput struct {
// also include underscores or any of the following characters: =,.@- // also include underscores or any of the following characters: =,.@-
SerialNumber *string `min:"9" type:"string"` SerialNumber *string `min:"9" type:"string"`
// A list of session tags that you want to pass. Each session tag consists of
// a key name and an associated value. For more information about session tags,
// see Tagging AWS STS Sessions (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// This parameter is optional. You can pass up to 50 session tags. The plain
// text session tag keys cant exceed 128 characters, and the values cant
// exceed 256 characters. For these and additional limits, see IAM and STS Character
// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length)
// in the IAM User Guide.
//
// An AWS conversion compresses the passed session policies and session tags
// into a packed binary format that has a separate limit. Your request can fail
// for this limit even if your plain text meets the other requirements. The
// PackedPolicySize response element indicates by percentage how close the policies
// and tags for your request are to the upper size limit.
//
// You can pass a session tag with the same key as a tag that is already attached
// to the role. When you do, session tags override a role tag with the same
// key.
//
// Tag keyvalue pairs are not case sensitive, but case is preserved. This
// means that you cannot have separate Department and department tag keys. Assume
// that the role has the Department=Marketing tag and you pass the department=engineering
// session tag. Department and department are not saved as separate tags, and
// the session tag passed in the request takes precedence over the role tag.
//
// Additionally, if you used temporary credentials to perform this operation,
// the new session inherits any transitive session tags from the calling session.
// If you pass a session tag with the same key as an inherited tag, the operation
// fails. To view the inherited tags for a session, see the AWS CloudTrail logs.
// For more information, see Viewing Session Tags in CloudTrail (https://docs.aws.amazon.com/IAM/latest/UserGuide/session-tags.html#id_session-tags_ctlogs)
// in the IAM User Guide.
Tags []*Tag `type:"list"`
// The value provided by the MFA device, if the trust policy of the role being // 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 // 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 // for MFA). If the role being assumed requires MFA and if the TokenCode value
@ -1292,6 +1498,19 @@ type AssumeRoleInput struct {
// The format for this parameter, as described by its regex pattern, is a sequence // The format for this parameter, as described by its regex pattern, is a sequence
// of six numeric digits. // of six numeric digits.
TokenCode *string `min:"6" type:"string"` TokenCode *string `min:"6" type:"string"`
// A list of keys for session tags that you want to set as transitive. If you
// set a tag key as transitive, the corresponding key and value passes to subsequent
// sessions in a role chain. For more information, see Chaining Roles with Session
// Tags (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining)
// in the IAM User Guide.
//
// This parameter is optional. When you set session tags as transitive, the
// session policy and session tags packed binary limit is not affected.
//
// If you choose not to specify a transitive tag key, then no tags are passed
// from this session to any subsequent sessions.
TransitiveTagKeys []*string `type:"list"`
} }
// String returns the string representation // String returns the string representation
@ -1344,6 +1563,16 @@ func (s *AssumeRoleInput) Validate() error {
} }
} }
} }
if s.Tags != nil {
for i, v := range s.Tags {
if v == nil {
continue
}
if err := v.Validate(); err != nil {
invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
}
}
}
if invalidParams.Len() > 0 { if invalidParams.Len() > 0 {
return invalidParams return invalidParams
@ -1393,12 +1622,24 @@ func (s *AssumeRoleInput) SetSerialNumber(v string) *AssumeRoleInput {
return s return s
} }
// SetTags sets the Tags field's value.
func (s *AssumeRoleInput) SetTags(v []*Tag) *AssumeRoleInput {
s.Tags = v
return s
}
// SetTokenCode sets the TokenCode field's value. // SetTokenCode sets the TokenCode field's value.
func (s *AssumeRoleInput) SetTokenCode(v string) *AssumeRoleInput { func (s *AssumeRoleInput) SetTokenCode(v string) *AssumeRoleInput {
s.TokenCode = &v s.TokenCode = &v
return s return s
} }
// SetTransitiveTagKeys sets the TransitiveTagKeys field's value.
func (s *AssumeRoleInput) SetTransitiveTagKeys(v []*string) *AssumeRoleInput {
s.TransitiveTagKeys = v
return s
}
// Contains the response to a successful AssumeRole request, including temporary // Contains the response to a successful AssumeRole request, including temporary
// AWS credentials that can be used to make AWS requests. // AWS credentials that can be used to make AWS requests.
type AssumeRoleOutput struct { type AssumeRoleOutput struct {
@ -1418,9 +1659,10 @@ type AssumeRoleOutput struct {
// We strongly recommend that you make no assumptions about the maximum size. // We strongly recommend that you make no assumptions about the maximum size.
Credentials *Credentials `type:"structure"` Credentials *Credentials `type:"structure"`
// A percentage value that indicates the size of the policy in packed form. // A percentage value that indicates the packed size of the session policies
// The service rejects any policy with a packed size greater than 100 percent, // and session tags combined passed in the request. The request fails if the
// which means the policy exceeded the allowed space. // packed size is greater than 100 percent, which means the policies and tags
// exceeded the allowed space.
PackedPolicySize *int64 `type:"integer"` PackedPolicySize *int64 `type:"integer"`
} }
@ -1491,16 +1733,16 @@ type AssumeRoleWithSAMLInput struct {
// in the IAM User Guide. // in the IAM User Guide.
// //
// The plain text that you use for both inline and managed session policies // The plain text that you use for both inline and managed session policies
// shouldn't exceed 2048 characters. The JSON policy characters can be any ASCII // can't exceed 2,048 characters. The JSON policy characters can be any ASCII
// character from the space character to the end of the valid character list // character from the space character to the end of the valid character list
// (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), // (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A),
// and carriage return (\u000D) characters. // and carriage return (\u000D) characters.
// //
// The characters in this parameter count towards the 2048 character session // An AWS conversion compresses the passed session policies and session tags
// policy guideline. However, an AWS conversion compresses the session policies // into a packed binary format that has a separate limit. Your request can fail
// into a packed binary format that has a separate limit. This is the enforced // for this limit even if your plain text meets the other requirements. The
// limit. The PackedPolicySize response element indicates by percentage how // PackedPolicySize response element indicates by percentage how close the policies
// close the policy is to the upper size limit. // and tags for your request are to the upper size limit.
Policy *string `min:"1" type:"string"` Policy *string `min:"1" type:"string"`
// The Amazon Resource Names (ARNs) of the IAM managed policies that you want // The Amazon Resource Names (ARNs) of the IAM managed policies that you want
@ -1509,15 +1751,15 @@ type AssumeRoleWithSAMLInput struct {
// //
// This parameter is optional. You can provide up to 10 managed policy ARNs. // This parameter is optional. You can provide up to 10 managed policy ARNs.
// However, the plain text that you use for both inline and managed session // However, the plain text that you use for both inline and managed session
// policies shouldn't exceed 2048 characters. For more information about ARNs, // policies can't exceed 2,048 characters. For more information about ARNs,
// see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) // see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
// in the AWS General Reference. // in the AWS General Reference.
// //
// The characters in this parameter count towards the 2048 character session // An AWS conversion compresses the passed session policies and session tags
// policy guideline. However, an AWS conversion compresses the session policies // into a packed binary format that has a separate limit. Your request can fail
// into a packed binary format that has a separate limit. This is the enforced // for this limit even if your plain text meets the other requirements. The
// limit. The PackedPolicySize response element indicates by percentage how // PackedPolicySize response element indicates by percentage how close the policies
// close the policy is to the upper size limit. // and tags for your request are to the upper size limit.
// //
// Passing policies to this operation returns new temporary credentials. The // Passing policies to this operation returns new temporary credentials. The
// resulting session's permissions are the intersection of the role's identity-based // resulting session's permissions are the intersection of the role's identity-based
@ -1673,9 +1915,10 @@ type AssumeRoleWithSAMLOutput struct {
// ) ) // ) )
NameQualifier *string `type:"string"` NameQualifier *string `type:"string"`
// A percentage value that indicates the size of the policy in packed form. // A percentage value that indicates the packed size of the session policies
// The service rejects any policy with a packed size greater than 100 percent, // and session tags combined passed in the request. The request fails if the
// which means the policy exceeded the allowed space. // packed size is greater than 100 percent, which means the policies and tags
// exceeded the allowed space.
PackedPolicySize *int64 `type:"integer"` PackedPolicySize *int64 `type:"integer"`
// The value of the NameID element in the Subject element of the SAML assertion. // The value of the NameID element in the Subject element of the SAML assertion.
@ -1786,16 +2029,16 @@ type AssumeRoleWithWebIdentityInput struct {
// in the IAM User Guide. // in the IAM User Guide.
// //
// The plain text that you use for both inline and managed session policies // The plain text that you use for both inline and managed session policies
// shouldn't exceed 2048 characters. The JSON policy characters can be any ASCII // can't exceed 2,048 characters. The JSON policy characters can be any ASCII
// character from the space character to the end of the valid character list // character from the space character to the end of the valid character list
// (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), // (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A),
// and carriage return (\u000D) characters. // and carriage return (\u000D) characters.
// //
// The characters in this parameter count towards the 2048 character session // An AWS conversion compresses the passed session policies and session tags
// policy guideline. However, an AWS conversion compresses the session policies // into a packed binary format that has a separate limit. Your request can fail
// into a packed binary format that has a separate limit. This is the enforced // for this limit even if your plain text meets the other requirements. The
// limit. The PackedPolicySize response element indicates by percentage how // PackedPolicySize response element indicates by percentage how close the policies
// close the policy is to the upper size limit. // and tags for your request are to the upper size limit.
Policy *string `min:"1" type:"string"` Policy *string `min:"1" type:"string"`
// The Amazon Resource Names (ARNs) of the IAM managed policies that you want // The Amazon Resource Names (ARNs) of the IAM managed policies that you want
@ -1804,15 +2047,15 @@ type AssumeRoleWithWebIdentityInput struct {
// //
// This parameter is optional. You can provide up to 10 managed policy ARNs. // This parameter is optional. You can provide up to 10 managed policy ARNs.
// However, the plain text that you use for both inline and managed session // However, the plain text that you use for both inline and managed session
// policies shouldn't exceed 2048 characters. For more information about ARNs, // policies can't exceed 2,048 characters. For more information about ARNs,
// see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) // see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
// in the AWS General Reference. // in the AWS General Reference.
// //
// The characters in this parameter count towards the 2048 character session // An AWS conversion compresses the passed session policies and session tags
// policy guideline. However, an AWS conversion compresses the session policies // into a packed binary format that has a separate limit. Your request can fail
// into a packed binary format that has a separate limit. This is the enforced // for this limit even if your plain text meets the other requirements. The
// limit. The PackedPolicySize response element indicates by percentage how // PackedPolicySize response element indicates by percentage how close the policies
// close the policy is to the upper size limit. // and tags for your request are to the upper size limit.
// //
// Passing policies to this operation returns new temporary credentials. The // Passing policies to this operation returns new temporary credentials. The
// resulting session's permissions are the intersection of the role's identity-based // resulting session's permissions are the intersection of the role's identity-based
@ -1983,9 +2226,10 @@ type AssumeRoleWithWebIdentityOutput struct {
// We strongly recommend that you make no assumptions about the maximum size. // We strongly recommend that you make no assumptions about the maximum size.
Credentials *Credentials `type:"structure"` Credentials *Credentials `type:"structure"`
// A percentage value that indicates the size of the policy in packed form. // A percentage value that indicates the packed size of the session policies
// The service rejects any policy with a packed size greater than 100 percent, // and session tags combined passed in the request. The request fails if the
// which means the policy exceeded the allowed space. // packed size is greater than 100 percent, which means the policies and tags
// exceeded the allowed space.
PackedPolicySize *int64 `type:"integer"` PackedPolicySize *int64 `type:"integer"`
// The issuing authority of the web identity token presented. For OpenID Connect // The issuing authority of the web identity token presented. For OpenID Connect
@ -2057,7 +2301,7 @@ type AssumedRoleUser struct {
// The ARN of the temporary security credentials that are returned from the // The ARN of the temporary security credentials that are returned from the
// AssumeRole action. For more information about ARNs and how to use them in // AssumeRole action. For more information about ARNs and how to use them in
// policies, see IAM Identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) // policies, see IAM Identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html)
// in Using IAM. // in the IAM User Guide.
// //
// Arn is a required field // Arn is a required field
Arn *string `min:"20" type:"string" required:"true"` Arn *string `min:"20" type:"string" required:"true"`
@ -2225,7 +2469,7 @@ type FederatedUser struct {
// The ARN that specifies the federated user that is associated with the credentials. // The ARN that specifies the federated user that is associated with the credentials.
// For more information about ARNs and how to use them in policies, see IAM // For more information about ARNs and how to use them in policies, see IAM
// Identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) // Identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html)
// in Using IAM. // in the IAM User Guide.
// //
// Arn is a required field // Arn is a required field
Arn *string `min:"20" type:"string" required:"true"` Arn *string `min:"20" type:"string" required:"true"`
@ -2265,7 +2509,7 @@ type GetAccessKeyInfoInput struct {
// The identifier of an access key. // The identifier of an access key.
// //
// This parameter allows (through its regex pattern) a string of characters // This parameter allows (through its regex pattern) a string of characters
// that can consist of any upper- or lowercased letter or digit. // that can consist of any upper- or lowercase letter or digit.
// //
// AccessKeyId is a required field // AccessKeyId is a required field
AccessKeyId *string `min:"16" type:"string" required:"true"` AccessKeyId *string `min:"16" type:"string" required:"true"`
@ -2418,10 +2662,7 @@ type GetFederationTokenInput struct {
// use as managed session policies. // use as managed session policies.
// //
// This parameter is optional. However, if you do not pass any session policies, // This parameter is optional. However, if you do not pass any session policies,
// then the resulting federated user session has no permissions. The only exception // then the resulting federated user session has no permissions.
// is when the credentials are used to access a resource that has a resource-based
// policy that specifically references the federated user session in the Principal
// element of the policy.
// //
// When you pass session policies, the session permissions are the intersection // When you pass session policies, the session permissions are the intersection
// of the IAM user policies and the session policies that you pass. This gives // of the IAM user policies and the session policies that you pass. This gives
@ -2431,17 +2672,23 @@ type GetFederationTokenInput struct {
// Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) // Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// in the IAM User Guide. // in the IAM User Guide.
// //
// The resulting credentials can be used to access a resource that has a resource-based
// policy. If that policy specifically references the federated user session
// in the Principal element of the policy, the session has the permissions allowed
// by the policy. These permissions are granted in addition to the permissions
// that are granted by the session policies.
//
// The plain text that you use for both inline and managed session policies // The plain text that you use for both inline and managed session policies
// shouldn't exceed 2048 characters. The JSON policy characters can be any ASCII // can't exceed 2,048 characters. The JSON policy characters can be any ASCII
// character from the space character to the end of the valid character list // character from the space character to the end of the valid character list
// (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), // (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A),
// and carriage return (\u000D) characters. // and carriage return (\u000D) characters.
// //
// The characters in this parameter count towards the 2048 character session // An AWS conversion compresses the passed session policies and session tags
// policy guideline. However, an AWS conversion compresses the session policies // into a packed binary format that has a separate limit. Your request can fail
// into a packed binary format that has a separate limit. This is the enforced // for this limit even if your plain text meets the other requirements. The
// limit. The PackedPolicySize response element indicates by percentage how // PackedPolicySize response element indicates by percentage how close the policies
// close the policy is to the upper size limit. // and tags for your request are to the upper size limit.
Policy *string `min:"1" type:"string"` Policy *string `min:"1" type:"string"`
// The Amazon Resource Names (ARNs) of the IAM managed policies that you want // The Amazon Resource Names (ARNs) of the IAM managed policies that you want
@ -2452,16 +2699,13 @@ type GetFederationTokenInput struct {
// to this operation. You can pass a single JSON policy document to use as an // to this operation. You can pass a single JSON policy document to use as an
// inline session policy. You can also specify up to 10 managed policies to // inline session policy. You can also specify up to 10 managed policies to
// use as managed session policies. The plain text that you use for both inline // use as managed session policies. The plain text that you use for both inline
// and managed session policies shouldn't exceed 2048 characters. You can provide // and managed session policies can't exceed 2,048 characters. You can provide
// up to 10 managed policy ARNs. For more information about ARNs, see Amazon // up to 10 managed policy ARNs. For more information about ARNs, see Amazon
// Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) // Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
// in the AWS General Reference. // in the AWS General Reference.
// //
// This parameter is optional. However, if you do not pass any session policies, // This parameter is optional. However, if you do not pass any session policies,
// then the resulting federated user session has no permissions. The only exception // then the resulting federated user session has no permissions.
// is when the credentials are used to access a resource that has a resource-based
// policy that specifically references the federated user session in the Principal
// element of the policy.
// //
// When you pass session policies, the session permissions are the intersection // When you pass session policies, the session permissions are the intersection
// of the IAM user policies and the session policies that you pass. This gives // of the IAM user policies and the session policies that you pass. This gives
@ -2471,12 +2715,46 @@ type GetFederationTokenInput struct {
// Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) // Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session)
// in the IAM User Guide. // in the IAM User Guide.
// //
// The characters in this parameter count towards the 2048 character session // The resulting credentials can be used to access a resource that has a resource-based
// policy guideline. However, an AWS conversion compresses the session policies // policy. If that policy specifically references the federated user session
// into a packed binary format that has a separate limit. This is the enforced // in the Principal element of the policy, the session has the permissions allowed
// limit. The PackedPolicySize response element indicates by percentage how // by the policy. These permissions are granted in addition to the permissions
// close the policy is to the upper size limit. // that are granted by the session policies.
//
// An AWS conversion compresses the passed session policies and session tags
// into a packed binary format that has a separate limit. Your request can fail
// for this limit even if your plain text meets the other requirements. The
// PackedPolicySize response element indicates by percentage how close the policies
// and tags for your request are to the upper size limit.
PolicyArns []*PolicyDescriptorType `type:"list"` PolicyArns []*PolicyDescriptorType `type:"list"`
// A list of session tags. Each session tag consists of a key name and an associated
// value. For more information about session tags, see Passing Session Tags
// in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// This parameter is optional. You can pass up to 50 session tags. The plain
// text session tag keys cant exceed 128 characters and the values cant
// exceed 256 characters. For these and additional limits, see IAM and STS Character
// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length)
// in the IAM User Guide.
//
// An AWS conversion compresses the passed session policies and session tags
// into a packed binary format that has a separate limit. Your request can fail
// for this limit even if your plain text meets the other requirements. The
// PackedPolicySize response element indicates by percentage how close the policies
// and tags for your request are to the upper size limit.
//
// You can pass a session tag with the same key as a tag that is already attached
// to the user you are federating. When you do, session tags override a user
// tag with the same key.
//
// Tag keyvalue pairs are not case sensitive, but case is preserved. This
// means that you cannot have separate Department and department tag keys. Assume
// that the role has the Department=Marketing tag and you pass the department=engineering
// session tag. Department and department are not saved as separate tags, and
// the session tag passed in the request takes precedence over the role tag.
Tags []*Tag `type:"list"`
} }
// String returns the string representation // String returns the string representation
@ -2514,6 +2792,16 @@ func (s *GetFederationTokenInput) Validate() error {
} }
} }
} }
if s.Tags != nil {
for i, v := range s.Tags {
if v == nil {
continue
}
if err := v.Validate(); err != nil {
invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
}
}
}
if invalidParams.Len() > 0 { if invalidParams.Len() > 0 {
return invalidParams return invalidParams
@ -2545,6 +2833,12 @@ func (s *GetFederationTokenInput) SetPolicyArns(v []*PolicyDescriptorType) *GetF
return s return s
} }
// SetTags sets the Tags field's value.
func (s *GetFederationTokenInput) SetTags(v []*Tag) *GetFederationTokenInput {
s.Tags = v
return s
}
// Contains the response to a successful GetFederationToken request, including // Contains the response to a successful GetFederationToken request, including
// temporary AWS credentials that can be used to make AWS requests. // temporary AWS credentials that can be used to make AWS requests.
type GetFederationTokenOutput struct { type GetFederationTokenOutput struct {
@ -2563,9 +2857,10 @@ type GetFederationTokenOutput struct {
// an Amazon S3 bucket policy. // an Amazon S3 bucket policy.
FederatedUser *FederatedUser `type:"structure"` FederatedUser *FederatedUser `type:"structure"`
// A percentage value indicating the size of the policy in packed form. The // A percentage value that indicates the packed size of the session policies
// service rejects policies for which the packed size is greater than 100 percent // and session tags combined passed in the request. The request fails if the
// of the allowed value. // packed size is greater than 100 percent, which means the policies and tags
// exceeded the allowed space.
PackedPolicySize *int64 `type:"integer"` PackedPolicySize *int64 `type:"integer"`
} }
@ -2748,3 +3043,73 @@ func (s *PolicyDescriptorType) SetArn(v string) *PolicyDescriptorType {
s.Arn = &v s.Arn = &v
return s return s
} }
// You can pass custom key-value pair attributes when you assume a role or federate
// a user. These are called session tags. You can then use the session tags
// to control access to resources. For more information, see Tagging AWS STS
// Sessions (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
type Tag struct {
_ struct{} `type:"structure"`
// The key for a session tag.
//
// You can pass up to 50 session tags. The plain text session tag keys cant
// exceed 128 characters. For these and additional limits, see IAM and STS Character
// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length)
// in the IAM User Guide.
//
// Key is a required field
Key *string `min:"1" type:"string" required:"true"`
// The value for a session tag.
//
// You can pass up to 50 session tags. The plain text session tag values cant
// exceed 256 characters. For these and additional limits, see IAM and STS Character
// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length)
// in the IAM User Guide.
//
// Value is a required field
Value *string `type:"string" required:"true"`
}
// String returns the string representation
func (s Tag) String() string {
return awsutil.Prettify(s)
}
// GoString returns the string representation
func (s Tag) GoString() string {
return s.String()
}
// Validate inspects the fields of the type to determine if they are valid.
func (s *Tag) Validate() error {
invalidParams := request.ErrInvalidParams{Context: "Tag"}
if s.Key == nil {
invalidParams.Add(request.NewErrParamRequired("Key"))
}
if s.Key != nil && len(*s.Key) < 1 {
invalidParams.Add(request.NewErrParamMinLen("Key", 1))
}
if s.Value == nil {
invalidParams.Add(request.NewErrParamRequired("Value"))
}
if invalidParams.Len() > 0 {
return invalidParams
}
return nil
}
// SetKey sets the Key field's value.
func (s *Tag) SetKey(v string) *Tag {
s.Key = &v
return s
}
// SetValue sets the Value field's value.
func (s *Tag) SetValue(v string) *Tag {
s.Value = &v
return s
}

View file

@ -14,11 +14,11 @@ const (
// ErrCodeIDPCommunicationErrorException for service response error code // ErrCodeIDPCommunicationErrorException for service response error code
// "IDPCommunicationError". // "IDPCommunicationError".
// //
// The request could not be fulfilled because the non-AWS identity provider // The request could not be fulfilled because the identity provider (IDP) that
// (IDP) that was asked to verify the incoming identity token could not be reached. // was asked to verify the incoming identity token could not be reached. This
// This is often a transient error caused by network conditions. Retry the request // is often a transient error caused by network conditions. Retry the request
// a limited number of times so that you don't exceed the request rate. If the // a limited number of times so that you don't exceed the request rate. If the
// error persists, the non-AWS identity provider might be down or not responding. // error persists, the identity provider might be down or not responding.
ErrCodeIDPCommunicationErrorException = "IDPCommunicationError" ErrCodeIDPCommunicationErrorException = "IDPCommunicationError"
// ErrCodeIDPRejectedClaimException for service response error code // ErrCodeIDPRejectedClaimException for service response error code
@ -34,9 +34,9 @@ const (
// ErrCodeInvalidAuthorizationMessageException for service response error code // ErrCodeInvalidAuthorizationMessageException for service response error code
// "InvalidAuthorizationMessageException". // "InvalidAuthorizationMessageException".
// //
// This error is returned if the message passed to DecodeAuthorizationMessage // The error returned if the message passed to DecodeAuthorizationMessage was
// was invalid. This can happen if the token contains invalid characters, such // invalid. This can happen if the token contains invalid characters, such as
// as linebreaks. // linebreaks.
ErrCodeInvalidAuthorizationMessageException = "InvalidAuthorizationMessageException" ErrCodeInvalidAuthorizationMessageException = "InvalidAuthorizationMessageException"
// ErrCodeInvalidIdentityTokenException for service response error code // ErrCodeInvalidIdentityTokenException for service response error code
@ -56,9 +56,18 @@ const (
// ErrCodePackedPolicyTooLargeException for service response error code // ErrCodePackedPolicyTooLargeException for service response error code
// "PackedPolicyTooLarge". // "PackedPolicyTooLarge".
// //
// The request was rejected because the policy document was too large. The error // The request was rejected because the total packed size of the session policies
// message describes how big the policy document is, in packed form, as a percentage // and session tags combined was too large. An AWS conversion compresses the
// of what the API allows. // session policy document, session policy ARNs, and session tags into a packed
// binary format that has a separate limit. The error message indicates by percentage
// how close the policies and tags are to the upper size limit. For more information,
// see Passing Session Tags in STS (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html)
// in the IAM User Guide.
//
// You could receive this error even though you meet other defined session policy
// and session tag limits. For more information, see IAM and STS Entity Character
// Limits (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
// in the IAM User Guide.
ErrCodePackedPolicyTooLargeException = "PackedPolicyTooLarge" ErrCodePackedPolicyTooLargeException = "PackedPolicyTooLarge"
// ErrCodeRegionDisabledException for service response error code // ErrCodeRegionDisabledException for service response error code

View file

@ -31,7 +31,7 @@ var initRequest func(*request.Request)
const ( const (
ServiceName = "sts" // Name of service. ServiceName = "sts" // Name of service.
EndpointsID = ServiceName // ID to lookup a service endpoint with. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "STS" // ServiceID is a unique identifer of a specific service. ServiceID = "STS" // ServiceID is a unique identifier of a specific service.
) )
// New creates a new instance of the STS client with a session. // New creates a new instance of the STS client with a session.
@ -39,6 +39,8 @@ const (
// aws.Config parameter to add your extra config. // aws.Config parameter to add your extra config.
// //
// Example: // Example:
// mySession := session.Must(session.NewSession())
//
// // Create a STS client from just a session. // // Create a STS client from just a session.
// svc := sts.New(mySession) // svc := sts.New(mySession)
// //

View file

@ -1,20 +0,0 @@
package md2man
import (
"github.com/russross/blackfriday"
)
// Render converts a markdown document into a roff formatted document.
func Render(doc []byte) []byte {
renderer := RoffRenderer(0)
extensions := 0
extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS
extensions |= blackfriday.EXTENSION_TABLES
extensions |= blackfriday.EXTENSION_FENCED_CODE
extensions |= blackfriday.EXTENSION_AUTOLINK
extensions |= blackfriday.EXTENSION_SPACE_HEADERS
extensions |= blackfriday.EXTENSION_FOOTNOTES
extensions |= blackfriday.EXTENSION_TITLEBLOCK
return blackfriday.Markdown(doc, renderer, extensions)
}

View file

@ -1,285 +0,0 @@
package md2man
import (
"bytes"
"fmt"
"html"
"strings"
"github.com/russross/blackfriday"
)
type roffRenderer struct {
ListCounters []int
}
// RoffRenderer creates a new blackfriday Renderer for generating roff documents
// from markdown
func RoffRenderer(flags int) blackfriday.Renderer {
return &roffRenderer{}
}
func (r *roffRenderer) GetFlags() int {
return 0
}
func (r *roffRenderer) TitleBlock(out *bytes.Buffer, text []byte) {
out.WriteString(".TH ")
splitText := bytes.Split(text, []byte("\n"))
for i, line := range splitText {
line = bytes.TrimPrefix(line, []byte("% "))
if i == 0 {
line = bytes.Replace(line, []byte("("), []byte("\" \""), 1)
line = bytes.Replace(line, []byte(")"), []byte("\" \""), 1)
}
line = append([]byte("\""), line...)
line = append(line, []byte("\" ")...)
out.Write(line)
}
out.WriteString("\n")
// disable hyphenation
out.WriteString(".nh\n")
// disable justification (adjust text to left margin only)
out.WriteString(".ad l\n")
}
func (r *roffRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string) {
out.WriteString("\n.PP\n.RS\n\n.nf\n")
escapeSpecialChars(out, text)
out.WriteString("\n.fi\n.RE\n")
}
func (r *roffRenderer) BlockQuote(out *bytes.Buffer, text []byte) {
out.WriteString("\n.PP\n.RS\n")
out.Write(text)
out.WriteString("\n.RE\n")
}
func (r *roffRenderer) BlockHtml(out *bytes.Buffer, text []byte) { // nolint: golint
out.Write(text)
}
func (r *roffRenderer) Header(out *bytes.Buffer, text func() bool, level int, id string) {
marker := out.Len()
switch {
case marker == 0:
// This is the doc header
out.WriteString(".TH ")
case level == 1:
out.WriteString("\n\n.SH ")
case level == 2:
out.WriteString("\n.SH ")
default:
out.WriteString("\n.SS ")
}
if !text() {
out.Truncate(marker)
return
}
}
func (r *roffRenderer) HRule(out *bytes.Buffer) {
out.WriteString("\n.ti 0\n\\l'\\n(.lu'\n")
}
func (r *roffRenderer) List(out *bytes.Buffer, text func() bool, flags int) {
marker := out.Len()
r.ListCounters = append(r.ListCounters, 1)
out.WriteString("\n.RS\n")
if !text() {
out.Truncate(marker)
return
}
r.ListCounters = r.ListCounters[:len(r.ListCounters)-1]
out.WriteString("\n.RE\n")
}
func (r *roffRenderer) ListItem(out *bytes.Buffer, text []byte, flags int) {
if flags&blackfriday.LIST_TYPE_ORDERED != 0 {
out.WriteString(fmt.Sprintf(".IP \"%3d.\" 5\n", r.ListCounters[len(r.ListCounters)-1]))
r.ListCounters[len(r.ListCounters)-1]++
} else {
out.WriteString(".IP \\(bu 2\n")
}
out.Write(text)
out.WriteString("\n")
}
func (r *roffRenderer) Paragraph(out *bytes.Buffer, text func() bool) {
marker := out.Len()
out.WriteString("\n.PP\n")
if !text() {
out.Truncate(marker)
return
}
if marker != 0 {
out.WriteString("\n")
}
}
func (r *roffRenderer) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) {
out.WriteString("\n.TS\nallbox;\n")
maxDelims := 0
lines := strings.Split(strings.TrimRight(string(header), "\n")+"\n"+strings.TrimRight(string(body), "\n"), "\n")
for _, w := range lines {
curDelims := strings.Count(w, "\t")
if curDelims > maxDelims {
maxDelims = curDelims
}
}
out.Write([]byte(strings.Repeat("l ", maxDelims+1) + "\n"))
out.Write([]byte(strings.Repeat("l ", maxDelims+1) + ".\n"))
out.Write(header)
if len(header) > 0 {
out.Write([]byte("\n"))
}
out.Write(body)
out.WriteString("\n.TE\n")
}
func (r *roffRenderer) TableRow(out *bytes.Buffer, text []byte) {
if out.Len() > 0 {
out.WriteString("\n")
}
out.Write(text)
}
func (r *roffRenderer) TableHeaderCell(out *bytes.Buffer, text []byte, align int) {
if out.Len() > 0 {
out.WriteString("\t")
}
if len(text) == 0 {
text = []byte{' '}
}
out.Write([]byte("\\fB\\fC" + string(text) + "\\fR"))
}
func (r *roffRenderer) TableCell(out *bytes.Buffer, text []byte, align int) {
if out.Len() > 0 {
out.WriteString("\t")
}
if len(text) > 30 {
text = append([]byte("T{\n"), text...)
text = append(text, []byte("\nT}")...)
}
if len(text) == 0 {
text = []byte{' '}
}
out.Write(text)
}
func (r *roffRenderer) Footnotes(out *bytes.Buffer, text func() bool) {
}
func (r *roffRenderer) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) {
}
func (r *roffRenderer) AutoLink(out *bytes.Buffer, link []byte, kind int) {
out.WriteString("\n\\[la]")
out.Write(link)
out.WriteString("\\[ra]")
}
func (r *roffRenderer) CodeSpan(out *bytes.Buffer, text []byte) {
out.WriteString("\\fB\\fC")
escapeSpecialChars(out, text)
out.WriteString("\\fR")
}
func (r *roffRenderer) DoubleEmphasis(out *bytes.Buffer, text []byte) {
out.WriteString("\\fB")
out.Write(text)
out.WriteString("\\fP")
}
func (r *roffRenderer) Emphasis(out *bytes.Buffer, text []byte) {
out.WriteString("\\fI")
out.Write(text)
out.WriteString("\\fP")
}
func (r *roffRenderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
}
func (r *roffRenderer) LineBreak(out *bytes.Buffer) {
out.WriteString("\n.br\n")
}
func (r *roffRenderer) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
out.Write(content)
r.AutoLink(out, link, 0)
}
func (r *roffRenderer) RawHtmlTag(out *bytes.Buffer, tag []byte) { // nolint: golint
out.Write(tag)
}
func (r *roffRenderer) TripleEmphasis(out *bytes.Buffer, text []byte) {
out.WriteString("\\s+2")
out.Write(text)
out.WriteString("\\s-2")
}
func (r *roffRenderer) StrikeThrough(out *bytes.Buffer, text []byte) {
}
func (r *roffRenderer) FootnoteRef(out *bytes.Buffer, ref []byte, id int) {
}
func (r *roffRenderer) Entity(out *bytes.Buffer, entity []byte) {
out.WriteString(html.UnescapeString(string(entity)))
}
func (r *roffRenderer) NormalText(out *bytes.Buffer, text []byte) {
escapeSpecialChars(out, text)
}
func (r *roffRenderer) DocumentHeader(out *bytes.Buffer) {
}
func (r *roffRenderer) DocumentFooter(out *bytes.Buffer) {
}
func needsBackslash(c byte) bool {
for _, r := range []byte("-_&\\~") {
if c == r {
return true
}
}
return false
}
func escapeSpecialChars(out *bytes.Buffer, text []byte) {
for i := 0; i < len(text); i++ {
// escape initial apostrophe or period
if len(text) >= 1 && (text[0] == '\'' || text[0] == '.') {
out.WriteString("\\&")
}
// directly copy normal characters
org := i
for i < len(text) && !needsBackslash(text[i]) {
i++
}
if i > org {
out.Write(text[org:i])
}
// escape a character
if i >= len(text) {
break
}
out.WriteByte('\\')
out.WriteByte(text[i])
}
}

View file

@ -0,0 +1,14 @@
package md2man
import (
"github.com/russross/blackfriday/v2"
)
// Render converts a markdown document into a roff formatted document.
func Render(doc []byte) []byte {
renderer := NewRoffRenderer()
return blackfriday.Run(doc,
[]blackfriday.Option{blackfriday.WithRenderer(renderer),
blackfriday.WithExtensions(renderer.GetExtensions())}...)
}

345
vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go generated vendored Normal file
View file

@ -0,0 +1,345 @@
package md2man
import (
"fmt"
"io"
"os"
"strings"
"github.com/russross/blackfriday/v2"
)
// roffRenderer implements the blackfriday.Renderer interface for creating
// roff format (manpages) from markdown text
type roffRenderer struct {
extensions blackfriday.Extensions
listCounters []int
firstHeader bool
defineTerm bool
listDepth int
}
const (
titleHeader = ".TH "
topLevelHeader = "\n\n.SH "
secondLevelHdr = "\n.SH "
otherHeader = "\n.SS "
crTag = "\n"
emphTag = "\\fI"
emphCloseTag = "\\fP"
strongTag = "\\fB"
strongCloseTag = "\\fP"
breakTag = "\n.br\n"
paraTag = "\n.PP\n"
hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n"
linkTag = "\n\\[la]"
linkCloseTag = "\\[ra]"
codespanTag = "\\fB\\fC"
codespanCloseTag = "\\fR"
codeTag = "\n.PP\n.RS\n\n.nf\n"
codeCloseTag = "\n.fi\n.RE\n"
quoteTag = "\n.PP\n.RS\n"
quoteCloseTag = "\n.RE\n"
listTag = "\n.RS\n"
listCloseTag = "\n.RE\n"
arglistTag = "\n.TP\n"
tableStart = "\n.TS\nallbox;\n"
tableEnd = ".TE\n"
tableCellStart = "T{\n"
tableCellEnd = "\nT}\n"
)
// NewRoffRenderer creates a new blackfriday Renderer for generating roff documents
// from markdown
func NewRoffRenderer() *roffRenderer { // nolint: golint
var extensions blackfriday.Extensions
extensions |= blackfriday.NoIntraEmphasis
extensions |= blackfriday.Tables
extensions |= blackfriday.FencedCode
extensions |= blackfriday.SpaceHeadings
extensions |= blackfriday.Footnotes
extensions |= blackfriday.Titleblock
extensions |= blackfriday.DefinitionLists
return &roffRenderer{
extensions: extensions,
}
}
// GetExtensions returns the list of extensions used by this renderer implementation
func (r *roffRenderer) GetExtensions() blackfriday.Extensions {
return r.extensions
}
// RenderHeader handles outputting the header at document start
func (r *roffRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) {
// disable hyphenation
out(w, ".nh\n")
}
// RenderFooter handles outputting the footer at the document end; the roff
// renderer has no footer information
func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) {
}
// RenderNode is called for each node in a markdown document; based on the node
// type the equivalent roff output is sent to the writer
func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
var walkAction = blackfriday.GoToNext
switch node.Type {
case blackfriday.Text:
r.handleText(w, node, entering)
case blackfriday.Softbreak:
out(w, crTag)
case blackfriday.Hardbreak:
out(w, breakTag)
case blackfriday.Emph:
if entering {
out(w, emphTag)
} else {
out(w, emphCloseTag)
}
case blackfriday.Strong:
if entering {
out(w, strongTag)
} else {
out(w, strongCloseTag)
}
case blackfriday.Link:
if !entering {
out(w, linkTag+string(node.LinkData.Destination)+linkCloseTag)
}
case blackfriday.Image:
// ignore images
walkAction = blackfriday.SkipChildren
case blackfriday.Code:
out(w, codespanTag)
escapeSpecialChars(w, node.Literal)
out(w, codespanCloseTag)
case blackfriday.Document:
break
case blackfriday.Paragraph:
// roff .PP markers break lists
if r.listDepth > 0 {
return blackfriday.GoToNext
}
if entering {
out(w, paraTag)
} else {
out(w, crTag)
}
case blackfriday.BlockQuote:
if entering {
out(w, quoteTag)
} else {
out(w, quoteCloseTag)
}
case blackfriday.Heading:
r.handleHeading(w, node, entering)
case blackfriday.HorizontalRule:
out(w, hruleTag)
case blackfriday.List:
r.handleList(w, node, entering)
case blackfriday.Item:
r.handleItem(w, node, entering)
case blackfriday.CodeBlock:
out(w, codeTag)
escapeSpecialChars(w, node.Literal)
out(w, codeCloseTag)
case blackfriday.Table:
r.handleTable(w, node, entering)
case blackfriday.TableCell:
r.handleTableCell(w, node, entering)
case blackfriday.TableHead:
case blackfriday.TableBody:
case blackfriday.TableRow:
// no action as cell entries do all the nroff formatting
return blackfriday.GoToNext
default:
fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String())
}
return walkAction
}
func (r *roffRenderer) handleText(w io.Writer, node *blackfriday.Node, entering bool) {
var (
start, end string
)
// handle special roff table cell text encapsulation
if node.Parent.Type == blackfriday.TableCell {
if len(node.Literal) > 30 {
start = tableCellStart
end = tableCellEnd
} else {
// end rows that aren't terminated by "tableCellEnd" with a cr if end of row
if node.Parent.Next == nil && !node.Parent.IsHeader {
end = crTag
}
}
}
out(w, start)
escapeSpecialChars(w, node.Literal)
out(w, end)
}
func (r *roffRenderer) handleHeading(w io.Writer, node *blackfriday.Node, entering bool) {
if entering {
switch node.Level {
case 1:
if !r.firstHeader {
out(w, titleHeader)
r.firstHeader = true
break
}
out(w, topLevelHeader)
case 2:
out(w, secondLevelHdr)
default:
out(w, otherHeader)
}
}
}
func (r *roffRenderer) handleList(w io.Writer, node *blackfriday.Node, entering bool) {
openTag := listTag
closeTag := listCloseTag
if node.ListFlags&blackfriday.ListTypeDefinition != 0 {
// tags for definition lists handled within Item node
openTag = ""
closeTag = ""
}
if entering {
r.listDepth++
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
r.listCounters = append(r.listCounters, 1)
}
out(w, openTag)
} else {
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
r.listCounters = r.listCounters[:len(r.listCounters)-1]
}
out(w, closeTag)
r.listDepth--
}
}
func (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering bool) {
if entering {
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
out(w, fmt.Sprintf(".IP \"%3d.\" 5\n", r.listCounters[len(r.listCounters)-1]))
r.listCounters[len(r.listCounters)-1]++
} else if node.ListFlags&blackfriday.ListTypeDefinition != 0 {
// state machine for handling terms and following definitions
// since blackfriday does not distinguish them properly, nor
// does it seperate them into separate lists as it should
if !r.defineTerm {
out(w, arglistTag)
r.defineTerm = true
} else {
r.defineTerm = false
}
} else {
out(w, ".IP \\(bu 2\n")
}
} else {
out(w, "\n")
}
}
func (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering bool) {
if entering {
out(w, tableStart)
//call walker to count cells (and rows?) so format section can be produced
columns := countColumns(node)
out(w, strings.Repeat("l ", columns)+"\n")
out(w, strings.Repeat("l ", columns)+".\n")
} else {
out(w, tableEnd)
}
}
func (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, entering bool) {
var (
start, end string
)
if node.IsHeader {
start = codespanTag
end = codespanCloseTag
}
if entering {
if node.Prev != nil && node.Prev.Type == blackfriday.TableCell {
out(w, "\t"+start)
} else {
out(w, start)
}
} else {
// need to carriage return if we are at the end of the header row
if node.IsHeader && node.Next == nil {
end = end + crTag
}
out(w, end)
}
}
// because roff format requires knowing the column count before outputting any table
// data we need to walk a table tree and count the columns
func countColumns(node *blackfriday.Node) int {
var columns int
node.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
switch node.Type {
case blackfriday.TableRow:
if !entering {
return blackfriday.Terminate
}
case blackfriday.TableCell:
if entering {
columns++
}
default:
}
return blackfriday.GoToNext
})
return columns
}
func out(w io.Writer, output string) {
io.WriteString(w, output) // nolint: errcheck
}
func needsBackslash(c byte) bool {
for _, r := range []byte("-_&\\~") {
if c == r {
return true
}
}
return false
}
func escapeSpecialChars(w io.Writer, text []byte) {
for i := 0; i < len(text); i++ {
// escape initial apostrophe or period
if len(text) >= 1 && (text[0] == '\'' || text[0] == '.') {
out(w, "\\&")
}
// directly copy normal characters
org := i
for i < len(text) && !needsBackslash(text[i]) {
i++
}
if i > org {
w.Write(text[org:i]) // nolint: errcheck
}
// escape a character
if i >= len(text) {
break
}
w.Write([]byte{'\\', text[i]}) // nolint: errcheck
}
}

View file

@ -49,6 +49,10 @@ const (
func (u *LaunchResultBase) UnmarshalJSON(body []byte) error { func (u *LaunchResultBase) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// AsyncJobId : This response indicates that the processing is
// asynchronous. The string is an id that can be used to obtain the
// status of the asynchronous job.
AsyncJobId string `json:"async_job_id,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -58,7 +62,7 @@ func (u *LaunchResultBase) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "async_job_id": case "async_job_id":
err = json.Unmarshal(body, &u.AsyncJobId) u.AsyncJobId = w.AsyncJobId
if err != nil { if err != nil {
return err return err
@ -88,6 +92,10 @@ const (
func (u *LaunchEmptyResult) UnmarshalJSON(body []byte) error { func (u *LaunchEmptyResult) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// AsyncJobId : This response indicates that the processing is
// asynchronous. The string is an id that can be used to obtain the
// status of the asynchronous job.
AsyncJobId string `json:"async_job_id,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -97,7 +105,7 @@ func (u *LaunchEmptyResult) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "async_job_id": case "async_job_id":
err = json.Unmarshal(body, &u.AsyncJobId) u.AsyncJobId = w.AsyncJobId
if err != nil { if err != nil {
return err return err

View file

@ -49,9 +49,9 @@ func (u *AccessError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// InvalidAccountType : Current account type cannot access the resource. // InvalidAccountType : Current account type cannot access the resource.
InvalidAccountType json.RawMessage `json:"invalid_account_type,omitempty"` InvalidAccountType *InvalidAccountTypeError `json:"invalid_account_type,omitempty"`
// PaperAccessDenied : Current account cannot access Paper. // PaperAccessDenied : Current account cannot access Paper.
PaperAccessDenied json.RawMessage `json:"paper_access_denied,omitempty"` PaperAccessDenied *PaperAccessError `json:"paper_access_denied,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -61,13 +61,13 @@ func (u *AccessError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "invalid_account_type": case "invalid_account_type":
err = json.Unmarshal(w.InvalidAccountType, &u.InvalidAccountType) u.InvalidAccountType = w.InvalidAccountType
if err != nil { if err != nil {
return err return err
} }
case "paper_access_denied": case "paper_access_denied":
err = json.Unmarshal(w.PaperAccessDenied, &u.PaperAccessDenied) u.PaperAccessDenied = w.PaperAccessDenied
if err != nil { if err != nil {
return err return err
@ -79,6 +79,9 @@ func (u *AccessError) UnmarshalJSON(body []byte) error {
// AuthError : Errors occurred during authentication. // AuthError : Errors occurred during authentication.
type AuthError struct { type AuthError struct {
dropbox.Tagged dropbox.Tagged
// MissingScope : The access token does not have the required scope to
// access the route.
MissingScope *TokenScopeError `json:"missing_scope,omitempty"`
} }
// Valid tag values for AuthError // Valid tag values for AuthError
@ -88,9 +91,32 @@ const (
AuthErrorInvalidSelectAdmin = "invalid_select_admin" AuthErrorInvalidSelectAdmin = "invalid_select_admin"
AuthErrorUserSuspended = "user_suspended" AuthErrorUserSuspended = "user_suspended"
AuthErrorExpiredAccessToken = "expired_access_token" AuthErrorExpiredAccessToken = "expired_access_token"
AuthErrorMissingScope = "missing_scope"
AuthErrorOther = "other" AuthErrorOther = "other"
) )
// UnmarshalJSON deserializes into a AuthError instance
func (u *AuthError) UnmarshalJSON(body []byte) error {
type wrap struct {
dropbox.Tagged
}
var w wrap
var err error
if err = json.Unmarshal(body, &w); err != nil {
return err
}
u.Tag = w.Tag
switch u.Tag {
case "missing_scope":
err = json.Unmarshal(body, &u.MissingScope)
if err != nil {
return err
}
}
return nil
}
// InvalidAccountTypeError : has no documentation (yet) // InvalidAccountTypeError : has no documentation (yet)
type InvalidAccountTypeError struct { type InvalidAccountTypeError struct {
dropbox.Tagged dropbox.Tagged
@ -186,3 +212,16 @@ func NewTokenFromOAuth1Result(Oauth2Token string) *TokenFromOAuth1Result {
s.Oauth2Token = Oauth2Token s.Oauth2Token = Oauth2Token
return s return s
} }
// TokenScopeError : has no documentation (yet)
type TokenScopeError struct {
// RequiredScope : The required scope to access the route.
RequiredScope string `json:"required_scope"`
}
// NewTokenScopeError returns a new TokenScopeError instance
func NewTokenScopeError(RequiredScope string) *TokenScopeError {
s := new(TokenScopeError)
s.RequiredScope = RequiredScope
return s
}

View file

@ -52,6 +52,14 @@ const (
func (u *PathRoot) UnmarshalJSON(body []byte) error { func (u *PathRoot) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// Root : Paths are relative to the authenticating user's root namespace
// (This results in `PathRootError.invalid_root` if the user's root
// namespace has changed.).
Root string `json:"root,omitempty"`
// NamespaceId : Paths are relative to given namespace id (This results
// in `PathRootError.no_permission` if you don't have access to this
// namespace.).
NamespaceId string `json:"namespace_id,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -61,13 +69,13 @@ func (u *PathRoot) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "root": case "root":
err = json.Unmarshal(body, &u.Root) u.Root = w.Root
if err != nil { if err != nil {
return err return err
} }
case "namespace_id": case "namespace_id":
err = json.Unmarshal(body, &u.NamespaceId) u.NamespaceId = w.NamespaceId
if err != nil { if err != nil {
return err return err
@ -107,7 +115,7 @@ func (u *PathRootError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "invalid_root": case "invalid_root":
u.InvalidRoot, err = IsRootInfoFromJSON(body) u.InvalidRoot, err = IsRootInfoFromJSON(w.InvalidRoot)
if err != nil { if err != nil {
return err return err
@ -161,10 +169,6 @@ const (
func (u *rootInfoUnion) UnmarshalJSON(body []byte) error { func (u *rootInfoUnion) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// Team : has no documentation (yet)
Team json.RawMessage `json:"team,omitempty"`
// User : has no documentation (yet)
User json.RawMessage `json:"user,omitempty"`
} }
var w wrap var w wrap
var err error var err error

View file

@ -86,6 +86,8 @@ const (
func (u *TemplateError) UnmarshalJSON(body []byte) error { func (u *TemplateError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// TemplateNotFound : Template does not exist for the given identifier.
TemplateNotFound string `json:"template_not_found,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -95,7 +97,7 @@ func (u *TemplateError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "template_not_found": case "template_not_found":
err = json.Unmarshal(body, &u.TemplateNotFound) u.TemplateNotFound = w.TemplateNotFound
if err != nil { if err != nil {
return err return err
@ -126,8 +128,10 @@ const (
func (u *PropertiesError) UnmarshalJSON(body []byte) error { func (u *PropertiesError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// TemplateNotFound : Template does not exist for the given identifier.
TemplateNotFound string `json:"template_not_found,omitempty"`
// Path : has no documentation (yet) // Path : has no documentation (yet)
Path json.RawMessage `json:"path,omitempty"` Path *LookupError `json:"path,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -137,13 +141,13 @@ func (u *PropertiesError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "template_not_found": case "template_not_found":
err = json.Unmarshal(body, &u.TemplateNotFound) u.TemplateNotFound = w.TemplateNotFound
if err != nil { if err != nil {
return err return err
} }
case "path": case "path":
err = json.Unmarshal(w.Path, &u.Path) u.Path = w.Path
if err != nil { if err != nil {
return err return err
@ -176,8 +180,10 @@ const (
func (u *InvalidPropertyGroupError) UnmarshalJSON(body []byte) error { func (u *InvalidPropertyGroupError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// TemplateNotFound : Template does not exist for the given identifier.
TemplateNotFound string `json:"template_not_found,omitempty"`
// Path : has no documentation (yet) // Path : has no documentation (yet)
Path json.RawMessage `json:"path,omitempty"` Path *LookupError `json:"path,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -187,13 +193,13 @@ func (u *InvalidPropertyGroupError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "template_not_found": case "template_not_found":
err = json.Unmarshal(body, &u.TemplateNotFound) u.TemplateNotFound = w.TemplateNotFound
if err != nil { if err != nil {
return err return err
} }
case "path": case "path":
err = json.Unmarshal(w.Path, &u.Path) u.Path = w.Path
if err != nil { if err != nil {
return err return err
@ -227,8 +233,10 @@ const (
func (u *AddPropertiesError) UnmarshalJSON(body []byte) error { func (u *AddPropertiesError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// TemplateNotFound : Template does not exist for the given identifier.
TemplateNotFound string `json:"template_not_found,omitempty"`
// Path : has no documentation (yet) // Path : has no documentation (yet)
Path json.RawMessage `json:"path,omitempty"` Path *LookupError `json:"path,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -238,13 +246,13 @@ func (u *AddPropertiesError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "template_not_found": case "template_not_found":
err = json.Unmarshal(body, &u.TemplateNotFound) u.TemplateNotFound = w.TemplateNotFound
if err != nil { if err != nil {
return err return err
} }
case "path": case "path":
err = json.Unmarshal(w.Path, &u.Path) u.Path = w.Path
if err != nil { if err != nil {
return err return err
@ -388,6 +396,8 @@ const (
func (u *LookupError) UnmarshalJSON(body []byte) error { func (u *LookupError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// MalformedPath : has no documentation (yet)
MalformedPath string `json:"malformed_path,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -397,7 +407,7 @@ func (u *LookupError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "malformed_path": case "malformed_path":
err = json.Unmarshal(body, &u.MalformedPath) u.MalformedPath = w.MalformedPath
if err != nil { if err != nil {
return err return err
@ -428,6 +438,8 @@ const (
func (u *ModifyTemplateError) UnmarshalJSON(body []byte) error { func (u *ModifyTemplateError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// TemplateNotFound : Template does not exist for the given identifier.
TemplateNotFound string `json:"template_not_found,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -437,7 +449,7 @@ func (u *ModifyTemplateError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "template_not_found": case "template_not_found":
err = json.Unmarshal(body, &u.TemplateNotFound) u.TemplateNotFound = w.TemplateNotFound
if err != nil { if err != nil {
return err return err
@ -522,7 +534,7 @@ func (u *PropertiesSearchError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// PropertyGroupLookup : has no documentation (yet) // PropertyGroupLookup : has no documentation (yet)
PropertyGroupLookup json.RawMessage `json:"property_group_lookup,omitempty"` PropertyGroupLookup *LookUpPropertiesError `json:"property_group_lookup,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -532,7 +544,7 @@ func (u *PropertiesSearchError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "property_group_lookup": case "property_group_lookup":
err = json.Unmarshal(w.PropertyGroupLookup, &u.PropertyGroupLookup) u.PropertyGroupLookup = w.PropertyGroupLookup
if err != nil { if err != nil {
return err return err
@ -580,6 +592,8 @@ const (
func (u *PropertiesSearchMode) UnmarshalJSON(body []byte) error { func (u *PropertiesSearchMode) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// FieldName : Search for a value associated with this field name.
FieldName string `json:"field_name,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -589,7 +603,7 @@ func (u *PropertiesSearchMode) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "field_name": case "field_name":
err = json.Unmarshal(body, &u.FieldName) u.FieldName = w.FieldName
if err != nil { if err != nil {
return err return err
@ -768,10 +782,12 @@ const (
func (u *RemovePropertiesError) UnmarshalJSON(body []byte) error { func (u *RemovePropertiesError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// TemplateNotFound : Template does not exist for the given identifier.
TemplateNotFound string `json:"template_not_found,omitempty"`
// Path : has no documentation (yet) // Path : has no documentation (yet)
Path json.RawMessage `json:"path,omitempty"` Path *LookupError `json:"path,omitempty"`
// PropertyGroupLookup : has no documentation (yet) // PropertyGroupLookup : has no documentation (yet)
PropertyGroupLookup json.RawMessage `json:"property_group_lookup,omitempty"` PropertyGroupLookup *LookUpPropertiesError `json:"property_group_lookup,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -781,19 +797,19 @@ func (u *RemovePropertiesError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "template_not_found": case "template_not_found":
err = json.Unmarshal(body, &u.TemplateNotFound) u.TemplateNotFound = w.TemplateNotFound
if err != nil { if err != nil {
return err return err
} }
case "path": case "path":
err = json.Unmarshal(w.Path, &u.Path) u.Path = w.Path
if err != nil { if err != nil {
return err return err
} }
case "property_group_lookup": case "property_group_lookup":
err = json.Unmarshal(w.PropertyGroupLookup, &u.PropertyGroupLookup) u.PropertyGroupLookup = w.PropertyGroupLookup
if err != nil { if err != nil {
return err return err
@ -836,7 +852,7 @@ func (u *TemplateFilterBase) UnmarshalJSON(body []byte) error {
dropbox.Tagged dropbox.Tagged
// FilterSome : Only templates with an ID in the supplied list will be // FilterSome : Only templates with an ID in the supplied list will be
// returned (a subset of templates will be returned). // returned (a subset of templates will be returned).
FilterSome json.RawMessage `json:"filter_some,omitempty"` FilterSome []string `json:"filter_some,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -846,7 +862,7 @@ func (u *TemplateFilterBase) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "filter_some": case "filter_some":
err = json.Unmarshal(body, &u.FilterSome) u.FilterSome = w.FilterSome
if err != nil { if err != nil {
return err return err
@ -876,7 +892,7 @@ func (u *TemplateFilter) UnmarshalJSON(body []byte) error {
dropbox.Tagged dropbox.Tagged
// FilterSome : Only templates with an ID in the supplied list will be // FilterSome : Only templates with an ID in the supplied list will be
// returned (a subset of templates will be returned). // returned (a subset of templates will be returned).
FilterSome json.RawMessage `json:"filter_some,omitempty"` FilterSome []string `json:"filter_some,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -886,7 +902,7 @@ func (u *TemplateFilter) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "filter_some": case "filter_some":
err = json.Unmarshal(body, &u.FilterSome) u.FilterSome = w.FilterSome
if err != nil { if err != nil {
return err return err
@ -950,10 +966,12 @@ const (
func (u *UpdatePropertiesError) UnmarshalJSON(body []byte) error { func (u *UpdatePropertiesError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// TemplateNotFound : Template does not exist for the given identifier.
TemplateNotFound string `json:"template_not_found,omitempty"`
// Path : has no documentation (yet) // Path : has no documentation (yet)
Path json.RawMessage `json:"path,omitempty"` Path *LookupError `json:"path,omitempty"`
// PropertyGroupLookup : has no documentation (yet) // PropertyGroupLookup : has no documentation (yet)
PropertyGroupLookup json.RawMessage `json:"property_group_lookup,omitempty"` PropertyGroupLookup *LookUpPropertiesError `json:"property_group_lookup,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -963,19 +981,19 @@ func (u *UpdatePropertiesError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "template_not_found": case "template_not_found":
err = json.Unmarshal(body, &u.TemplateNotFound) u.TemplateNotFound = w.TemplateNotFound
if err != nil { if err != nil {
return err return err
} }
case "path": case "path":
err = json.Unmarshal(w.Path, &u.Path) u.Path = w.Path
if err != nil { if err != nil {
return err return err
} }
case "property_group_lookup": case "property_group_lookup":
err = json.Unmarshal(w.PropertyGroupLookup, &u.PropertyGroupLookup) u.PropertyGroupLookup = w.PropertyGroupLookup
if err != nil { if err != nil {
return err return err

View file

@ -57,7 +57,7 @@ type Client interface {
Copy(arg *RelocationArg) (res IsMetadata, err error) Copy(arg *RelocationArg) (res IsMetadata, err error)
// CopyBatch : Copy multiple files or folders to different locations at once // CopyBatch : Copy multiple files or folders to different locations at once
// in the user's Dropbox. This route will replace `copyBatch`. The main // in the user's Dropbox. This route will replace `copyBatch`. The main
// difference is this route will return stutus for each entry, while // difference is this route will return status for each entry, while
// `copyBatch` raises failure if any entry fails. This route will either // `copyBatch` raises failure if any entry fails. This route will either
// finish synchronously, or return a job ID and do the async copy job in // finish synchronously, or return a job ID and do the async copy job in
// background. Please use `copyBatchCheck` to check the job status. // background. Please use `copyBatchCheck` to check the job status.
@ -130,19 +130,23 @@ type Client interface {
// total files. The input cannot be a single file. Any single file must be // total files. The input cannot be a single file. Any single file must be
// less than 4GB in size. // less than 4GB in size.
DownloadZip(arg *DownloadZipArg) (res *DownloadZipResult, content io.ReadCloser, err error) DownloadZip(arg *DownloadZipArg) (res *DownloadZipResult, content io.ReadCloser, err error)
// Export : Export a file from a user's Dropbox. This route only supports
// exporting files that cannot be downloaded directly and whose
// `ExportResult.file_metadata` has `ExportInfo.export_as` populated.
Export(arg *ExportArg) (res *ExportResult, content io.ReadCloser, err error)
// GetMetadata : Returns the metadata for a file or folder. Note: Metadata // GetMetadata : Returns the metadata for a file or folder. Note: Metadata
// for the root folder is unsupported. // for the root folder is unsupported.
GetMetadata(arg *GetMetadataArg) (res IsMetadata, err error) GetMetadata(arg *GetMetadataArg) (res IsMetadata, err error)
// GetPreview : Get a preview for a file. Currently, PDF previews are // GetPreview : Get a preview for a file. Currently, PDF previews are
// generated for files with the following extensions: .ai, .doc, .docm, // generated for files with the following extensions: .ai, .doc, .docm,
// .docx, .eps, .odp, .odt, .pps, .ppsm, .ppsx, .ppt, .pptm, .pptx, .rtf. // .docx, .eps, .gdoc, .gslides, .odp, .odt, .pps, .ppsm, .ppsx, .ppt,
// HTML previews are generated for files with the following extensions: // .pptm, .pptx, .rtf. HTML previews are generated for files with the
// .csv, .ods, .xls, .xlsm, .xlsx. Other formats will return an unsupported // following extensions: .csv, .ods, .xls, .xlsm, .gsheet, .xlsx. Other
// extension error. // formats will return an unsupported extension error.
GetPreview(arg *PreviewArg) (res *FileMetadata, content io.ReadCloser, err error) GetPreview(arg *PreviewArg) (res *FileMetadata, content io.ReadCloser, err error)
// GetTemporaryLink : Get a temporary link to stream content of a file. This // GetTemporaryLink : Get a temporary link to stream content of a file. This
// link will expire in four hours and afterwards you will get 410 Gone. So // link will expire in four hours and afterwards you will get 410 Gone. This
// this URL should not be used to display content directly in the browser. // URL should not be used to display content directly in the browser. The
// Content-Type of the link is determined automatically by the file's mime // Content-Type of the link is determined automatically by the file's mime
// type. // type.
GetTemporaryLink(arg *GetTemporaryLinkArg) (res *GetTemporaryLinkResult, err error) GetTemporaryLink(arg *GetTemporaryLinkArg) (res *GetTemporaryLinkResult, err error)
@ -246,7 +250,7 @@ type Client interface {
Move(arg *RelocationArg) (res IsMetadata, err error) Move(arg *RelocationArg) (res IsMetadata, err error)
// MoveBatch : Move multiple files or folders to different locations at once // MoveBatch : Move multiple files or folders to different locations at once
// in the user's Dropbox. This route will replace `moveBatch`. The main // in the user's Dropbox. This route will replace `moveBatch`. The main
// difference is this route will return stutus for each entry, while // difference is this route will return status for each entry, while
// `moveBatch` raises failure if any entry fails. This route will either // `moveBatch` raises failure if any entry fails. This route will either
// finish synchronously, or return a job ID and do the async move job in // finish synchronously, or return a job ID and do the async move job in
// background. Please use `moveBatchCheck` to check the job status. // background. Please use `moveBatchCheck` to check the job status.
@ -477,7 +481,7 @@ func (dbx *apiImpl) AlphaUpload(arg *CommitInfoWithProperties, content io.Reader
headers := map[string]string{ headers := map[string]string{
"Content-Type": "application/octet-stream", "Content-Type": "application/octet-stream",
"Dropbox-API-Arg": string(b), "Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
} }
if dbx.Config.AsMemberID != "" { if dbx.Config.AsMemberID != "" {
headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID
@ -1636,7 +1640,7 @@ func (dbx *apiImpl) Download(arg *DownloadArg) (res *FileMetadata, content io.Re
} }
headers := map[string]string{ headers := map[string]string{
"Dropbox-API-Arg": string(b), "Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
} }
for k, v := range arg.ExtraHeaders { for k, v := range arg.ExtraHeaders {
headers[k] = v headers[k] = v
@ -1706,7 +1710,7 @@ func (dbx *apiImpl) DownloadZip(arg *DownloadZipArg) (res *DownloadZipResult, co
} }
headers := map[string]string{ headers := map[string]string{
"Dropbox-API-Arg": string(b), "Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
} }
if dbx.Config.AsMemberID != "" { if dbx.Config.AsMemberID != "" {
headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID
@ -1757,6 +1761,73 @@ func (dbx *apiImpl) DownloadZip(arg *DownloadZipArg) (res *DownloadZipResult, co
return return
} }
//ExportAPIError is an error-wrapper for the export route
type ExportAPIError struct {
dropbox.APIError
EndpointError *ExportError `json:"error"`
}
func (dbx *apiImpl) Export(arg *ExportArg) (res *ExportResult, content io.ReadCloser, err error) {
cli := dbx.Client
dbx.Config.LogDebug("arg: %v", arg)
b, err := json.Marshal(arg)
if err != nil {
return
}
headers := map[string]string{
"Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
}
if dbx.Config.AsMemberID != "" {
headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID
}
req, err := (*dropbox.Context)(dbx).NewRequest("content", "download", true, "files", "export", headers, nil)
if err != nil {
return
}
dbx.Config.LogInfo("req: %v", req)
resp, err := cli.Do(req)
if err != nil {
return
}
dbx.Config.LogInfo("resp: %v", resp)
body := []byte(resp.Header.Get("Dropbox-API-Result"))
content = resp.Body
dbx.Config.LogDebug("body: %s", body)
if resp.StatusCode == http.StatusOK {
err = json.Unmarshal(body, &res)
if err != nil {
return
}
return
}
if resp.StatusCode == http.StatusConflict {
defer resp.Body.Close()
body, err = ioutil.ReadAll(resp.Body)
if err != nil {
return
}
var apiError ExportAPIError
err = json.Unmarshal(body, &apiError)
if err != nil {
return
}
err = apiError
return
}
err = auth.HandleCommonAuthErrors(dbx.Config, resp, body)
if err != nil {
return
}
err = dropbox.HandleCommonAPIErrors(dbx.Config, resp, body)
return
}
//GetMetadataAPIError is an error-wrapper for the get_metadata route //GetMetadataAPIError is an error-wrapper for the get_metadata route
type GetMetadataAPIError struct { type GetMetadataAPIError struct {
dropbox.APIError dropbox.APIError
@ -1850,7 +1921,7 @@ func (dbx *apiImpl) GetPreview(arg *PreviewArg) (res *FileMetadata, content io.R
} }
headers := map[string]string{ headers := map[string]string{
"Dropbox-API-Arg": string(b), "Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
} }
if dbx.Config.AsMemberID != "" { if dbx.Config.AsMemberID != "" {
headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID
@ -2049,7 +2120,7 @@ func (dbx *apiImpl) GetThumbnail(arg *ThumbnailArg) (res *FileMetadata, content
} }
headers := map[string]string{ headers := map[string]string{
"Dropbox-API-Arg": string(b), "Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
} }
if dbx.Config.AsMemberID != "" { if dbx.Config.AsMemberID != "" {
headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID
@ -2116,7 +2187,7 @@ func (dbx *apiImpl) GetThumbnailBatch(arg *GetThumbnailBatchArg) (res *GetThumbn
} }
headers := map[string]string{ headers := map[string]string{
"Dropbox-API-Arg": string(b), "Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
} }
if dbx.Config.AsMemberID != "" { if dbx.Config.AsMemberID != "" {
headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID
@ -3625,7 +3696,7 @@ func (dbx *apiImpl) Upload(arg *CommitInfo, content io.Reader) (res *FileMetadat
headers := map[string]string{ headers := map[string]string{
"Content-Type": "application/octet-stream", "Content-Type": "application/octet-stream",
"Dropbox-API-Arg": string(b), "Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
} }
if dbx.Config.AsMemberID != "" { if dbx.Config.AsMemberID != "" {
headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID
@ -3692,7 +3763,7 @@ func (dbx *apiImpl) UploadSessionAppendV2(arg *UploadSessionAppendArg, content i
headers := map[string]string{ headers := map[string]string{
"Content-Type": "application/octet-stream", "Content-Type": "application/octet-stream",
"Dropbox-API-Arg": string(b), "Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
} }
if dbx.Config.AsMemberID != "" { if dbx.Config.AsMemberID != "" {
headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID
@ -3757,7 +3828,7 @@ func (dbx *apiImpl) UploadSessionAppend(arg *UploadSessionCursor, content io.Rea
headers := map[string]string{ headers := map[string]string{
"Content-Type": "application/octet-stream", "Content-Type": "application/octet-stream",
"Dropbox-API-Arg": string(b), "Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
} }
if dbx.Config.AsMemberID != "" { if dbx.Config.AsMemberID != "" {
headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID
@ -3819,7 +3890,7 @@ func (dbx *apiImpl) UploadSessionFinish(arg *UploadSessionFinishArg, content io.
headers := map[string]string{ headers := map[string]string{
"Content-Type": "application/octet-stream", "Content-Type": "application/octet-stream",
"Dropbox-API-Arg": string(b), "Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
} }
if dbx.Config.AsMemberID != "" { if dbx.Config.AsMemberID != "" {
headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID
@ -4018,7 +4089,7 @@ func (dbx *apiImpl) UploadSessionStart(arg *UploadSessionStartArg, content io.Re
headers := map[string]string{ headers := map[string]string{
"Content-Type": "application/octet-stream", "Content-Type": "application/octet-stream",
"Dropbox-API-Arg": string(b), "Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
} }
if dbx.Config.AsMemberID != "" { if dbx.Config.AsMemberID != "" {
headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID

File diff suppressed because it is too large Load diff

View file

@ -21,6 +21,7 @@
package dropbox package dropbox
import ( import (
"bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -37,8 +38,8 @@ const (
hostAPI = "api" hostAPI = "api"
hostContent = "content" hostContent = "content"
hostNotify = "notify" hostNotify = "notify"
sdkVersion = "5.4.0" sdkVersion = "5.6.0"
specVersion = "097e9ba" specVersion = "0e697d7"
) )
// Version returns the current SDK version and API Spec version // Version returns the current SDK version and API Spec version
@ -221,3 +222,20 @@ func HandleCommonAPIErrors(c Config, resp *http.Response, body []byte) error {
} }
return apiError return apiError
} }
// HTTPHeaderSafeJSON encode the JSON passed in b []byte passed in in
// a way that is suitable for HTTP headers.
//
// See: https://www.dropbox.com/developers/reference/json-encoding
func HTTPHeaderSafeJSON(b []byte) string {
var s bytes.Buffer
s.Grow(len(b))
for _, r := range string(b) {
if r >= 0x007f {
fmt.Fprintf(&s, "\\u%04x", r)
} else {
s.WriteRune(r)
}
}
return s.String()
}

View file

@ -30,9 +30,12 @@ type PlatformType struct {
// Valid tag values for PlatformType // Valid tag values for PlatformType
const ( const (
PlatformTypeWeb = "web" PlatformTypeWeb = "web"
PlatformTypeMobile = "mobile" PlatformTypeDesktop = "desktop"
PlatformTypeDesktop = "desktop" PlatformTypeMobileIos = "mobile_ios"
PlatformTypeUnknown = "unknown" PlatformTypeMobileAndroid = "mobile_android"
PlatformTypeOther = "other" PlatformTypeApi = "api"
PlatformTypeUnknown = "unknown"
PlatformTypeMobile = "mobile"
PlatformTypeOther = "other"
) )

View file

@ -966,7 +966,7 @@ func (dbx *apiImpl) GetSharedLinkFile(arg *GetSharedLinkMetadataArg) (res IsShar
} }
headers := map[string]string{ headers := map[string]string{
"Dropbox-API-Arg": string(b), "Dropbox-API-Arg": dropbox.HTTPHeaderSafeJSON(b),
} }
if dbx.Config.AsMemberID != "" { if dbx.Config.AsMemberID != "" {
headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID headers["Dropbox-API-Select-User"] = dbx.Config.AsMemberID

File diff suppressed because it is too large Load diff

View file

@ -153,11 +153,11 @@ func (u *BaseTeamFolderError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// AccessError : has no documentation (yet) // AccessError : has no documentation (yet)
AccessError json.RawMessage `json:"access_error,omitempty"` AccessError *TeamFolderAccessError `json:"access_error,omitempty"`
// StatusError : has no documentation (yet) // StatusError : has no documentation (yet)
StatusError json.RawMessage `json:"status_error,omitempty"` StatusError *TeamFolderInvalidStatusError `json:"status_error,omitempty"`
// TeamSharedDropboxError : has no documentation (yet) // TeamSharedDropboxError : has no documentation (yet)
TeamSharedDropboxError json.RawMessage `json:"team_shared_dropbox_error,omitempty"` TeamSharedDropboxError *TeamFolderTeamSharedDropboxError `json:"team_shared_dropbox_error,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -167,19 +167,19 @@ func (u *BaseTeamFolderError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "access_error": case "access_error":
err = json.Unmarshal(w.AccessError, &u.AccessError) u.AccessError = w.AccessError
if err != nil { if err != nil {
return err return err
} }
case "status_error": case "status_error":
err = json.Unmarshal(w.StatusError, &u.StatusError) u.StatusError = w.StatusError
if err != nil { if err != nil {
return err return err
} }
case "team_shared_dropbox_error": case "team_shared_dropbox_error":
err = json.Unmarshal(w.TeamSharedDropboxError, &u.TeamSharedDropboxError) u.TeamSharedDropboxError = w.TeamSharedDropboxError
if err != nil { if err != nil {
return err return err
@ -219,10 +219,8 @@ const (
func (u *CustomQuotaResult) UnmarshalJSON(body []byte) error { func (u *CustomQuotaResult) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// Success : User's custom quota.
Success json.RawMessage `json:"success,omitempty"`
// InvalidUser : Invalid user (not in team). // InvalidUser : Invalid user (not in team).
InvalidUser json.RawMessage `json:"invalid_user,omitempty"` InvalidUser *UserSelectorArg `json:"invalid_user,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -238,7 +236,7 @@ func (u *CustomQuotaResult) UnmarshalJSON(body []byte) error {
return err return err
} }
case "invalid_user": case "invalid_user":
err = json.Unmarshal(w.InvalidUser, &u.InvalidUser) u.InvalidUser = w.InvalidUser
if err != nil { if err != nil {
return err return err
@ -540,13 +538,13 @@ func (u *FeatureValue) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// UploadApiRateLimit : has no documentation (yet) // UploadApiRateLimit : has no documentation (yet)
UploadApiRateLimit json.RawMessage `json:"upload_api_rate_limit,omitempty"` UploadApiRateLimit *UploadApiRateLimitValue `json:"upload_api_rate_limit,omitempty"`
// HasTeamSharedDropbox : has no documentation (yet) // HasTeamSharedDropbox : has no documentation (yet)
HasTeamSharedDropbox json.RawMessage `json:"has_team_shared_dropbox,omitempty"` HasTeamSharedDropbox *HasTeamSharedDropboxValue `json:"has_team_shared_dropbox,omitempty"`
// HasTeamFileEvents : has no documentation (yet) // HasTeamFileEvents : has no documentation (yet)
HasTeamFileEvents json.RawMessage `json:"has_team_file_events,omitempty"` HasTeamFileEvents *HasTeamFileEventsValue `json:"has_team_file_events,omitempty"`
// HasTeamSelectiveSync : has no documentation (yet) // HasTeamSelectiveSync : has no documentation (yet)
HasTeamSelectiveSync json.RawMessage `json:"has_team_selective_sync,omitempty"` HasTeamSelectiveSync *HasTeamSelectiveSyncValue `json:"has_team_selective_sync,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -556,25 +554,25 @@ func (u *FeatureValue) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "upload_api_rate_limit": case "upload_api_rate_limit":
err = json.Unmarshal(w.UploadApiRateLimit, &u.UploadApiRateLimit) u.UploadApiRateLimit = w.UploadApiRateLimit
if err != nil { if err != nil {
return err return err
} }
case "has_team_shared_dropbox": case "has_team_shared_dropbox":
err = json.Unmarshal(w.HasTeamSharedDropbox, &u.HasTeamSharedDropbox) u.HasTeamSharedDropbox = w.HasTeamSharedDropbox
if err != nil { if err != nil {
return err return err
} }
case "has_team_file_events": case "has_team_file_events":
err = json.Unmarshal(w.HasTeamFileEvents, &u.HasTeamFileEvents) u.HasTeamFileEvents = w.HasTeamFileEvents
if err != nil { if err != nil {
return err return err
} }
case "has_team_selective_sync": case "has_team_selective_sync":
err = json.Unmarshal(w.HasTeamSelectiveSync, &u.HasTeamSelectiveSync) u.HasTeamSelectiveSync = w.HasTeamSelectiveSync
if err != nil { if err != nil {
return err return err
@ -1010,12 +1008,12 @@ func (u *GroupMembersAddError) UnmarshalJSON(body []byte) error {
// Currently, you cannot add members to a group if they are not part of // Currently, you cannot add members to a group if they are not part of
// your team, though this may change in a subsequent version. To add new // your team, though this may change in a subsequent version. To add new
// members to your Dropbox Business team, use the `membersAdd` endpoint. // members to your Dropbox Business team, use the `membersAdd` endpoint.
MembersNotInTeam json.RawMessage `json:"members_not_in_team,omitempty"` MembersNotInTeam []string `json:"members_not_in_team,omitempty"`
// UsersNotFound : These users were not found in Dropbox. // UsersNotFound : These users were not found in Dropbox.
UsersNotFound json.RawMessage `json:"users_not_found,omitempty"` UsersNotFound []string `json:"users_not_found,omitempty"`
// UserCannotBeManagerOfCompanyManagedGroup : A company-managed group // UserCannotBeManagerOfCompanyManagedGroup : A company-managed group
// cannot be managed by a user. // cannot be managed by a user.
UserCannotBeManagerOfCompanyManagedGroup json.RawMessage `json:"user_cannot_be_manager_of_company_managed_group,omitempty"` UserCannotBeManagerOfCompanyManagedGroup []string `json:"user_cannot_be_manager_of_company_managed_group,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -1025,19 +1023,19 @@ func (u *GroupMembersAddError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "members_not_in_team": case "members_not_in_team":
err = json.Unmarshal(body, &u.MembersNotInTeam) u.MembersNotInTeam = w.MembersNotInTeam
if err != nil { if err != nil {
return err return err
} }
case "users_not_found": case "users_not_found":
err = json.Unmarshal(body, &u.UsersNotFound) u.UsersNotFound = w.UsersNotFound
if err != nil { if err != nil {
return err return err
} }
case "user_cannot_be_manager_of_company_managed_group": case "user_cannot_be_manager_of_company_managed_group":
err = json.Unmarshal(body, &u.UserCannotBeManagerOfCompanyManagedGroup) u.UserCannotBeManagerOfCompanyManagedGroup = w.UserCannotBeManagerOfCompanyManagedGroup
if err != nil { if err != nil {
return err return err
@ -1123,9 +1121,9 @@ func (u *GroupMembersRemoveError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// MembersNotInTeam : These members are not part of your team. // MembersNotInTeam : These members are not part of your team.
MembersNotInTeam json.RawMessage `json:"members_not_in_team,omitempty"` MembersNotInTeam []string `json:"members_not_in_team,omitempty"`
// UsersNotFound : These users were not found in Dropbox. // UsersNotFound : These users were not found in Dropbox.
UsersNotFound json.RawMessage `json:"users_not_found,omitempty"` UsersNotFound []string `json:"users_not_found,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -1135,13 +1133,13 @@ func (u *GroupMembersRemoveError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "members_not_in_team": case "members_not_in_team":
err = json.Unmarshal(body, &u.MembersNotInTeam) u.MembersNotInTeam = w.MembersNotInTeam
if err != nil { if err != nil {
return err return err
} }
case "users_not_found": case "users_not_found":
err = json.Unmarshal(body, &u.UsersNotFound) u.UsersNotFound = w.UsersNotFound
if err != nil { if err != nil {
return err return err
@ -1207,6 +1205,10 @@ const (
func (u *GroupSelector) UnmarshalJSON(body []byte) error { func (u *GroupSelector) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// GroupId : Group ID.
GroupId string `json:"group_id,omitempty"`
// GroupExternalId : External ID of the group.
GroupExternalId string `json:"group_external_id,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -1216,13 +1218,13 @@ func (u *GroupSelector) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "group_id": case "group_id":
err = json.Unmarshal(body, &u.GroupId) u.GroupId = w.GroupId
if err != nil { if err != nil {
return err return err
} }
case "group_external_id": case "group_external_id":
err = json.Unmarshal(body, &u.GroupExternalId) u.GroupExternalId = w.GroupExternalId
if err != nil { if err != nil {
return err return err
@ -1301,8 +1303,11 @@ const (
func (u *GroupsGetInfoItem) UnmarshalJSON(body []byte) error { func (u *GroupsGetInfoItem) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// GroupInfo : Info about a group. // IdNotFound : An ID that was provided as a parameter to
GroupInfo json.RawMessage `json:"group_info,omitempty"` // `groupsGetInfo`, and did not match a corresponding group. The ID can
// be a group ID, or an external ID, depending on how the method was
// called.
IdNotFound string `json:"id_not_found,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -1312,7 +1317,7 @@ func (u *GroupsGetInfoItem) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "id_not_found": case "id_not_found":
err = json.Unmarshal(body, &u.IdNotFound) u.IdNotFound = w.IdNotFound
if err != nil { if err != nil {
return err return err
@ -1482,9 +1487,9 @@ func (u *GroupsSelector) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// GroupIds : List of group IDs. // GroupIds : List of group IDs.
GroupIds json.RawMessage `json:"group_ids,omitempty"` GroupIds []string `json:"group_ids,omitempty"`
// GroupExternalIds : List of external IDs of groups. // GroupExternalIds : List of external IDs of groups.
GroupExternalIds json.RawMessage `json:"group_external_ids,omitempty"` GroupExternalIds []string `json:"group_external_ids,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -1494,13 +1499,13 @@ func (u *GroupsSelector) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "group_ids": case "group_ids":
err = json.Unmarshal(body, &u.GroupIds) u.GroupIds = w.GroupIds
if err != nil { if err != nil {
return err return err
} }
case "group_external_ids": case "group_external_ids":
err = json.Unmarshal(body, &u.GroupExternalIds) u.GroupExternalIds = w.GroupExternalIds
if err != nil { if err != nil {
return err return err
@ -1526,6 +1531,8 @@ const (
func (u *HasTeamFileEventsValue) UnmarshalJSON(body []byte) error { func (u *HasTeamFileEventsValue) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// Enabled : Does this team have file events.
Enabled bool `json:"enabled,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -1535,7 +1542,7 @@ func (u *HasTeamFileEventsValue) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "enabled": case "enabled":
err = json.Unmarshal(body, &u.Enabled) u.Enabled = w.Enabled
if err != nil { if err != nil {
return err return err
@ -1561,6 +1568,9 @@ const (
func (u *HasTeamSelectiveSyncValue) UnmarshalJSON(body []byte) error { func (u *HasTeamSelectiveSyncValue) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// HasTeamSelectiveSync : Does this team have team selective sync
// enabled.
HasTeamSelectiveSync bool `json:"has_team_selective_sync,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -1570,7 +1580,7 @@ func (u *HasTeamSelectiveSyncValue) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "has_team_selective_sync": case "has_team_selective_sync":
err = json.Unmarshal(body, &u.HasTeamSelectiveSync) u.HasTeamSelectiveSync = w.HasTeamSelectiveSync
if err != nil { if err != nil {
return err return err
@ -1596,6 +1606,8 @@ const (
func (u *HasTeamSharedDropboxValue) UnmarshalJSON(body []byte) error { func (u *HasTeamSharedDropboxValue) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// HasTeamSharedDropbox : Does this team have a shared team root.
HasTeamSharedDropbox bool `json:"has_team_shared_dropbox,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -1605,7 +1617,7 @@ func (u *HasTeamSharedDropboxValue) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "has_team_shared_dropbox": case "has_team_shared_dropbox":
err = json.Unmarshal(body, &u.HasTeamSharedDropbox) u.HasTeamSharedDropbox = w.HasTeamSharedDropbox
if err != nil { if err != nil {
return err return err
@ -2019,8 +2031,36 @@ const (
func (u *MemberAddResult) UnmarshalJSON(body []byte) error { func (u *MemberAddResult) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// Success : Describes a user that was successfully added to the team. // TeamLicenseLimit : Team is already full. The organization has no
Success json.RawMessage `json:"success,omitempty"` // available licenses.
TeamLicenseLimit string `json:"team_license_limit,omitempty"`
// FreeTeamMemberLimitReached : Team is already full. The free team
// member limit has been reached.
FreeTeamMemberLimitReached string `json:"free_team_member_limit_reached,omitempty"`
// UserAlreadyOnTeam : User is already on this team. The provided email
// address is associated with a user who is already a member of
// (including in recoverable state) or invited to the team.
UserAlreadyOnTeam string `json:"user_already_on_team,omitempty"`
// UserOnAnotherTeam : User is already on another team. The provided
// email address is associated with a user that is already a member or
// invited to another team.
UserOnAnotherTeam string `json:"user_on_another_team,omitempty"`
// UserAlreadyPaired : User is already paired.
UserAlreadyPaired string `json:"user_already_paired,omitempty"`
// UserMigrationFailed : User migration has failed.
UserMigrationFailed string `json:"user_migration_failed,omitempty"`
// DuplicateExternalMemberId : A user with the given external member ID
// already exists on the team (including in recoverable state).
DuplicateExternalMemberId string `json:"duplicate_external_member_id,omitempty"`
// DuplicateMemberPersistentId : A user with the given persistent ID
// already exists on the team (including in recoverable state).
DuplicateMemberPersistentId string `json:"duplicate_member_persistent_id,omitempty"`
// PersistentIdDisabled : Persistent ID is only available to teams with
// persistent ID SAML configuration. Please contact Dropbox for more
// information.
PersistentIdDisabled string `json:"persistent_id_disabled,omitempty"`
// UserCreationFailed : User creation has failed.
UserCreationFailed string `json:"user_creation_failed,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -2036,61 +2076,61 @@ func (u *MemberAddResult) UnmarshalJSON(body []byte) error {
return err return err
} }
case "team_license_limit": case "team_license_limit":
err = json.Unmarshal(body, &u.TeamLicenseLimit) u.TeamLicenseLimit = w.TeamLicenseLimit
if err != nil { if err != nil {
return err return err
} }
case "free_team_member_limit_reached": case "free_team_member_limit_reached":
err = json.Unmarshal(body, &u.FreeTeamMemberLimitReached) u.FreeTeamMemberLimitReached = w.FreeTeamMemberLimitReached
if err != nil { if err != nil {
return err return err
} }
case "user_already_on_team": case "user_already_on_team":
err = json.Unmarshal(body, &u.UserAlreadyOnTeam) u.UserAlreadyOnTeam = w.UserAlreadyOnTeam
if err != nil { if err != nil {
return err return err
} }
case "user_on_another_team": case "user_on_another_team":
err = json.Unmarshal(body, &u.UserOnAnotherTeam) u.UserOnAnotherTeam = w.UserOnAnotherTeam
if err != nil { if err != nil {
return err return err
} }
case "user_already_paired": case "user_already_paired":
err = json.Unmarshal(body, &u.UserAlreadyPaired) u.UserAlreadyPaired = w.UserAlreadyPaired
if err != nil { if err != nil {
return err return err
} }
case "user_migration_failed": case "user_migration_failed":
err = json.Unmarshal(body, &u.UserMigrationFailed) u.UserMigrationFailed = w.UserMigrationFailed
if err != nil { if err != nil {
return err return err
} }
case "duplicate_external_member_id": case "duplicate_external_member_id":
err = json.Unmarshal(body, &u.DuplicateExternalMemberId) u.DuplicateExternalMemberId = w.DuplicateExternalMemberId
if err != nil { if err != nil {
return err return err
} }
case "duplicate_member_persistent_id": case "duplicate_member_persistent_id":
err = json.Unmarshal(body, &u.DuplicateMemberPersistentId) u.DuplicateMemberPersistentId = w.DuplicateMemberPersistentId
if err != nil { if err != nil {
return err return err
} }
case "persistent_id_disabled": case "persistent_id_disabled":
err = json.Unmarshal(body, &u.PersistentIdDisabled) u.PersistentIdDisabled = w.PersistentIdDisabled
if err != nil { if err != nil {
return err return err
} }
case "user_creation_failed": case "user_creation_failed":
err = json.Unmarshal(body, &u.UserCreationFailed) u.UserCreationFailed = w.UserCreationFailed
if err != nil { if err != nil {
return err return err
@ -2160,11 +2200,17 @@ type MemberProfile struct {
// JoinedOn : The date and time the user joined as a member of a specific // JoinedOn : The date and time the user joined as a member of a specific
// team. // team.
JoinedOn time.Time `json:"joined_on,omitempty"` JoinedOn time.Time `json:"joined_on,omitempty"`
// SuspendedOn : The date and time the user was suspended from the team
// (contains value only when the member's status matches
// `TeamMemberStatus.suspended`.
SuspendedOn time.Time `json:"suspended_on,omitempty"`
// PersistentId : Persistent ID that a team can attach to the user. The // PersistentId : Persistent ID that a team can attach to the user. The
// persistent ID is unique ID to be used for SAML authentication. // persistent ID is unique ID to be used for SAML authentication.
PersistentId string `json:"persistent_id,omitempty"` PersistentId string `json:"persistent_id,omitempty"`
// IsDirectoryRestricted : Whether the user is a directory restricted user. // IsDirectoryRestricted : Whether the user is a directory restricted user.
IsDirectoryRestricted bool `json:"is_directory_restricted,omitempty"` IsDirectoryRestricted bool `json:"is_directory_restricted,omitempty"`
// ProfilePhotoUrl : URL for the photo representing the user, if one is set.
ProfilePhotoUrl string `json:"profile_photo_url,omitempty"`
} }
// NewMemberProfile returns a new MemberProfile instance // NewMemberProfile returns a new MemberProfile instance
@ -2243,7 +2289,10 @@ func (u *MembersAddJobStatus) UnmarshalJSON(body []byte) error {
// Complete : The asynchronous job has finished. For each member that // Complete : The asynchronous job has finished. For each member that
// was specified in the parameter `MembersAddArg` that was provided to // was specified in the parameter `MembersAddArg` that was provided to
// `membersAdd`, a corresponding item is returned in this list. // `membersAdd`, a corresponding item is returned in this list.
Complete []json.RawMessage `json:"complete,omitempty"` Complete []*MemberAddResult `json:"complete,omitempty"`
// Failed : The asynchronous job returned an error. The string contains
// an error message.
Failed string `json:"failed,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -2253,13 +2302,13 @@ func (u *MembersAddJobStatus) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "complete": case "complete":
err = json.Unmarshal(body, &u.Complete) u.Complete = w.Complete
if err != nil { if err != nil {
return err return err
} }
case "failed": case "failed":
err = json.Unmarshal(body, &u.Failed) u.Failed = w.Failed
if err != nil { if err != nil {
return err return err
@ -2289,8 +2338,12 @@ const (
func (u *MembersAddLaunch) UnmarshalJSON(body []byte) error { func (u *MembersAddLaunch) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// AsyncJobId : This response indicates that the processing is
// asynchronous. The string is an id that can be used to obtain the
// status of the asynchronous job.
AsyncJobId string `json:"async_job_id,omitempty"`
// Complete : has no documentation (yet) // Complete : has no documentation (yet)
Complete []json.RawMessage `json:"complete,omitempty"` Complete []*MemberAddResult `json:"complete,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -2300,13 +2353,13 @@ func (u *MembersAddLaunch) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "async_job_id": case "async_job_id":
err = json.Unmarshal(body, &u.AsyncJobId) u.AsyncJobId = w.AsyncJobId
if err != nil { if err != nil {
return err return err
} }
case "complete": case "complete":
err = json.Unmarshal(body, &u.Complete) u.Complete = w.Complete
if err != nil { if err != nil {
return err return err
@ -2422,8 +2475,11 @@ const (
func (u *MembersGetInfoItem) UnmarshalJSON(body []byte) error { func (u *MembersGetInfoItem) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// MemberInfo : Info about a team member. // IdNotFound : An ID that was provided as a parameter to
MemberInfo json.RawMessage `json:"member_info,omitempty"` // `membersGetInfo`, and did not match a corresponding user. This might
// be a team_member_id, an email, or an external ID, depending on how
// the method was called.
IdNotFound string `json:"id_not_found,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -2433,7 +2489,7 @@ func (u *MembersGetInfoItem) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "id_not_found": case "id_not_found":
err = json.Unmarshal(body, &u.IdNotFound) u.IdNotFound = w.IdNotFound
if err != nil { if err != nil {
return err return err
@ -2896,9 +2952,9 @@ func (u *RemoveCustomQuotaResult) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// Success : Successfully removed user. // Success : Successfully removed user.
Success json.RawMessage `json:"success,omitempty"` Success *UserSelectorArg `json:"success,omitempty"`
// InvalidUser : Invalid user (not in team). // InvalidUser : Invalid user (not in team).
InvalidUser json.RawMessage `json:"invalid_user,omitempty"` InvalidUser *UserSelectorArg `json:"invalid_user,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -2908,13 +2964,13 @@ func (u *RemoveCustomQuotaResult) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "success": case "success":
err = json.Unmarshal(w.Success, &u.Success) u.Success = w.Success
if err != nil { if err != nil {
return err return err
} }
case "invalid_user": case "invalid_user":
err = json.Unmarshal(w.InvalidUser, &u.InvalidUser) u.InvalidUser = w.InvalidUser
if err != nil { if err != nil {
return err return err
@ -2980,12 +3036,6 @@ const (
func (u *RevokeDeviceSessionArg) UnmarshalJSON(body []byte) error { func (u *RevokeDeviceSessionArg) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// WebSession : End an active session.
WebSession json.RawMessage `json:"web_session,omitempty"`
// DesktopClient : Unlink a linked desktop device.
DesktopClient json.RawMessage `json:"desktop_client,omitempty"`
// MobileClient : Unlink a linked mobile device.
MobileClient json.RawMessage `json:"mobile_client,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -3242,11 +3292,11 @@ func (u *TeamFolderActivateError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// AccessError : has no documentation (yet) // AccessError : has no documentation (yet)
AccessError json.RawMessage `json:"access_error,omitempty"` AccessError *TeamFolderAccessError `json:"access_error,omitempty"`
// StatusError : has no documentation (yet) // StatusError : has no documentation (yet)
StatusError json.RawMessage `json:"status_error,omitempty"` StatusError *TeamFolderInvalidStatusError `json:"status_error,omitempty"`
// TeamSharedDropboxError : has no documentation (yet) // TeamSharedDropboxError : has no documentation (yet)
TeamSharedDropboxError json.RawMessage `json:"team_shared_dropbox_error,omitempty"` TeamSharedDropboxError *TeamFolderTeamSharedDropboxError `json:"team_shared_dropbox_error,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -3256,19 +3306,19 @@ func (u *TeamFolderActivateError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "access_error": case "access_error":
err = json.Unmarshal(w.AccessError, &u.AccessError) u.AccessError = w.AccessError
if err != nil { if err != nil {
return err return err
} }
case "status_error": case "status_error":
err = json.Unmarshal(w.StatusError, &u.StatusError) u.StatusError = w.StatusError
if err != nil { if err != nil {
return err return err
} }
case "team_shared_dropbox_error": case "team_shared_dropbox_error":
err = json.Unmarshal(w.TeamSharedDropboxError, &u.TeamSharedDropboxError) u.TeamSharedDropboxError = w.TeamSharedDropboxError
if err != nil { if err != nil {
return err return err
@ -3329,11 +3379,11 @@ func (u *TeamFolderArchiveError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// AccessError : has no documentation (yet) // AccessError : has no documentation (yet)
AccessError json.RawMessage `json:"access_error,omitempty"` AccessError *TeamFolderAccessError `json:"access_error,omitempty"`
// StatusError : has no documentation (yet) // StatusError : has no documentation (yet)
StatusError json.RawMessage `json:"status_error,omitempty"` StatusError *TeamFolderInvalidStatusError `json:"status_error,omitempty"`
// TeamSharedDropboxError : has no documentation (yet) // TeamSharedDropboxError : has no documentation (yet)
TeamSharedDropboxError json.RawMessage `json:"team_shared_dropbox_error,omitempty"` TeamSharedDropboxError *TeamFolderTeamSharedDropboxError `json:"team_shared_dropbox_error,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -3343,19 +3393,19 @@ func (u *TeamFolderArchiveError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "access_error": case "access_error":
err = json.Unmarshal(w.AccessError, &u.AccessError) u.AccessError = w.AccessError
if err != nil { if err != nil {
return err return err
} }
case "status_error": case "status_error":
err = json.Unmarshal(w.StatusError, &u.StatusError) u.StatusError = w.StatusError
if err != nil { if err != nil {
return err return err
} }
case "team_shared_dropbox_error": case "team_shared_dropbox_error":
err = json.Unmarshal(w.TeamSharedDropboxError, &u.TeamSharedDropboxError) u.TeamSharedDropboxError = w.TeamSharedDropboxError
if err != nil { if err != nil {
return err return err
@ -3386,12 +3436,9 @@ const (
func (u *TeamFolderArchiveJobStatus) UnmarshalJSON(body []byte) error { func (u *TeamFolderArchiveJobStatus) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// Complete : The archive job has finished. The value is the metadata
// for the resulting team folder.
Complete json.RawMessage `json:"complete,omitempty"`
// Failed : Error occurred while performing an asynchronous job from // Failed : Error occurred while performing an asynchronous job from
// `teamFolderArchive`. // `teamFolderArchive`.
Failed json.RawMessage `json:"failed,omitempty"` Failed *TeamFolderArchiveError `json:"failed,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -3407,7 +3454,7 @@ func (u *TeamFolderArchiveJobStatus) UnmarshalJSON(body []byte) error {
return err return err
} }
case "failed": case "failed":
err = json.Unmarshal(w.Failed, &u.Failed) u.Failed = w.Failed
if err != nil { if err != nil {
return err return err
@ -3437,8 +3484,10 @@ const (
func (u *TeamFolderArchiveLaunch) UnmarshalJSON(body []byte) error { func (u *TeamFolderArchiveLaunch) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// Complete : has no documentation (yet) // AsyncJobId : This response indicates that the processing is
Complete json.RawMessage `json:"complete,omitempty"` // asynchronous. The string is an id that can be used to obtain the
// status of the asynchronous job.
AsyncJobId string `json:"async_job_id,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -3448,7 +3497,7 @@ func (u *TeamFolderArchiveLaunch) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "async_job_id": case "async_job_id":
err = json.Unmarshal(body, &u.AsyncJobId) u.AsyncJobId = w.AsyncJobId
if err != nil { if err != nil {
return err return err
@ -3500,7 +3549,7 @@ func (u *TeamFolderCreateError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// SyncSettingsError : An error occurred setting the sync settings. // SyncSettingsError : An error occurred setting the sync settings.
SyncSettingsError json.RawMessage `json:"sync_settings_error,omitempty"` SyncSettingsError *files.SyncSettingsError `json:"sync_settings_error,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -3510,7 +3559,7 @@ func (u *TeamFolderCreateError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "sync_settings_error": case "sync_settings_error":
err = json.Unmarshal(w.SyncSettingsError, &u.SyncSettingsError) u.SyncSettingsError = w.SyncSettingsError
if err != nil { if err != nil {
return err return err
@ -3539,8 +3588,9 @@ const (
func (u *TeamFolderGetInfoItem) UnmarshalJSON(body []byte) error { func (u *TeamFolderGetInfoItem) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// TeamFolderMetadata : Properties of a team folder. // IdNotFound : An ID that was provided as a parameter to
TeamFolderMetadata json.RawMessage `json:"team_folder_metadata,omitempty"` // `teamFolderGetInfo` did not match any of the team's team folders.
IdNotFound string `json:"id_not_found,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -3550,7 +3600,7 @@ func (u *TeamFolderGetInfoItem) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "id_not_found": case "id_not_found":
err = json.Unmarshal(body, &u.IdNotFound) u.IdNotFound = w.IdNotFound
if err != nil { if err != nil {
return err return err
@ -3717,11 +3767,11 @@ func (u *TeamFolderPermanentlyDeleteError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// AccessError : has no documentation (yet) // AccessError : has no documentation (yet)
AccessError json.RawMessage `json:"access_error,omitempty"` AccessError *TeamFolderAccessError `json:"access_error,omitempty"`
// StatusError : has no documentation (yet) // StatusError : has no documentation (yet)
StatusError json.RawMessage `json:"status_error,omitempty"` StatusError *TeamFolderInvalidStatusError `json:"status_error,omitempty"`
// TeamSharedDropboxError : has no documentation (yet) // TeamSharedDropboxError : has no documentation (yet)
TeamSharedDropboxError json.RawMessage `json:"team_shared_dropbox_error,omitempty"` TeamSharedDropboxError *TeamFolderTeamSharedDropboxError `json:"team_shared_dropbox_error,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -3731,19 +3781,19 @@ func (u *TeamFolderPermanentlyDeleteError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "access_error": case "access_error":
err = json.Unmarshal(w.AccessError, &u.AccessError) u.AccessError = w.AccessError
if err != nil { if err != nil {
return err return err
} }
case "status_error": case "status_error":
err = json.Unmarshal(w.StatusError, &u.StatusError) u.StatusError = w.StatusError
if err != nil { if err != nil {
return err return err
} }
case "team_shared_dropbox_error": case "team_shared_dropbox_error":
err = json.Unmarshal(w.TeamSharedDropboxError, &u.TeamSharedDropboxError) u.TeamSharedDropboxError = w.TeamSharedDropboxError
if err != nil { if err != nil {
return err return err
@ -3794,11 +3844,11 @@ func (u *TeamFolderRenameError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// AccessError : has no documentation (yet) // AccessError : has no documentation (yet)
AccessError json.RawMessage `json:"access_error,omitempty"` AccessError *TeamFolderAccessError `json:"access_error,omitempty"`
// StatusError : has no documentation (yet) // StatusError : has no documentation (yet)
StatusError json.RawMessage `json:"status_error,omitempty"` StatusError *TeamFolderInvalidStatusError `json:"status_error,omitempty"`
// TeamSharedDropboxError : has no documentation (yet) // TeamSharedDropboxError : has no documentation (yet)
TeamSharedDropboxError json.RawMessage `json:"team_shared_dropbox_error,omitempty"` TeamSharedDropboxError *TeamFolderTeamSharedDropboxError `json:"team_shared_dropbox_error,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -3808,19 +3858,19 @@ func (u *TeamFolderRenameError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "access_error": case "access_error":
err = json.Unmarshal(w.AccessError, &u.AccessError) u.AccessError = w.AccessError
if err != nil { if err != nil {
return err return err
} }
case "status_error": case "status_error":
err = json.Unmarshal(w.StatusError, &u.StatusError) u.StatusError = w.StatusError
if err != nil { if err != nil {
return err return err
} }
case "team_shared_dropbox_error": case "team_shared_dropbox_error":
err = json.Unmarshal(w.TeamSharedDropboxError, &u.TeamSharedDropboxError) u.TeamSharedDropboxError = w.TeamSharedDropboxError
if err != nil { if err != nil {
return err return err
@ -3898,13 +3948,13 @@ func (u *TeamFolderUpdateSyncSettingsError) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// AccessError : has no documentation (yet) // AccessError : has no documentation (yet)
AccessError json.RawMessage `json:"access_error,omitempty"` AccessError *TeamFolderAccessError `json:"access_error,omitempty"`
// StatusError : has no documentation (yet) // StatusError : has no documentation (yet)
StatusError json.RawMessage `json:"status_error,omitempty"` StatusError *TeamFolderInvalidStatusError `json:"status_error,omitempty"`
// TeamSharedDropboxError : has no documentation (yet) // TeamSharedDropboxError : has no documentation (yet)
TeamSharedDropboxError json.RawMessage `json:"team_shared_dropbox_error,omitempty"` TeamSharedDropboxError *TeamFolderTeamSharedDropboxError `json:"team_shared_dropbox_error,omitempty"`
// SyncSettingsError : An error occurred setting the sync settings. // SyncSettingsError : An error occurred setting the sync settings.
SyncSettingsError json.RawMessage `json:"sync_settings_error,omitempty"` SyncSettingsError *files.SyncSettingsError `json:"sync_settings_error,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -3914,25 +3964,25 @@ func (u *TeamFolderUpdateSyncSettingsError) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "access_error": case "access_error":
err = json.Unmarshal(w.AccessError, &u.AccessError) u.AccessError = w.AccessError
if err != nil { if err != nil {
return err return err
} }
case "status_error": case "status_error":
err = json.Unmarshal(w.StatusError, &u.StatusError) u.StatusError = w.StatusError
if err != nil { if err != nil {
return err return err
} }
case "team_shared_dropbox_error": case "team_shared_dropbox_error":
err = json.Unmarshal(w.TeamSharedDropboxError, &u.TeamSharedDropboxError) u.TeamSharedDropboxError = w.TeamSharedDropboxError
if err != nil { if err != nil {
return err return err
} }
case "sync_settings_error": case "sync_settings_error":
err = json.Unmarshal(w.SyncSettingsError, &u.SyncSettingsError) u.SyncSettingsError = w.SyncSettingsError
if err != nil { if err != nil {
return err return err
@ -4026,9 +4076,6 @@ const (
func (u *TeamMemberStatus) UnmarshalJSON(body []byte) error { func (u *TeamMemberStatus) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// Removed : User is no longer a member of the team. Removed users are
// only listed when include_removed is true in members/list.
Removed json.RawMessage `json:"removed,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -4129,6 +4176,19 @@ func NewTeamNamespacesListResult(Namespaces []*NamespaceMetadata, Cursor string,
return s return s
} }
// TeamReportFailureReason : has no documentation (yet)
type TeamReportFailureReason struct {
dropbox.Tagged
}
// Valid tag values for TeamReportFailureReason
const (
TeamReportFailureReasonTemporaryError = "temporary_error"
TeamReportFailureReasonManyReportsAtOnce = "many_reports_at_once"
TeamReportFailureReasonTooMuchData = "too_much_data"
TeamReportFailureReasonOther = "other"
)
// TokenGetAuthenticatedAdminError : Error returned by // TokenGetAuthenticatedAdminError : Error returned by
// `tokenGetAuthenticatedAdmin`. // `tokenGetAuthenticatedAdmin`.
type TokenGetAuthenticatedAdminError struct { type TokenGetAuthenticatedAdminError struct {
@ -4173,6 +4233,8 @@ const (
func (u *UploadApiRateLimitValue) UnmarshalJSON(body []byte) error { func (u *UploadApiRateLimitValue) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// Limit : The number of upload API calls allowed per month.
Limit uint32 `json:"limit,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -4182,7 +4244,7 @@ func (u *UploadApiRateLimitValue) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "limit": case "limit":
err = json.Unmarshal(body, &u.Limit) u.Limit = w.Limit
if err != nil { if err != nil {
return err return err
@ -4247,6 +4309,12 @@ const (
func (u *UserSelectorArg) UnmarshalJSON(body []byte) error { func (u *UserSelectorArg) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// TeamMemberId : has no documentation (yet)
TeamMemberId string `json:"team_member_id,omitempty"`
// ExternalId : has no documentation (yet)
ExternalId string `json:"external_id,omitempty"`
// Email : has no documentation (yet)
Email string `json:"email,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -4256,19 +4324,19 @@ func (u *UserSelectorArg) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "team_member_id": case "team_member_id":
err = json.Unmarshal(body, &u.TeamMemberId) u.TeamMemberId = w.TeamMemberId
if err != nil { if err != nil {
return err return err
} }
case "external_id": case "external_id":
err = json.Unmarshal(body, &u.ExternalId) u.ExternalId = w.ExternalId
if err != nil { if err != nil {
return err return err
} }
case "email": case "email":
err = json.Unmarshal(body, &u.Email) u.Email = w.Email
if err != nil { if err != nil {
return err return err
@ -4301,11 +4369,11 @@ func (u *UsersSelectorArg) UnmarshalJSON(body []byte) error {
type wrap struct { type wrap struct {
dropbox.Tagged dropbox.Tagged
// TeamMemberIds : List of member IDs. // TeamMemberIds : List of member IDs.
TeamMemberIds json.RawMessage `json:"team_member_ids,omitempty"` TeamMemberIds []string `json:"team_member_ids,omitempty"`
// ExternalIds : List of external user IDs. // ExternalIds : List of external user IDs.
ExternalIds json.RawMessage `json:"external_ids,omitempty"` ExternalIds []string `json:"external_ids,omitempty"`
// Emails : List of email addresses. // Emails : List of email addresses.
Emails json.RawMessage `json:"emails,omitempty"` Emails []string `json:"emails,omitempty"`
} }
var w wrap var w wrap
var err error var err error
@ -4315,19 +4383,19 @@ func (u *UsersSelectorArg) UnmarshalJSON(body []byte) error {
u.Tag = w.Tag u.Tag = w.Tag
switch u.Tag { switch u.Tag {
case "team_member_ids": case "team_member_ids":
err = json.Unmarshal(body, &u.TeamMemberIds) u.TeamMemberIds = w.TeamMemberIds
if err != nil { if err != nil {
return err return err
} }
case "external_ids": case "external_ids":
err = json.Unmarshal(body, &u.ExternalIds) u.ExternalIds = w.ExternalIds
if err != nil { if err != nil {
return err return err
} }
case "emails": case "emails":
err = json.Unmarshal(body, &u.Emails) u.Emails = w.Emails
if err != nil { if err != nil {
return err return err

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