Unverified Commit 553517e1 authored by Erik Wilson's avatar Erik Wilson Committed by GitHub

Merge pull request #1569 from ibuildthecloud/k3s-v1.18

k8s 1.18
parents c14dac9a 0434eea4

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

...@@ -6,7 +6,7 @@ ARG DAPPER_HOST_ARCH ...@@ -6,7 +6,7 @@ ARG DAPPER_HOST_ARCH
ENV ARCH $DAPPER_HOST_ARCH ENV ARCH $DAPPER_HOST_ARCH
RUN if [ "${ARCH}" == "amd64" ] || [ "${ARCH}" == "arm64" ]; then \ RUN if [ "${ARCH}" == "amd64" ] || [ "${ARCH}" == "arm64" ]; then \
VERSION=0.17.1 OS=linux && \ VERSION=0.17.2 OS=linux && \
curl -sL "https://github.com/vmware-tanzu/sonobuoy/releases/download/v${VERSION}/sonobuoy_${VERSION}_${OS}_${ARCH}.tar.gz" | \ curl -sL "https://github.com/vmware-tanzu/sonobuoy/releases/download/v${VERSION}/sonobuoy_${VERSION}_${OS}_${ARCH}.tar.gz" | \
tar -xzf - -C /usr/local/bin; \ tar -xzf - -C /usr/local/bin; \
fi fi
......
module github.com/rancher/k3s module github.com/rancher/k3s
go 1.12 go 1.13
replace ( replace (
github.com/Microsoft/hcsshim => github.com/Microsoft/hcsshim v0.8.7-0.20190926181021-82c7525d98c8 github.com/Microsoft/hcsshim => github.com/Microsoft/hcsshim v0.8.7-0.20190926181021-82c7525d98c8
...@@ -13,7 +13,7 @@ replace ( ...@@ -13,7 +13,7 @@ replace (
github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c github.com/containerd/fifo => github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c
github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda github.com/containerd/go-runc => github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda
github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd github.com/containerd/typeurl => github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd
github.com/coreos/flannel => github.com/rancher/flannel v0.11.0-k3s.1 github.com/coreos/flannel => github.com/rancher/flannel v0.11.0-k3s.2
github.com/coreos/go-systemd => github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e github.com/coreos/go-systemd => github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
github.com/docker/distribution => github.com/docker/distribution v0.0.0-20190205005809-0d3efadf0154 github.com/docker/distribution => github.com/docker/distribution v0.0.0-20190205005809-0d3efadf0154
github.com/docker/docker => github.com/docker/docker v17.12.0-ce-rc1.0.20190219214528-cbe11bdc6da8+incompatible github.com/docker/docker => github.com/docker/docker v17.12.0-ce-rc1.0.20190219214528-cbe11bdc6da8+incompatible
...@@ -25,43 +25,44 @@ replace ( ...@@ -25,43 +25,44 @@ replace (
github.com/golangci/gosec => github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547 github.com/golangci/gosec => github.com/golangci/gosec v0.0.0-20190211064107-66fb7fc33547
github.com/golangci/ineffassign => github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc github.com/golangci/ineffassign => github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc
github.com/golangci/lint-1 => github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217 github.com/golangci/lint-1 => github.com/golangci/lint-1 v0.0.0-20190420132249-ee948d087217
github.com/kubernetes-sigs/cri-tools => github.com/rancher/cri-tools v1.17.0-k3s1 github.com/kubernetes-sigs/cri-tools => github.com/rancher/cri-tools v1.18.0-k3s1
github.com/matryer/moq => github.com/rancher/moq v0.0.0-20190404221404-ee5226d43009 github.com/matryer/moq => github.com/rancher/moq v0.0.0-20190404221404-ee5226d43009
github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v0.0.0-20180911193056-5684b8af48c1 github.com/opencontainers/runtime-spec => github.com/opencontainers/runtime-spec v0.0.0-20180911193056-5684b8af48c1
github.com/prometheus/client_golang => github.com/prometheus/client_golang v0.9.2 github.com/prometheus/client_golang => github.com/prometheus/client_golang v0.9.2
github.com/prometheus/client_model => github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 github.com/prometheus/client_model => github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910
github.com/prometheus/common => github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 github.com/prometheus/common => github.com/prometheus/common v0.0.0-20181126121408-4724e9255275
github.com/prometheus/procfs => github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a github.com/prometheus/procfs => github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a
k8s.io/api => github.com/rancher/kubernetes/staging/src/k8s.io/api v1.17.4-k3s1 k8s.io/api => github.com/rancher/kubernetes/staging/src/k8s.io/api v1.18.2-k3s.1
k8s.io/apiextensions-apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/apiextensions-apiserver v1.17.4-k3s1 k8s.io/apiextensions-apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/apiextensions-apiserver v1.18.2-k3s.1
k8s.io/apimachinery => github.com/rancher/kubernetes/staging/src/k8s.io/apimachinery v1.17.4-k3s1 k8s.io/apimachinery => github.com/rancher/kubernetes/staging/src/k8s.io/apimachinery v1.18.2-k3s.1
k8s.io/apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/apiserver v1.17.4-k3s1 k8s.io/apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/apiserver v1.18.2-k3s.1
k8s.io/cli-runtime => github.com/rancher/kubernetes/staging/src/k8s.io/cli-runtime v1.17.4-k3s1 k8s.io/cli-runtime => github.com/rancher/kubernetes/staging/src/k8s.io/cli-runtime v1.18.2-k3s.1
k8s.io/client-go => github.com/rancher/kubernetes/staging/src/k8s.io/client-go v1.17.4-k3s1 k8s.io/client-go => github.com/rancher/kubernetes/staging/src/k8s.io/client-go v1.18.2-k3s.1
k8s.io/cloud-provider => github.com/rancher/kubernetes/staging/src/k8s.io/cloud-provider v1.17.4-k3s1 k8s.io/cloud-provider => github.com/rancher/kubernetes/staging/src/k8s.io/cloud-provider v1.18.2-k3s.1
k8s.io/cluster-bootstrap => github.com/rancher/kubernetes/staging/src/k8s.io/cluster-bootstrap v1.17.4-k3s1 k8s.io/cluster-bootstrap => github.com/rancher/kubernetes/staging/src/k8s.io/cluster-bootstrap v1.18.2-k3s.1
k8s.io/code-generator => github.com/rancher/kubernetes/staging/src/k8s.io/code-generator v1.17.4-k3s1 k8s.io/code-generator => github.com/rancher/kubernetes/staging/src/k8s.io/code-generator v1.18.2-k3s.1
k8s.io/component-base => github.com/rancher/kubernetes/staging/src/k8s.io/component-base v1.17.4-k3s1 k8s.io/component-base => github.com/rancher/kubernetes/staging/src/k8s.io/component-base v1.18.2-k3s.1
k8s.io/cri-api => github.com/rancher/kubernetes/staging/src/k8s.io/cri-api v1.17.4-k3s1 k8s.io/cri-api => github.com/rancher/kubernetes/staging/src/k8s.io/cri-api v1.18.2-k3s.1
k8s.io/csi-translation-lib => github.com/rancher/kubernetes/staging/src/k8s.io/csi-translation-lib v1.17.4-k3s1 k8s.io/csi-translation-lib => github.com/rancher/kubernetes/staging/src/k8s.io/csi-translation-lib v1.18.2-k3s.1
k8s.io/kube-aggregator => github.com/rancher/kubernetes/staging/src/k8s.io/kube-aggregator v1.17.4-k3s1 k8s.io/kube-aggregator => github.com/rancher/kubernetes/staging/src/k8s.io/kube-aggregator v1.18.2-k3s.1
k8s.io/kube-controller-manager => github.com/rancher/kubernetes/staging/src/k8s.io/kube-controller-manager v1.17.4-k3s1 k8s.io/kube-controller-manager => github.com/rancher/kubernetes/staging/src/k8s.io/kube-controller-manager v1.18.2-k3s.1
k8s.io/kube-proxy => github.com/rancher/kubernetes/staging/src/k8s.io/kube-proxy v1.17.4-k3s1 k8s.io/kube-proxy => github.com/rancher/kubernetes/staging/src/k8s.io/kube-proxy v1.18.2-k3s.1
k8s.io/kube-scheduler => github.com/rancher/kubernetes/staging/src/k8s.io/kube-scheduler v1.17.4-k3s1 k8s.io/kube-scheduler => github.com/rancher/kubernetes/staging/src/k8s.io/kube-scheduler v1.18.2-k3s.1
k8s.io/kubectl => github.com/rancher/kubernetes/staging/src/k8s.io/kubectl v1.17.4-k3s1 k8s.io/kubectl => github.com/rancher/kubernetes/staging/src/k8s.io/kubectl v1.18.2-k3s.1
k8s.io/kubelet => github.com/rancher/kubernetes/staging/src/k8s.io/kubelet v1.17.4-k3s1 k8s.io/kubelet => github.com/rancher/kubernetes/staging/src/k8s.io/kubelet v1.18.2-k3s.1
k8s.io/kubernetes => github.com/rancher/kubernetes v1.17.4-k3s1 k8s.io/kubernetes => github.com/rancher/kubernetes v1.18.2-k3s.1
k8s.io/legacy-cloud-providers => github.com/rancher/kubernetes/staging/src/k8s.io/legacy-cloud-providers v1.17.4-k3s1 k8s.io/legacy-cloud-providers => github.com/rancher/kubernetes/staging/src/k8s.io/legacy-cloud-providers v1.18.2-k3s.1
k8s.io/metrics => github.com/rancher/kubernetes/staging/src/k8s.io/metrics v1.17.4-k3s1 k8s.io/metrics => github.com/rancher/kubernetes/staging/src/k8s.io/metrics v1.18.2-k3s.1
k8s.io/node-api => github.com/rancher/kubernetes/staging/src/k8s.io/node-api v1.17.4-k3s1 k8s.io/node-api => github.com/rancher/kubernetes/staging/src/k8s.io/node-api v1.18.2-k3s.1
k8s.io/sample-apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/sample-apiserver v1.17.4-k3s1 k8s.io/sample-apiserver => github.com/rancher/kubernetes/staging/src/k8s.io/sample-apiserver v1.18.2-k3s.1
k8s.io/sample-cli-plugin => github.com/rancher/kubernetes/staging/src/k8s.io/sample-cli-plugin v1.17.4-k3s1 k8s.io/sample-cli-plugin => github.com/rancher/kubernetes/staging/src/k8s.io/sample-cli-plugin v1.18.2-k3s.1
k8s.io/sample-controller => github.com/rancher/kubernetes/staging/src/k8s.io/sample-controller v1.17.4-k3s1 k8s.io/sample-controller => github.com/rancher/kubernetes/staging/src/k8s.io/sample-controller v1.18.2-k3s.1
mvdan.cc/unparam => mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34 mvdan.cc/unparam => mvdan.cc/unparam v0.0.0-20190209190245-fbb59629db34
) )
require ( require (
github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/bhendo/go-powershell v0.0.0-20190719160123-219e7fb4e41e // indirect github.com/bhendo/go-powershell v0.0.0-20190719160123-219e7fb4e41e // indirect
github.com/bronze1man/goStrongswanVici v0.0.0-20190828090544-27d02f80ba40 // indirect github.com/bronze1man/goStrongswanVici v0.0.0-20190828090544-27d02f80ba40 // indirect
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23 // indirect
...@@ -96,14 +97,14 @@ require ( ...@@ -96,14 +97,14 @@ require (
github.com/natefinch/lumberjack v2.0.0+incompatible github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/opencontainers/runc v1.0.0-rc9 github.com/opencontainers/runc v1.0.0-rc9
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52 github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.9.1
github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8 // indirect github.com/rakelkar/gonetsh v0.0.0-20190719023240-501daadcadf8 // indirect
github.com/rancher/dynamiclistener v0.2.0 github.com/rancher/dynamiclistener v0.2.0
github.com/rancher/helm-controller v0.4.1 github.com/rancher/helm-controller v0.4.2-0.20200326195131-eb51d4fa9d8d
github.com/rancher/kine v0.3.5 github.com/rancher/kine v0.3.5
github.com/rancher/remotedialer v0.2.0 github.com/rancher/remotedialer v0.2.0
github.com/rancher/wrangler v0.4.0 github.com/rancher/wrangler v0.5.4-0.20200326191509-4054411d9736
github.com/rancher/wrangler-api v0.4.0 github.com/rancher/wrangler-api v0.5.1-0.20200326194427-c13310506d04
github.com/rootless-containers/rootlesskit v0.7.2 github.com/rootless-containers/rootlesskit v0.7.2
github.com/sirupsen/logrus v1.4.2 github.com/sirupsen/logrus v1.4.2
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
...@@ -112,17 +113,17 @@ require ( ...@@ -112,17 +113,17 @@ require (
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975
golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e
google.golang.org/grpc v1.25.1 google.golang.org/grpc v1.26.0
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect
gopkg.in/robfig/cron.v2 v2.0.0-20150107220207-be2e0b0deed5 // indirect gopkg.in/robfig/cron.v2 v2.0.0-20150107220207-be2e0b0deed5 // indirect
gopkg.in/yaml.v2 v2.2.8 gopkg.in/yaml.v2 v2.2.8
k8s.io/api v0.17.0 k8s.io/api v0.18.0
k8s.io/apimachinery v0.17.0 k8s.io/apimachinery v0.18.0
k8s.io/apiserver v0.0.0 k8s.io/apiserver v0.0.0
k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible
k8s.io/cloud-provider v0.0.0 k8s.io/cloud-provider v0.0.0
k8s.io/component-base v0.0.0 k8s.io/component-base v0.0.0
k8s.io/cri-api v0.0.0 k8s.io/cri-api v0.0.0
k8s.io/klog v1.0.0 k8s.io/klog v1.0.0
k8s.io/kubernetes v1.16.0 k8s.io/kubernetes v1.18.0
) )
...@@ -80,7 +80,7 @@ func Run(ctx context.Context, cfg *config.Node) error { ...@@ -80,7 +80,7 @@ func Run(ctx context.Context, cfg *config.Node) error {
continue continue
} }
conn, err := grpc.Dial(addr, grpc.WithInsecure(), grpc.WithTimeout(3*time.Second), grpc.WithDialer(dialer), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(maxMsgSize))) conn, err := grpc.Dial(addr, grpc.WithInsecure(), grpc.WithTimeout(3*time.Second), grpc.WithContextDialer(dialer), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(maxMsgSize)))
if err != nil { if err != nil {
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
continue continue
......
...@@ -81,7 +81,7 @@ func Run(ctx context.Context, nodeConfig *config.Node, nodes v1.NodeInterface) e ...@@ -81,7 +81,7 @@ func Run(ctx context.Context, nodeConfig *config.Node, nodes v1.NodeInterface) e
nodeName := nodeConfig.AgentConfig.NodeName nodeName := nodeConfig.AgentConfig.NodeName
for { for {
node, err := nodes.Get(nodeName, metav1.GetOptions{}) node, err := nodes.Get(ctx, nodeName, metav1.GetOptions{})
if err == nil && node.Spec.PodCIDR != "" { if err == nil && node.Spec.PodCIDR != "" {
break break
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
package netpol package netpol
import ( import (
"context"
"crypto/sha256" "crypto/sha256"
"encoding/base32" "encoding/base32"
"errors" "errors"
...@@ -1700,7 +1701,7 @@ func NewNetworkPolicyController( ...@@ -1700,7 +1701,7 @@ func NewNetworkPolicyController(
npc.v1NetworkPolicy = false npc.v1NetworkPolicy = false
} }
node, err := clientset.CoreV1().Nodes().Get(hostnameOverride, metav1.GetOptions{}) node, err := clientset.CoreV1().Nodes().Get(context.TODO(), hostnameOverride, metav1.GetOptions{})
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -158,7 +158,7 @@ func validate() error { ...@@ -158,7 +158,7 @@ func validate() error {
func configureNode(ctx context.Context, agentConfig *daemonconfig.Agent, nodes v1.NodeInterface) error { func configureNode(ctx context.Context, agentConfig *daemonconfig.Agent, nodes v1.NodeInterface) error {
for { for {
node, err := nodes.Get(agentConfig.NodeName, metav1.GetOptions{}) node, err := nodes.Get(ctx, agentConfig.NodeName, metav1.GetOptions{})
if err != nil { if err != nil {
logrus.Infof("Waiting for kubelet to be ready on node %s: %v", agentConfig.NodeName, err) logrus.Infof("Waiting for kubelet to be ready on node %s: %v", agentConfig.NodeName, err)
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
...@@ -182,7 +182,7 @@ func configureNode(ctx context.Context, agentConfig *daemonconfig.Agent, nodes v ...@@ -182,7 +182,7 @@ func configureNode(ctx context.Context, agentConfig *daemonconfig.Agent, nodes v
updateNode = true updateNode = true
} }
if updateNode { if updateNode {
if _, err := nodes.Update(node); err != nil { if _, err := nodes.Update(ctx, node, metav1.UpdateOptions{}); err != nil {
logrus.Infof("Failed to update node %s: %v", agentConfig.NodeName, err) logrus.Infof("Failed to update node %s: %v", agentConfig.NodeName, err)
select { select {
case <-ctx.Done(): case <-ctx.Done():
......
...@@ -73,7 +73,7 @@ func Setup(ctx context.Context, config *config.Node, onChange func([]string)) er ...@@ -73,7 +73,7 @@ func Setup(ctx context.Context, config *config.Node, onChange func([]string)) er
addresses := []string{config.ServerAddress} addresses := []string{config.ServerAddress}
endpoint, _ := client.CoreV1().Endpoints("default").Get("kubernetes", metav1.GetOptions{}) endpoint, _ := client.CoreV1().Endpoints("default").Get(ctx, "kubernetes", metav1.GetOptions{})
if endpoint != nil { if endpoint != nil {
addresses = getAddresses(endpoint) addresses = getAddresses(endpoint)
if onChange != nil { if onChange != nil {
...@@ -94,7 +94,7 @@ func Setup(ctx context.Context, config *config.Node, onChange func([]string)) er ...@@ -94,7 +94,7 @@ func Setup(ctx context.Context, config *config.Node, onChange func([]string)) er
connect: connect:
for { for {
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
watch, err := client.CoreV1().Endpoints("default").Watch(metav1.ListOptions{ watch, err := client.CoreV1().Endpoints("default").Watch(ctx, metav1.ListOptions{
FieldSelector: fields.Set{"metadata.name": "kubernetes"}.String(), FieldSelector: fields.Set{"metadata.name": "kubernetes"}.String(),
ResourceVersion: "0", ResourceVersion: "0",
}) })
......
...@@ -59,7 +59,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) { ...@@ -59,7 +59,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
configShallowCopy := *c configShallowCopy := *c
if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 {
if configShallowCopy.Burst <= 0 { if configShallowCopy.Burst <= 0 {
return nil, fmt.Errorf("Burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0")
} }
configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst)
} }
......
...@@ -19,6 +19,7 @@ limitations under the License. ...@@ -19,6 +19,7 @@ limitations under the License.
package v1 package v1
import ( import (
"context"
"time" "time"
v1 "github.com/rancher/k3s/pkg/apis/k3s.cattle.io/v1" v1 "github.com/rancher/k3s/pkg/apis/k3s.cattle.io/v1"
...@@ -37,15 +38,15 @@ type AddonsGetter interface { ...@@ -37,15 +38,15 @@ type AddonsGetter interface {
// AddonInterface has methods to work with Addon resources. // AddonInterface has methods to work with Addon resources.
type AddonInterface interface { type AddonInterface interface {
Create(*v1.Addon) (*v1.Addon, error) Create(ctx context.Context, addon *v1.Addon, opts metav1.CreateOptions) (*v1.Addon, error)
Update(*v1.Addon) (*v1.Addon, error) Update(ctx context.Context, addon *v1.Addon, opts metav1.UpdateOptions) (*v1.Addon, error)
UpdateStatus(*v1.Addon) (*v1.Addon, error) UpdateStatus(ctx context.Context, addon *v1.Addon, opts metav1.UpdateOptions) (*v1.Addon, error)
Delete(name string, options *metav1.DeleteOptions) error Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
Get(name string, options metav1.GetOptions) (*v1.Addon, error) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Addon, error)
List(opts metav1.ListOptions) (*v1.AddonList, error) List(ctx context.Context, opts metav1.ListOptions) (*v1.AddonList, error)
Watch(opts metav1.ListOptions) (watch.Interface, error) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error)
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Addon, err error) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Addon, err error)
AddonExpansion AddonExpansion
} }
...@@ -64,20 +65,20 @@ func newAddons(c *K3sV1Client, namespace string) *addons { ...@@ -64,20 +65,20 @@ func newAddons(c *K3sV1Client, namespace string) *addons {
} }
// Get takes name of the addon, and returns the corresponding addon object, and an error if there is any. // Get takes name of the addon, and returns the corresponding addon object, and an error if there is any.
func (c *addons) Get(name string, options metav1.GetOptions) (result *v1.Addon, err error) { func (c *addons) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.Addon, err error) {
result = &v1.Addon{} result = &v1.Addon{}
err = c.client.Get(). err = c.client.Get().
Namespace(c.ns). Namespace(c.ns).
Resource("addons"). Resource("addons").
Name(name). Name(name).
VersionedParams(&options, scheme.ParameterCodec). VersionedParams(&options, scheme.ParameterCodec).
Do(). Do(ctx).
Into(result) Into(result)
return return
} }
// List takes label and field selectors, and returns the list of Addons that match those selectors. // List takes label and field selectors, and returns the list of Addons that match those selectors.
func (c *addons) List(opts metav1.ListOptions) (result *v1.AddonList, err error) { func (c *addons) List(ctx context.Context, opts metav1.ListOptions) (result *v1.AddonList, err error) {
var timeout time.Duration var timeout time.Duration
if opts.TimeoutSeconds != nil { if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
...@@ -88,13 +89,13 @@ func (c *addons) List(opts metav1.ListOptions) (result *v1.AddonList, err error) ...@@ -88,13 +89,13 @@ func (c *addons) List(opts metav1.ListOptions) (result *v1.AddonList, err error)
Resource("addons"). Resource("addons").
VersionedParams(&opts, scheme.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout). Timeout(timeout).
Do(). Do(ctx).
Into(result) Into(result)
return return
} }
// Watch returns a watch.Interface that watches the requested addons. // Watch returns a watch.Interface that watches the requested addons.
func (c *addons) Watch(opts metav1.ListOptions) (watch.Interface, error) { func (c *addons) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
var timeout time.Duration var timeout time.Duration
if opts.TimeoutSeconds != nil { if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
...@@ -105,87 +106,90 @@ func (c *addons) Watch(opts metav1.ListOptions) (watch.Interface, error) { ...@@ -105,87 +106,90 @@ func (c *addons) Watch(opts metav1.ListOptions) (watch.Interface, error) {
Resource("addons"). Resource("addons").
VersionedParams(&opts, scheme.ParameterCodec). VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout). Timeout(timeout).
Watch() Watch(ctx)
} }
// Create takes the representation of a addon and creates it. Returns the server's representation of the addon, and an error, if there is any. // Create takes the representation of a addon and creates it. Returns the server's representation of the addon, and an error, if there is any.
func (c *addons) Create(addon *v1.Addon) (result *v1.Addon, err error) { func (c *addons) Create(ctx context.Context, addon *v1.Addon, opts metav1.CreateOptions) (result *v1.Addon, err error) {
result = &v1.Addon{} result = &v1.Addon{}
err = c.client.Post(). err = c.client.Post().
Namespace(c.ns). Namespace(c.ns).
Resource("addons"). Resource("addons").
VersionedParams(&opts, scheme.ParameterCodec).
Body(addon). Body(addon).
Do(). Do(ctx).
Into(result) Into(result)
return return
} }
// Update takes the representation of a addon and updates it. Returns the server's representation of the addon, and an error, if there is any. // Update takes the representation of a addon and updates it. Returns the server's representation of the addon, and an error, if there is any.
func (c *addons) Update(addon *v1.Addon) (result *v1.Addon, err error) { func (c *addons) Update(ctx context.Context, addon *v1.Addon, opts metav1.UpdateOptions) (result *v1.Addon, err error) {
result = &v1.Addon{} result = &v1.Addon{}
err = c.client.Put(). err = c.client.Put().
Namespace(c.ns). Namespace(c.ns).
Resource("addons"). Resource("addons").
Name(addon.Name). Name(addon.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(addon). Body(addon).
Do(). Do(ctx).
Into(result) Into(result)
return return
} }
// UpdateStatus was generated because the type contains a Status member. // UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *addons) UpdateStatus(ctx context.Context, addon *v1.Addon, opts metav1.UpdateOptions) (result *v1.Addon, err error) {
func (c *addons) UpdateStatus(addon *v1.Addon) (result *v1.Addon, err error) {
result = &v1.Addon{} result = &v1.Addon{}
err = c.client.Put(). err = c.client.Put().
Namespace(c.ns). Namespace(c.ns).
Resource("addons"). Resource("addons").
Name(addon.Name). Name(addon.Name).
SubResource("status"). SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(addon). Body(addon).
Do(). Do(ctx).
Into(result) Into(result)
return return
} }
// Delete takes name of the addon and deletes it. Returns an error if one occurs. // Delete takes name of the addon and deletes it. Returns an error if one occurs.
func (c *addons) Delete(name string, options *metav1.DeleteOptions) error { func (c *addons) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
return c.client.Delete(). return c.client.Delete().
Namespace(c.ns). Namespace(c.ns).
Resource("addons"). Resource("addons").
Name(name). Name(name).
Body(options). Body(&opts).
Do(). Do(ctx).
Error() Error()
} }
// DeleteCollection deletes a collection of objects. // DeleteCollection deletes a collection of objects.
func (c *addons) DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error { func (c *addons) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
var timeout time.Duration var timeout time.Duration
if listOptions.TimeoutSeconds != nil { if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOptions.TimeoutSeconds) * time.Second timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
} }
return c.client.Delete(). return c.client.Delete().
Namespace(c.ns). Namespace(c.ns).
Resource("addons"). Resource("addons").
VersionedParams(&listOptions, scheme.ParameterCodec). VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout). Timeout(timeout).
Body(options). Body(&opts).
Do(). Do(ctx).
Error() Error()
} }
// Patch applies the patch and returns the patched addon. // Patch applies the patch and returns the patched addon.
func (c *addons) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Addon, err error) { func (c *addons) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.Addon, err error) {
result = &v1.Addon{} result = &v1.Addon{}
err = c.client.Patch(pt). err = c.client.Patch(pt).
Namespace(c.ns). Namespace(c.ns).
Resource("addons"). Resource("addons").
SubResource(subresources...).
Name(name). Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data). Body(data).
Do(). Do(ctx).
Into(result) Into(result)
return return
} }
...@@ -19,6 +19,8 @@ limitations under the License. ...@@ -19,6 +19,8 @@ limitations under the License.
package fake package fake
import ( import (
"context"
k3scattleiov1 "github.com/rancher/k3s/pkg/apis/k3s.cattle.io/v1" k3scattleiov1 "github.com/rancher/k3s/pkg/apis/k3s.cattle.io/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels" labels "k8s.io/apimachinery/pkg/labels"
...@@ -39,7 +41,7 @@ var addonsResource = schema.GroupVersionResource{Group: "k3s.cattle.io", Version ...@@ -39,7 +41,7 @@ var addonsResource = schema.GroupVersionResource{Group: "k3s.cattle.io", Version
var addonsKind = schema.GroupVersionKind{Group: "k3s.cattle.io", Version: "v1", Kind: "Addon"} var addonsKind = schema.GroupVersionKind{Group: "k3s.cattle.io", Version: "v1", Kind: "Addon"}
// Get takes name of the addon, and returns the corresponding addon object, and an error if there is any. // Get takes name of the addon, and returns the corresponding addon object, and an error if there is any.
func (c *FakeAddons) Get(name string, options v1.GetOptions) (result *k3scattleiov1.Addon, err error) { func (c *FakeAddons) Get(ctx context.Context, name string, options v1.GetOptions) (result *k3scattleiov1.Addon, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewGetAction(addonsResource, c.ns, name), &k3scattleiov1.Addon{}) Invokes(testing.NewGetAction(addonsResource, c.ns, name), &k3scattleiov1.Addon{})
...@@ -50,7 +52,7 @@ func (c *FakeAddons) Get(name string, options v1.GetOptions) (result *k3scattlei ...@@ -50,7 +52,7 @@ func (c *FakeAddons) Get(name string, options v1.GetOptions) (result *k3scattlei
} }
// List takes label and field selectors, and returns the list of Addons that match those selectors. // List takes label and field selectors, and returns the list of Addons that match those selectors.
func (c *FakeAddons) List(opts v1.ListOptions) (result *k3scattleiov1.AddonList, err error) { func (c *FakeAddons) List(ctx context.Context, opts v1.ListOptions) (result *k3scattleiov1.AddonList, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewListAction(addonsResource, addonsKind, c.ns, opts), &k3scattleiov1.AddonList{}) Invokes(testing.NewListAction(addonsResource, addonsKind, c.ns, opts), &k3scattleiov1.AddonList{})
...@@ -72,14 +74,14 @@ func (c *FakeAddons) List(opts v1.ListOptions) (result *k3scattleiov1.AddonList, ...@@ -72,14 +74,14 @@ func (c *FakeAddons) List(opts v1.ListOptions) (result *k3scattleiov1.AddonList,
} }
// Watch returns a watch.Interface that watches the requested addons. // Watch returns a watch.Interface that watches the requested addons.
func (c *FakeAddons) Watch(opts v1.ListOptions) (watch.Interface, error) { func (c *FakeAddons) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake. return c.Fake.
InvokesWatch(testing.NewWatchAction(addonsResource, c.ns, opts)) InvokesWatch(testing.NewWatchAction(addonsResource, c.ns, opts))
} }
// Create takes the representation of a addon and creates it. Returns the server's representation of the addon, and an error, if there is any. // Create takes the representation of a addon and creates it. Returns the server's representation of the addon, and an error, if there is any.
func (c *FakeAddons) Create(addon *k3scattleiov1.Addon) (result *k3scattleiov1.Addon, err error) { func (c *FakeAddons) Create(ctx context.Context, addon *k3scattleiov1.Addon, opts v1.CreateOptions) (result *k3scattleiov1.Addon, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewCreateAction(addonsResource, c.ns, addon), &k3scattleiov1.Addon{}) Invokes(testing.NewCreateAction(addonsResource, c.ns, addon), &k3scattleiov1.Addon{})
...@@ -90,7 +92,7 @@ func (c *FakeAddons) Create(addon *k3scattleiov1.Addon) (result *k3scattleiov1.A ...@@ -90,7 +92,7 @@ func (c *FakeAddons) Create(addon *k3scattleiov1.Addon) (result *k3scattleiov1.A
} }
// Update takes the representation of a addon and updates it. Returns the server's representation of the addon, and an error, if there is any. // Update takes the representation of a addon and updates it. Returns the server's representation of the addon, and an error, if there is any.
func (c *FakeAddons) Update(addon *k3scattleiov1.Addon) (result *k3scattleiov1.Addon, err error) { func (c *FakeAddons) Update(ctx context.Context, addon *k3scattleiov1.Addon, opts v1.UpdateOptions) (result *k3scattleiov1.Addon, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewUpdateAction(addonsResource, c.ns, addon), &k3scattleiov1.Addon{}) Invokes(testing.NewUpdateAction(addonsResource, c.ns, addon), &k3scattleiov1.Addon{})
...@@ -102,7 +104,7 @@ func (c *FakeAddons) Update(addon *k3scattleiov1.Addon) (result *k3scattleiov1.A ...@@ -102,7 +104,7 @@ func (c *FakeAddons) Update(addon *k3scattleiov1.Addon) (result *k3scattleiov1.A
// UpdateStatus was generated because the type contains a Status member. // UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeAddons) UpdateStatus(addon *k3scattleiov1.Addon) (*k3scattleiov1.Addon, error) { func (c *FakeAddons) UpdateStatus(ctx context.Context, addon *k3scattleiov1.Addon, opts v1.UpdateOptions) (*k3scattleiov1.Addon, error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(addonsResource, "status", c.ns, addon), &k3scattleiov1.Addon{}) Invokes(testing.NewUpdateSubresourceAction(addonsResource, "status", c.ns, addon), &k3scattleiov1.Addon{})
...@@ -113,7 +115,7 @@ func (c *FakeAddons) UpdateStatus(addon *k3scattleiov1.Addon) (*k3scattleiov1.Ad ...@@ -113,7 +115,7 @@ func (c *FakeAddons) UpdateStatus(addon *k3scattleiov1.Addon) (*k3scattleiov1.Ad
} }
// Delete takes name of the addon and deletes it. Returns an error if one occurs. // Delete takes name of the addon and deletes it. Returns an error if one occurs.
func (c *FakeAddons) Delete(name string, options *v1.DeleteOptions) error { func (c *FakeAddons) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake. _, err := c.Fake.
Invokes(testing.NewDeleteAction(addonsResource, c.ns, name), &k3scattleiov1.Addon{}) Invokes(testing.NewDeleteAction(addonsResource, c.ns, name), &k3scattleiov1.Addon{})
...@@ -121,15 +123,15 @@ func (c *FakeAddons) Delete(name string, options *v1.DeleteOptions) error { ...@@ -121,15 +123,15 @@ func (c *FakeAddons) Delete(name string, options *v1.DeleteOptions) error {
} }
// DeleteCollection deletes a collection of objects. // DeleteCollection deletes a collection of objects.
func (c *FakeAddons) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { func (c *FakeAddons) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewDeleteCollectionAction(addonsResource, c.ns, listOptions) action := testing.NewDeleteCollectionAction(addonsResource, c.ns, listOpts)
_, err := c.Fake.Invokes(action, &k3scattleiov1.AddonList{}) _, err := c.Fake.Invokes(action, &k3scattleiov1.AddonList{})
return err return err
} }
// Patch applies the patch and returns the patched addon. // Patch applies the patch and returns the patched addon.
func (c *FakeAddons) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *k3scattleiov1.Addon, err error) { func (c *FakeAddons) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *k3scattleiov1.Addon, err error) {
obj, err := c.Fake. obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(addonsResource, c.ns, name, pt, data, subresources...), &k3scattleiov1.Addon{}) Invokes(testing.NewPatchSubresourceAction(addonsResource, c.ns, name, pt, data, subresources...), &k3scattleiov1.Addon{})
......
...@@ -176,35 +176,38 @@ func (c *addonController) Cache() AddonCache { ...@@ -176,35 +176,38 @@ func (c *addonController) Cache() AddonCache {
} }
func (c *addonController) Create(obj *v1.Addon) (*v1.Addon, error) { func (c *addonController) Create(obj *v1.Addon) (*v1.Addon, error) {
return c.clientGetter.Addons(obj.Namespace).Create(obj) return c.clientGetter.Addons(obj.Namespace).Create(context.TODO(), obj, metav1.CreateOptions{})
} }
func (c *addonController) Update(obj *v1.Addon) (*v1.Addon, error) { func (c *addonController) Update(obj *v1.Addon) (*v1.Addon, error) {
return c.clientGetter.Addons(obj.Namespace).Update(obj) return c.clientGetter.Addons(obj.Namespace).Update(context.TODO(), obj, metav1.UpdateOptions{})
} }
func (c *addonController) UpdateStatus(obj *v1.Addon) (*v1.Addon, error) { func (c *addonController) UpdateStatus(obj *v1.Addon) (*v1.Addon, error) {
return c.clientGetter.Addons(obj.Namespace).UpdateStatus(obj) return c.clientGetter.Addons(obj.Namespace).UpdateStatus(context.TODO(), obj, metav1.UpdateOptions{})
} }
func (c *addonController) Delete(namespace, name string, options *metav1.DeleteOptions) error { func (c *addonController) Delete(namespace, name string, options *metav1.DeleteOptions) error {
return c.clientGetter.Addons(namespace).Delete(name, options) if options == nil {
options = &metav1.DeleteOptions{}
}
return c.clientGetter.Addons(namespace).Delete(context.TODO(), name, *options)
} }
func (c *addonController) Get(namespace, name string, options metav1.GetOptions) (*v1.Addon, error) { func (c *addonController) Get(namespace, name string, options metav1.GetOptions) (*v1.Addon, error) {
return c.clientGetter.Addons(namespace).Get(name, options) return c.clientGetter.Addons(namespace).Get(context.TODO(), name, options)
} }
func (c *addonController) List(namespace string, opts metav1.ListOptions) (*v1.AddonList, error) { func (c *addonController) List(namespace string, opts metav1.ListOptions) (*v1.AddonList, error) {
return c.clientGetter.Addons(namespace).List(opts) return c.clientGetter.Addons(namespace).List(context.TODO(), opts)
} }
func (c *addonController) Watch(namespace string, opts metav1.ListOptions) (watch.Interface, error) { func (c *addonController) Watch(namespace string, opts metav1.ListOptions) (watch.Interface, error) {
return c.clientGetter.Addons(namespace).Watch(opts) return c.clientGetter.Addons(namespace).Watch(context.TODO(), opts)
} }
func (c *addonController) Patch(namespace, name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Addon, err error) { func (c *addonController) Patch(namespace, name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Addon, err error) {
return c.clientGetter.Addons(namespace).Patch(name, pt, data, subresources...) return c.clientGetter.Addons(namespace).Patch(context.TODO(), name, pt, data, metav1.PatchOptions{}, subresources...)
} }
type addonCache struct { type addonCache struct {
...@@ -233,6 +236,7 @@ func (c *addonCache) GetByIndex(indexName, key string) (result []*v1.Addon, err ...@@ -233,6 +236,7 @@ func (c *addonCache) GetByIndex(indexName, key string) (result []*v1.Addon, err
if err != nil { if err != nil {
return nil, err return nil, err
} }
result = make([]*v1.Addon, 0, len(objs))
for _, obj := range objs { for _, obj := range objs {
result = append(result, obj.(*v1.Addon)) result = append(result, obj.(*v1.Addon))
} }
......
...@@ -19,6 +19,7 @@ limitations under the License. ...@@ -19,6 +19,7 @@ limitations under the License.
package v1 package v1
import ( import (
"context"
time "time" time "time"
k3scattleiov1 "github.com/rancher/k3s/pkg/apis/k3s.cattle.io/v1" k3scattleiov1 "github.com/rancher/k3s/pkg/apis/k3s.cattle.io/v1"
...@@ -61,13 +62,13 @@ func NewFilteredAddonInformer(client versioned.Interface, namespace string, resy ...@@ -61,13 +62,13 @@ func NewFilteredAddonInformer(client versioned.Interface, namespace string, resy
if tweakListOptions != nil { if tweakListOptions != nil {
tweakListOptions(&options) tweakListOptions(&options)
} }
return client.K3sV1().Addons(namespace).List(options) return client.K3sV1().Addons(namespace).List(context.TODO(), options)
}, },
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil { if tweakListOptions != nil {
tweakListOptions(&options) tweakListOptions(&options)
} }
return client.K3sV1().Addons(namespace).Watch(options) return client.K3sV1().Addons(namespace).Watch(context.TODO(), options)
}, },
}, },
&k3scattleiov1.Addon{}, &k3scattleiov1.Addon{},
......
...@@ -187,7 +187,7 @@ func (h *handler) updateService(svc *core.Service) (runtime.Object, error) { ...@@ -187,7 +187,7 @@ func (h *handler) updateService(svc *core.Service) (runtime.Object, error) {
} }
logrus.Debugf("Setting service loadbalancer %s/%s to IPs %v", svc.Namespace, svc.Name, expectedIPs) logrus.Debugf("Setting service loadbalancer %s/%s to IPs %v", svc.Namespace, svc.Name, expectedIPs)
return h.services.Services(svc.Namespace).UpdateStatus(svc) return h.services.Services(svc.Namespace).UpdateStatus(context.TODO(), svc, meta.UpdateOptions{})
} }
func serviceIPs(svc *core.Service) []string { func serviceIPs(svc *core.Service) []string {
...@@ -391,7 +391,7 @@ func (h *handler) newDaemonSet(svc *core.Service) (*apps.DaemonSet, error) { ...@@ -391,7 +391,7 @@ func (h *handler) newDaemonSet(svc *core.Service) (*apps.DaemonSet, error) {
} }
func (h *handler) updateDaemonSets() error { func (h *handler) updateDaemonSets() error {
daemonsets, err := h.daemonsets.DaemonSets("").List(meta.ListOptions{ daemonsets, err := h.daemonsets.DaemonSets("").List(context.TODO(), meta.ListOptions{
LabelSelector: nodeSelectorLabel + "=false", LabelSelector: nodeSelectorLabel + "=false",
}) })
if err != nil { if err != nil {
...@@ -403,7 +403,7 @@ func (h *handler) updateDaemonSets() error { ...@@ -403,7 +403,7 @@ func (h *handler) updateDaemonSets() error {
daemonsetNodeLabel: "true", daemonsetNodeLabel: "true",
} }
ds.Labels[nodeSelectorLabel] = "true" ds.Labels[nodeSelectorLabel] = "true"
if _, err := h.daemonsets.DaemonSets(ds.Namespace).Update(&ds); err != nil { if _, err := h.daemonsets.DaemonSets(ds.Namespace).Update(context.TODO(), &ds, meta.UpdateOptions{}); err != nil {
return err return err
} }
...@@ -420,5 +420,5 @@ func (h *handler) deleteOldDeployments(svc *core.Service) error { ...@@ -420,5 +420,5 @@ func (h *handler) deleteOldDeployments(svc *core.Service) error {
} }
return err return err
} }
return h.deployments.Deployments(svc.Namespace).Delete(name, &meta.DeleteOptions{}) return h.deployments.Deployments(svc.Namespace).Delete(context.TODO(), name, meta.DeleteOptions{})
} }
...@@ -13,8 +13,8 @@ mkdir -p $artifacts ...@@ -13,8 +13,8 @@ mkdir -p $artifacts
# --- # ---
[ "$ARCH" = 'arm' ] && \ [ "$ARCH" != 'amd64' ] && \
early-exit "Skipping sonobuoy, images not available for $ARCH." early-exit "Skipping remaining tests, images not available for $ARCH."
E2E_OUTPUT=$artifacts test-run-sonobuoy E2E_OUTPUT=$artifacts test-run-sonobuoy
...@@ -23,9 +23,6 @@ E2E_OUTPUT=$artifacts test-run-sonobuoy ...@@ -23,9 +23,6 @@ E2E_OUTPUT=$artifacts test-run-sonobuoy
[ "$DRONE_BUILD_EVENT" = 'tag' ] && \ [ "$DRONE_BUILD_EVENT" = 'tag' ] && \
early-exit 'Skipping remaining tests on tag.' early-exit 'Skipping remaining tests on tag.'
[ "$ARCH" != 'amd64' ] && \
early-exit "Skipping remaining tests, images not available for $ARCH."
# --- # ---
test-run-sonobuoy mysql test-run-sonobuoy mysql
......
...@@ -92,7 +92,7 @@ func (client AccountsClient) CheckNameAvailabilityPreparer(ctx context.Context, ...@@ -92,7 +92,7 @@ func (client AccountsClient) CheckNameAvailabilityPreparer(ctx context.Context,
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -203,7 +203,7 @@ func (client AccountsClient) CreatePreparer(ctx context.Context, resourceGroupNa ...@@ -203,7 +203,7 @@ func (client AccountsClient) CreatePreparer(ctx context.Context, resourceGroupNa
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -303,7 +303,7 @@ func (client AccountsClient) DeletePreparer(ctx context.Context, resourceGroupNa ...@@ -303,7 +303,7 @@ func (client AccountsClient) DeletePreparer(ctx context.Context, resourceGroupNa
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -390,7 +390,7 @@ func (client AccountsClient) FailoverPreparer(ctx context.Context, resourceGroup ...@@ -390,7 +390,7 @@ func (client AccountsClient) FailoverPreparer(ctx context.Context, resourceGroup
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -490,7 +490,7 @@ func (client AccountsClient) GetPropertiesPreparer(ctx context.Context, resource ...@@ -490,7 +490,7 @@ func (client AccountsClient) GetPropertiesPreparer(ctx context.Context, resource
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -573,7 +573,7 @@ func (client AccountsClient) ListPreparer(ctx context.Context) (*http.Request, e ...@@ -573,7 +573,7 @@ func (client AccountsClient) ListPreparer(ctx context.Context) (*http.Request, e
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -705,7 +705,7 @@ func (client AccountsClient) ListAccountSASPreparer(ctx context.Context, resourc ...@@ -705,7 +705,7 @@ func (client AccountsClient) ListAccountSASPreparer(ctx context.Context, resourc
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -794,7 +794,7 @@ func (client AccountsClient) ListByResourceGroupPreparer(ctx context.Context, re ...@@ -794,7 +794,7 @@ func (client AccountsClient) ListByResourceGroupPreparer(ctx context.Context, re
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -887,7 +887,7 @@ func (client AccountsClient) ListKeysPreparer(ctx context.Context, resourceGroup ...@@ -887,7 +887,7 @@ func (client AccountsClient) ListKeysPreparer(ctx context.Context, resourceGroup
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -987,7 +987,7 @@ func (client AccountsClient) ListServiceSASPreparer(ctx context.Context, resourc ...@@ -987,7 +987,7 @@ func (client AccountsClient) ListServiceSASPreparer(ctx context.Context, resourc
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -1084,7 +1084,7 @@ func (client AccountsClient) RegenerateKeyPreparer(ctx context.Context, resource ...@@ -1084,7 +1084,7 @@ func (client AccountsClient) RegenerateKeyPreparer(ctx context.Context, resource
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -1178,7 +1178,7 @@ func (client AccountsClient) RevokeUserDelegationKeysPreparer(ctx context.Contex ...@@ -1178,7 +1178,7 @@ func (client AccountsClient) RevokeUserDelegationKeysPreparer(ctx context.Contex
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -1275,7 +1275,7 @@ func (client AccountsClient) UpdatePreparer(ctx context.Context, resourceGroupNa ...@@ -1275,7 +1275,7 @@ func (client AccountsClient) UpdatePreparer(ctx context.Context, resourceGroupNa
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
......
...@@ -111,7 +111,7 @@ func (client BlobContainersClient) ClearLegalHoldPreparer(ctx context.Context, r ...@@ -111,7 +111,7 @@ func (client BlobContainersClient) ClearLegalHoldPreparer(ctx context.Context, r
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -223,7 +223,7 @@ func (client BlobContainersClient) CreatePreparer(ctx context.Context, resourceG ...@@ -223,7 +223,7 @@ func (client BlobContainersClient) CreatePreparer(ctx context.Context, resourceG
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -335,7 +335,7 @@ func (client BlobContainersClient) CreateOrUpdateImmutabilityPolicyPreparer(ctx ...@@ -335,7 +335,7 @@ func (client BlobContainersClient) CreateOrUpdateImmutabilityPolicyPreparer(ctx
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -443,7 +443,7 @@ func (client BlobContainersClient) DeletePreparer(ctx context.Context, resourceG ...@@ -443,7 +443,7 @@ func (client BlobContainersClient) DeletePreparer(ctx context.Context, resourceG
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -548,7 +548,7 @@ func (client BlobContainersClient) DeleteImmutabilityPolicyPreparer(ctx context. ...@@ -548,7 +548,7 @@ func (client BlobContainersClient) DeleteImmutabilityPolicyPreparer(ctx context.
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -658,7 +658,7 @@ func (client BlobContainersClient) ExtendImmutabilityPolicyPreparer(ctx context. ...@@ -658,7 +658,7 @@ func (client BlobContainersClient) ExtendImmutabilityPolicyPreparer(ctx context.
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -763,7 +763,7 @@ func (client BlobContainersClient) GetPreparer(ctx context.Context, resourceGrou ...@@ -763,7 +763,7 @@ func (client BlobContainersClient) GetPreparer(ctx context.Context, resourceGrou
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -867,7 +867,7 @@ func (client BlobContainersClient) GetImmutabilityPolicyPreparer(ctx context.Con ...@@ -867,7 +867,7 @@ func (client BlobContainersClient) GetImmutabilityPolicyPreparer(ctx context.Con
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -972,7 +972,7 @@ func (client BlobContainersClient) LeasePreparer(ctx context.Context, resourceGr ...@@ -972,7 +972,7 @@ func (client BlobContainersClient) LeasePreparer(ctx context.Context, resourceGr
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -1017,10 +1017,9 @@ func (client BlobContainersClient) LeaseResponder(resp *http.Response) (result L ...@@ -1017,10 +1017,9 @@ func (client BlobContainersClient) LeaseResponder(resp *http.Response) (result L
// insensitive. // insensitive.
// accountName - the name of the storage account within the specified resource group. Storage account names // accountName - the name of the storage account within the specified resource group. Storage account names
// must be between 3 and 24 characters in length and use numbers and lower-case letters only. // must be between 3 and 24 characters in length and use numbers and lower-case letters only.
// skipToken - optional. Continuation token for the list operation.
// maxpagesize - optional. Specified maximum number of containers that can be included in the list. // maxpagesize - optional. Specified maximum number of containers that can be included in the list.
// filter - optional. When specified, only container names starting with the filter will be listed. // filter - optional. When specified, only container names starting with the filter will be listed.
func (client BlobContainersClient) List(ctx context.Context, resourceGroupName string, accountName string, skipToken string, maxpagesize string, filter string) (result ListContainerItemsPage, err error) { func (client BlobContainersClient) List(ctx context.Context, resourceGroupName string, accountName string, maxpagesize string, filter string) (result ListContainerItemsPage, err error) {
if tracing.IsEnabled() { if tracing.IsEnabled() {
ctx = tracing.StartSpan(ctx, fqdn+"/BlobContainersClient.List") ctx = tracing.StartSpan(ctx, fqdn+"/BlobContainersClient.List")
defer func() { defer func() {
...@@ -1045,7 +1044,7 @@ func (client BlobContainersClient) List(ctx context.Context, resourceGroupName s ...@@ -1045,7 +1044,7 @@ func (client BlobContainersClient) List(ctx context.Context, resourceGroupName s
} }
result.fn = client.listNextResults result.fn = client.listNextResults
req, err := client.ListPreparer(ctx, resourceGroupName, accountName, skipToken, maxpagesize, filter) req, err := client.ListPreparer(ctx, resourceGroupName, accountName, maxpagesize, filter)
if err != nil { if err != nil {
err = autorest.NewErrorWithError(err, "storage.BlobContainersClient", "List", nil, "Failure preparing request") err = autorest.NewErrorWithError(err, "storage.BlobContainersClient", "List", nil, "Failure preparing request")
return return
...@@ -1067,20 +1066,17 @@ func (client BlobContainersClient) List(ctx context.Context, resourceGroupName s ...@@ -1067,20 +1066,17 @@ func (client BlobContainersClient) List(ctx context.Context, resourceGroupName s
} }
// ListPreparer prepares the List request. // ListPreparer prepares the List request.
func (client BlobContainersClient) ListPreparer(ctx context.Context, resourceGroupName string, accountName string, skipToken string, maxpagesize string, filter string) (*http.Request, error) { func (client BlobContainersClient) ListPreparer(ctx context.Context, resourceGroupName string, accountName string, maxpagesize string, filter string) (*http.Request, error) {
pathParameters := map[string]interface{}{ pathParameters := map[string]interface{}{
"accountName": autorest.Encode("path", accountName), "accountName": autorest.Encode("path", accountName),
"resourceGroupName": autorest.Encode("path", resourceGroupName), "resourceGroupName": autorest.Encode("path", resourceGroupName),
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
if len(skipToken) > 0 {
queryParameters["$skipToken"] = autorest.Encode("query", skipToken)
}
if len(maxpagesize) > 0 { if len(maxpagesize) > 0 {
queryParameters["$maxpagesize"] = autorest.Encode("query", maxpagesize) queryParameters["$maxpagesize"] = autorest.Encode("query", maxpagesize)
} }
...@@ -1138,7 +1134,7 @@ func (client BlobContainersClient) listNextResults(ctx context.Context, lastResu ...@@ -1138,7 +1134,7 @@ func (client BlobContainersClient) listNextResults(ctx context.Context, lastResu
} }
// ListComplete enumerates all values, automatically crossing page boundaries as required. // ListComplete enumerates all values, automatically crossing page boundaries as required.
func (client BlobContainersClient) ListComplete(ctx context.Context, resourceGroupName string, accountName string, skipToken string, maxpagesize string, filter string) (result ListContainerItemsIterator, err error) { func (client BlobContainersClient) ListComplete(ctx context.Context, resourceGroupName string, accountName string, maxpagesize string, filter string) (result ListContainerItemsIterator, err error) {
if tracing.IsEnabled() { if tracing.IsEnabled() {
ctx = tracing.StartSpan(ctx, fqdn+"/BlobContainersClient.List") ctx = tracing.StartSpan(ctx, fqdn+"/BlobContainersClient.List")
defer func() { defer func() {
...@@ -1149,7 +1145,7 @@ func (client BlobContainersClient) ListComplete(ctx context.Context, resourceGro ...@@ -1149,7 +1145,7 @@ func (client BlobContainersClient) ListComplete(ctx context.Context, resourceGro
tracing.EndSpan(ctx, sc, err) tracing.EndSpan(ctx, sc, err)
}() }()
} }
result.page, err = client.List(ctx, resourceGroupName, accountName, skipToken, maxpagesize, filter) result.page, err = client.List(ctx, resourceGroupName, accountName, maxpagesize, filter)
return return
} }
...@@ -1223,7 +1219,7 @@ func (client BlobContainersClient) LockImmutabilityPolicyPreparer(ctx context.Co ...@@ -1223,7 +1219,7 @@ func (client BlobContainersClient) LockImmutabilityPolicyPreparer(ctx context.Co
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -1327,7 +1323,7 @@ func (client BlobContainersClient) SetLegalHoldPreparer(ctx context.Context, res ...@@ -1327,7 +1323,7 @@ func (client BlobContainersClient) SetLegalHoldPreparer(ctx context.Context, res
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -1431,7 +1427,7 @@ func (client BlobContainersClient) UpdatePreparer(ctx context.Context, resourceG ...@@ -1431,7 +1427,7 @@ func (client BlobContainersClient) UpdatePreparer(ctx context.Context, resourceG
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
......
...@@ -102,7 +102,7 @@ func (client BlobServicesClient) GetServicePropertiesPreparer(ctx context.Contex ...@@ -102,7 +102,7 @@ func (client BlobServicesClient) GetServicePropertiesPreparer(ctx context.Contex
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -194,7 +194,7 @@ func (client BlobServicesClient) ListPreparer(ctx context.Context, resourceGroup ...@@ -194,7 +194,7 @@ func (client BlobServicesClient) ListPreparer(ctx context.Context, resourceGroup
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -299,7 +299,7 @@ func (client BlobServicesClient) SetServicePropertiesPreparer(ctx context.Contex ...@@ -299,7 +299,7 @@ func (client BlobServicesClient) SetServicePropertiesPreparer(ctx context.Contex
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
......
// Package storage implements the Azure ARM Storage service API version 2019-04-01. // Package storage implements the Azure ARM Storage service API version 2019-06-01.
// //
// The Azure Storage Management API. // The Azure Storage Management API.
package storage package storage
......
...@@ -102,7 +102,7 @@ func (client FileServicesClient) GetServicePropertiesPreparer(ctx context.Contex ...@@ -102,7 +102,7 @@ func (client FileServicesClient) GetServicePropertiesPreparer(ctx context.Contex
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -194,7 +194,7 @@ func (client FileServicesClient) ListPreparer(ctx context.Context, resourceGroup ...@@ -194,7 +194,7 @@ func (client FileServicesClient) ListPreparer(ctx context.Context, resourceGroup
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -290,7 +290,7 @@ func (client FileServicesClient) SetServicePropertiesPreparer(ctx context.Contex ...@@ -290,7 +290,7 @@ func (client FileServicesClient) SetServicePropertiesPreparer(ctx context.Contex
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
......
...@@ -116,7 +116,7 @@ func (client FileSharesClient) CreatePreparer(ctx context.Context, resourceGroup ...@@ -116,7 +116,7 @@ func (client FileSharesClient) CreatePreparer(ctx context.Context, resourceGroup
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -217,7 +217,7 @@ func (client FileSharesClient) DeletePreparer(ctx context.Context, resourceGroup ...@@ -217,7 +217,7 @@ func (client FileSharesClient) DeletePreparer(ctx context.Context, resourceGroup
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -315,7 +315,7 @@ func (client FileSharesClient) GetPreparer(ctx context.Context, resourceGroupNam ...@@ -315,7 +315,7 @@ func (client FileSharesClient) GetPreparer(ctx context.Context, resourceGroupNam
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -354,10 +354,9 @@ func (client FileSharesClient) GetResponder(resp *http.Response) (result FileSha ...@@ -354,10 +354,9 @@ func (client FileSharesClient) GetResponder(resp *http.Response) (result FileSha
// insensitive. // insensitive.
// accountName - the name of the storage account within the specified resource group. Storage account names // accountName - the name of the storage account within the specified resource group. Storage account names
// must be between 3 and 24 characters in length and use numbers and lower-case letters only. // must be between 3 and 24 characters in length and use numbers and lower-case letters only.
// skipToken - optional. Continuation token for the list operation.
// maxpagesize - optional. Specified maximum number of shares that can be included in the list. // maxpagesize - optional. Specified maximum number of shares that can be included in the list.
// filter - optional. When specified, only share names starting with the filter will be listed. // filter - optional. When specified, only share names starting with the filter will be listed.
func (client FileSharesClient) List(ctx context.Context, resourceGroupName string, accountName string, skipToken string, maxpagesize string, filter string) (result FileShareItemsPage, err error) { func (client FileSharesClient) List(ctx context.Context, resourceGroupName string, accountName string, maxpagesize string, filter string) (result FileShareItemsPage, err error) {
if tracing.IsEnabled() { if tracing.IsEnabled() {
ctx = tracing.StartSpan(ctx, fqdn+"/FileSharesClient.List") ctx = tracing.StartSpan(ctx, fqdn+"/FileSharesClient.List")
defer func() { defer func() {
...@@ -382,7 +381,7 @@ func (client FileSharesClient) List(ctx context.Context, resourceGroupName strin ...@@ -382,7 +381,7 @@ func (client FileSharesClient) List(ctx context.Context, resourceGroupName strin
} }
result.fn = client.listNextResults result.fn = client.listNextResults
req, err := client.ListPreparer(ctx, resourceGroupName, accountName, skipToken, maxpagesize, filter) req, err := client.ListPreparer(ctx, resourceGroupName, accountName, maxpagesize, filter)
if err != nil { if err != nil {
err = autorest.NewErrorWithError(err, "storage.FileSharesClient", "List", nil, "Failure preparing request") err = autorest.NewErrorWithError(err, "storage.FileSharesClient", "List", nil, "Failure preparing request")
return return
...@@ -404,20 +403,17 @@ func (client FileSharesClient) List(ctx context.Context, resourceGroupName strin ...@@ -404,20 +403,17 @@ func (client FileSharesClient) List(ctx context.Context, resourceGroupName strin
} }
// ListPreparer prepares the List request. // ListPreparer prepares the List request.
func (client FileSharesClient) ListPreparer(ctx context.Context, resourceGroupName string, accountName string, skipToken string, maxpagesize string, filter string) (*http.Request, error) { func (client FileSharesClient) ListPreparer(ctx context.Context, resourceGroupName string, accountName string, maxpagesize string, filter string) (*http.Request, error) {
pathParameters := map[string]interface{}{ pathParameters := map[string]interface{}{
"accountName": autorest.Encode("path", accountName), "accountName": autorest.Encode("path", accountName),
"resourceGroupName": autorest.Encode("path", resourceGroupName), "resourceGroupName": autorest.Encode("path", resourceGroupName),
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
if len(skipToken) > 0 {
queryParameters["$skipToken"] = autorest.Encode("query", skipToken)
}
if len(maxpagesize) > 0 { if len(maxpagesize) > 0 {
queryParameters["$maxpagesize"] = autorest.Encode("query", maxpagesize) queryParameters["$maxpagesize"] = autorest.Encode("query", maxpagesize)
} }
...@@ -475,7 +471,7 @@ func (client FileSharesClient) listNextResults(ctx context.Context, lastResults ...@@ -475,7 +471,7 @@ func (client FileSharesClient) listNextResults(ctx context.Context, lastResults
} }
// ListComplete enumerates all values, automatically crossing page boundaries as required. // ListComplete enumerates all values, automatically crossing page boundaries as required.
func (client FileSharesClient) ListComplete(ctx context.Context, resourceGroupName string, accountName string, skipToken string, maxpagesize string, filter string) (result FileShareItemsIterator, err error) { func (client FileSharesClient) ListComplete(ctx context.Context, resourceGroupName string, accountName string, maxpagesize string, filter string) (result FileShareItemsIterator, err error) {
if tracing.IsEnabled() { if tracing.IsEnabled() {
ctx = tracing.StartSpan(ctx, fqdn+"/FileSharesClient.List") ctx = tracing.StartSpan(ctx, fqdn+"/FileSharesClient.List")
defer func() { defer func() {
...@@ -486,7 +482,7 @@ func (client FileSharesClient) ListComplete(ctx context.Context, resourceGroupNa ...@@ -486,7 +482,7 @@ func (client FileSharesClient) ListComplete(ctx context.Context, resourceGroupNa
tracing.EndSpan(ctx, sc, err) tracing.EndSpan(ctx, sc, err)
}() }()
} }
result.page, err = client.List(ctx, resourceGroupName, accountName, skipToken, maxpagesize, filter) result.page, err = client.List(ctx, resourceGroupName, accountName, maxpagesize, filter)
return return
} }
...@@ -558,7 +554,7 @@ func (client FileSharesClient) UpdatePreparer(ctx context.Context, resourceGroup ...@@ -558,7 +554,7 @@ func (client FileSharesClient) UpdatePreparer(ctx context.Context, resourceGroup
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
......
...@@ -107,7 +107,7 @@ func (client ManagementPoliciesClient) CreateOrUpdatePreparer(ctx context.Contex ...@@ -107,7 +107,7 @@ func (client ManagementPoliciesClient) CreateOrUpdatePreparer(ctx context.Contex
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -202,7 +202,7 @@ func (client ManagementPoliciesClient) DeletePreparer(ctx context.Context, resou ...@@ -202,7 +202,7 @@ func (client ManagementPoliciesClient) DeletePreparer(ctx context.Context, resou
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
...@@ -294,7 +294,7 @@ func (client ManagementPoliciesClient) GetPreparer(ctx context.Context, resource ...@@ -294,7 +294,7 @@ func (client ManagementPoliciesClient) GetPreparer(ctx context.Context, resource
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
......
...@@ -75,7 +75,7 @@ func (client OperationsClient) List(ctx context.Context) (result OperationListRe ...@@ -75,7 +75,7 @@ func (client OperationsClient) List(ctx context.Context) (result OperationListRe
// ListPreparer prepares the List request. // ListPreparer prepares the List request.
func (client OperationsClient) ListPreparer(ctx context.Context) (*http.Request, error) { func (client OperationsClient) ListPreparer(ctx context.Context) (*http.Request, error) {
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
......
package storage
// Copyright (c) Microsoft and contributors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
import (
"context"
"github.com/Azure/go-autorest/autorest"
"github.com/Azure/go-autorest/autorest/azure"
"github.com/Azure/go-autorest/autorest/validation"
"github.com/Azure/go-autorest/tracing"
"net/http"
)
// PrivateLinkResourcesClient is the the Azure Storage Management API.
type PrivateLinkResourcesClient struct {
BaseClient
}
// NewPrivateLinkResourcesClient creates an instance of the PrivateLinkResourcesClient client.
func NewPrivateLinkResourcesClient(subscriptionID string) PrivateLinkResourcesClient {
return NewPrivateLinkResourcesClientWithBaseURI(DefaultBaseURI, subscriptionID)
}
// NewPrivateLinkResourcesClientWithBaseURI creates an instance of the PrivateLinkResourcesClient client.
func NewPrivateLinkResourcesClientWithBaseURI(baseURI string, subscriptionID string) PrivateLinkResourcesClient {
return PrivateLinkResourcesClient{NewWithBaseURI(baseURI, subscriptionID)}
}
// ListByStorageAccount gets the private link resources that need to be created for a storage account.
// Parameters:
// resourceGroupName - the name of the resource group within the user's subscription. The name is case
// insensitive.
// accountName - the name of the storage account within the specified resource group. Storage account names
// must be between 3 and 24 characters in length and use numbers and lower-case letters only.
func (client PrivateLinkResourcesClient) ListByStorageAccount(ctx context.Context, resourceGroupName string, accountName string) (result PrivateLinkResourceListResult, err error) {
if tracing.IsEnabled() {
ctx = tracing.StartSpan(ctx, fqdn+"/PrivateLinkResourcesClient.ListByStorageAccount")
defer func() {
sc := -1
if result.Response.Response != nil {
sc = result.Response.Response.StatusCode
}
tracing.EndSpan(ctx, sc, err)
}()
}
if err := validation.Validate([]validation.Validation{
{TargetValue: resourceGroupName,
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
{TargetValue: accountName,
Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil},
{Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}},
{TargetValue: client.SubscriptionID,
Constraints: []validation.Constraint{{Target: "client.SubscriptionID", Name: validation.MinLength, Rule: 1, Chain: nil}}}}); err != nil {
return result, validation.NewError("storage.PrivateLinkResourcesClient", "ListByStorageAccount", err.Error())
}
req, err := client.ListByStorageAccountPreparer(ctx, resourceGroupName, accountName)
if err != nil {
err = autorest.NewErrorWithError(err, "storage.PrivateLinkResourcesClient", "ListByStorageAccount", nil, "Failure preparing request")
return
}
resp, err := client.ListByStorageAccountSender(req)
if err != nil {
result.Response = autorest.Response{Response: resp}
err = autorest.NewErrorWithError(err, "storage.PrivateLinkResourcesClient", "ListByStorageAccount", resp, "Failure sending request")
return
}
result, err = client.ListByStorageAccountResponder(resp)
if err != nil {
err = autorest.NewErrorWithError(err, "storage.PrivateLinkResourcesClient", "ListByStorageAccount", resp, "Failure responding to request")
}
return
}
// ListByStorageAccountPreparer prepares the ListByStorageAccount request.
func (client PrivateLinkResourcesClient) ListByStorageAccountPreparer(ctx context.Context, resourceGroupName string, accountName string) (*http.Request, error) {
pathParameters := map[string]interface{}{
"accountName": autorest.Encode("path", accountName),
"resourceGroupName": autorest.Encode("path", resourceGroupName),
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
}
const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{
"api-version": APIVersion,
}
preparer := autorest.CreatePreparer(
autorest.AsGet(),
autorest.WithBaseURL(client.BaseURI),
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/privateLinkResources", pathParameters),
autorest.WithQueryParameters(queryParameters))
return preparer.Prepare((&http.Request{}).WithContext(ctx))
}
// ListByStorageAccountSender sends the ListByStorageAccount request. The method will close the
// http.Response Body if it receives an error.
func (client PrivateLinkResourcesClient) ListByStorageAccountSender(req *http.Request) (*http.Response, error) {
sd := autorest.GetSendDecorators(req.Context(), azure.DoRetryWithRegistration(client.Client))
return autorest.SendWithSender(client, req, sd...)
}
// ListByStorageAccountResponder handles the response to the ListByStorageAccount request. The method always
// closes the http.Response Body.
func (client PrivateLinkResourcesClient) ListByStorageAccountResponder(resp *http.Response) (result PrivateLinkResourceListResult, err error) {
err = autorest.Respond(
resp,
client.ByInspecting(),
azure.WithErrorUnlessStatusCode(http.StatusOK),
autorest.ByUnmarshallingJSON(&result),
autorest.ByClosing())
result.Response = autorest.Response{Response: resp}
return
}
...@@ -86,7 +86,7 @@ func (client SkusClient) ListPreparer(ctx context.Context) (*http.Request, error ...@@ -86,7 +86,7 @@ func (client SkusClient) ListPreparer(ctx context.Context) (*http.Request, error
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
......
...@@ -89,7 +89,7 @@ func (client UsagesClient) ListByLocationPreparer(ctx context.Context, location ...@@ -89,7 +89,7 @@ func (client UsagesClient) ListByLocationPreparer(ctx context.Context, location
"subscriptionId": autorest.Encode("path", client.SubscriptionID), "subscriptionId": autorest.Encode("path", client.SubscriptionID),
} }
const APIVersion = "2019-04-01" const APIVersion = "2019-06-01"
queryParameters := map[string]interface{}{ queryParameters := map[string]interface{}{
"api-version": APIVersion, "api-version": APIVersion,
} }
......
...@@ -21,7 +21,7 @@ import "github.com/Azure/azure-sdk-for-go/version" ...@@ -21,7 +21,7 @@ import "github.com/Azure/azure-sdk-for-go/version"
// UserAgent returns the UserAgent string to use when sending http.Requests. // UserAgent returns the UserAgent string to use when sending http.Requests.
func UserAgent() string { func UserAgent() string {
return "Azure-SDK-For-Go/" + version.Number + " storage/2019-04-01" return "Azure-SDK-For-Go/" + version.Number + " storage/2019-06-01"
} }
// Version returns the semantic version (see http://semver.org) of the client. // Version returns the semantic version (see http://semver.org) of the client.
......
module github.com/Azure/go-autorest/autorest/mocks
go 1.12
package mocks
// Copyright 2017 Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import (
"fmt"
"io"
"net/http"
"time"
)
const (
// TestAuthorizationHeader is a faux HTTP Authorization header value
TestAuthorizationHeader = "BEARER SECRETTOKEN"
// TestBadURL is a malformed URL
TestBadURL = " "
// TestDelay is the Retry-After delay used in tests.
TestDelay = 0 * time.Second
// TestHeader is the header used in tests.
TestHeader = "x-test-header"
// TestURL is the URL used in tests.
TestURL = "https://microsoft.com/a/b/c/"
// TestAzureAsyncURL is a URL used in Azure asynchronous tests
TestAzureAsyncURL = "https://microsoft.com/a/b/c/async"
// TestLocationURL is a URL used in Azure asynchronous tests
TestLocationURL = "https://microsoft.com/a/b/c/location"
)
const (
headerLocation = "Location"
headerRetryAfter = "Retry-After"
)
// NewRequest instantiates a new request.
func NewRequest() *http.Request {
return NewRequestWithContent("")
}
// NewRequestWithContent instantiates a new request using the passed string for the body content.
func NewRequestWithContent(c string) *http.Request {
r, _ := http.NewRequest("GET", "https://microsoft.com/a/b/c/", NewBody(c))
return r
}
// NewRequestWithCloseBody instantiates a new request.
func NewRequestWithCloseBody() *http.Request {
return NewRequestWithCloseBodyContent("request body")
}
// NewRequestWithCloseBodyContent instantiates a new request using the passed string for the body content.
func NewRequestWithCloseBodyContent(c string) *http.Request {
r, _ := http.NewRequest("GET", "https://microsoft.com/a/b/c/", NewBodyClose(c))
return r
}
// NewRequestForURL instantiates a new request using the passed URL.
func NewRequestForURL(u string) *http.Request {
return NewRequestWithParams("GET", u, NewBody(""))
}
// NewRequestWithParams instantiates a new request using the provided parameters.
func NewRequestWithParams(method, u string, body io.Reader) *http.Request {
r, err := http.NewRequest(method, u, body)
if err != nil {
panic(fmt.Sprintf("mocks: ERROR (%v) parsing testing URL %s", err, u))
}
return r
}
// NewResponse instantiates a new response.
func NewResponse() *http.Response {
return NewResponseWithContent("")
}
// NewResponseWithBytes instantiates a new response with the passed bytes as the body content.
func NewResponseWithBytes(input []byte) *http.Response {
return &http.Response{
Status: "200 OK",
StatusCode: 200,
Proto: "HTTP/1.0",
ProtoMajor: 1,
ProtoMinor: 0,
Body: NewBodyWithBytes(input),
Request: NewRequest(),
}
}
// NewResponseWithContent instantiates a new response with the passed string as the body content.
func NewResponseWithContent(c string) *http.Response {
return &http.Response{
Status: "200 OK",
StatusCode: 200,
Proto: "HTTP/1.0",
ProtoMajor: 1,
ProtoMinor: 0,
Body: NewBody(c),
Request: NewRequest(),
}
}
// NewResponseWithStatus instantiates a new response using the passed string and integer as the
// status and status code.
func NewResponseWithStatus(s string, c int) *http.Response {
resp := NewResponse()
resp.Status = s
resp.StatusCode = c
return resp
}
// NewResponseWithBodyAndStatus instantiates a new response using the specified mock body,
// status and status code
func NewResponseWithBodyAndStatus(body *Body, c int, s string) *http.Response {
resp := NewResponse()
resp.Body = body
resp.ContentLength = body.Length()
resp.Status = s
resp.StatusCode = c
return resp
}
// SetResponseHeader adds a header to the passed response.
func SetResponseHeader(resp *http.Response, h string, v string) {
if resp.Header == nil {
resp.Header = make(http.Header)
}
resp.Header.Set(h, v)
}
// SetResponseHeaderValues adds a header containing all the passed string values.
func SetResponseHeaderValues(resp *http.Response, h string, values []string) {
if resp.Header == nil {
resp.Header = make(http.Header)
}
for _, v := range values {
resp.Header.Add(h, v)
}
}
// SetAcceptedHeaders adds the headers usually associated with a 202 Accepted response.
func SetAcceptedHeaders(resp *http.Response) {
SetLocationHeader(resp, TestURL)
SetRetryHeader(resp, TestDelay)
}
// SetLocationHeader adds the Location header.
func SetLocationHeader(resp *http.Response, location string) {
SetResponseHeader(resp, http.CanonicalHeaderKey(headerLocation), location)
}
// SetRetryHeader adds the Retry-After header.
func SetRetryHeader(resp *http.Response, delay time.Duration) {
SetResponseHeader(resp, http.CanonicalHeaderKey(headerRetryAfter), fmt.Sprintf("%v", delay.Seconds()))
}
/*
Package mocks provides mocks and helpers used in testing.
*/
package mocks
// Copyright 2017 Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import (
"fmt"
"io"
"net/http"
"time"
)
// Body implements acceptable body over a string.
type Body struct {
s string
b []byte
isOpen bool
closeAttempts int
}
// NewBody creates a new instance of Body.
func NewBody(s string) *Body {
return (&Body{s: s}).reset()
}
// NewBodyWithBytes creates a new instance of Body.
func NewBodyWithBytes(b []byte) *Body {
return &Body{
b: b,
isOpen: true,
}
}
// NewBodyClose creates a new instance of Body.
func NewBodyClose(s string) *Body {
return &Body{s: s}
}
// Read reads into the passed byte slice and returns the bytes read.
func (body *Body) Read(b []byte) (n int, err error) {
if !body.IsOpen() {
return 0, fmt.Errorf("ERROR: Body has been closed")
}
if len(body.b) == 0 {
return 0, io.EOF
}
n = copy(b, body.b)
body.b = body.b[n:]
return n, nil
}
// Close closes the body.
func (body *Body) Close() error {
if body.isOpen {
body.isOpen = false
body.closeAttempts++
}
return nil
}
// CloseAttempts returns the number of times Close was called.
func (body *Body) CloseAttempts() int {
return body.closeAttempts
}
// IsOpen returns true if the Body has not been closed, false otherwise.
func (body *Body) IsOpen() bool {
return body.isOpen
}
func (body *Body) reset() *Body {
body.isOpen = true
body.b = []byte(body.s)
return body
}
// Length returns the number of bytes in the body.
func (body *Body) Length() int64 {
if body == nil {
return 0
}
return int64(len(body.b))
}
type response struct {
r *http.Response
e error
d time.Duration
}
// Sender implements a simple null sender.
type Sender struct {
attempts int
responses []response
numResponses int
repeatResponse []int
err error
repeatError int
emitErrorAfter int
}
// NewSender creates a new instance of Sender.
func NewSender() *Sender {
return &Sender{}
}
// Do accepts the passed request and, based on settings, emits a response and possible error.
func (c *Sender) Do(r *http.Request) (resp *http.Response, err error) {
c.attempts++
if len(c.responses) > 0 {
resp = c.responses[0].r
if resp != nil {
if b, ok := resp.Body.(*Body); ok {
b.reset()
}
} else {
err = c.responses[0].e
}
time.Sleep(c.responses[0].d)
c.repeatResponse[0]--
if c.repeatResponse[0] == 0 {
c.responses = c.responses[1:]
c.repeatResponse = c.repeatResponse[1:]
}
} else {
resp = NewResponse()
}
if resp != nil {
resp.Request = r
}
if c.emitErrorAfter > 0 {
c.emitErrorAfter--
} else if c.err != nil {
err = c.err
c.repeatError--
if c.repeatError == 0 {
c.err = nil
}
}
return
}
// AppendResponse adds the passed http.Response to the response stack.
func (c *Sender) AppendResponse(resp *http.Response) {
c.AppendAndRepeatResponse(resp, 1)
}
// AppendResponseWithDelay adds the passed http.Response to the response stack with the specified delay.
func (c *Sender) AppendResponseWithDelay(resp *http.Response, delay time.Duration) {
c.AppendAndRepeatResponseWithDelay(resp, delay, 1)
}
// AppendAndRepeatResponse adds the passed http.Response to the response stack along with a
// repeat count. A negative repeat count will return the response for all remaining calls to Do.
func (c *Sender) AppendAndRepeatResponse(resp *http.Response, repeat int) {
c.appendAndRepeat(response{r: resp}, repeat)
}
// AppendAndRepeatResponseWithDelay adds the passed http.Response to the response stack with the specified
// delay along with a repeat count. A negative repeat count will return the response for all remaining calls to Do.
func (c *Sender) AppendAndRepeatResponseWithDelay(resp *http.Response, delay time.Duration, repeat int) {
c.appendAndRepeat(response{r: resp, d: delay}, repeat)
}
// AppendError adds the passed error to the response stack.
func (c *Sender) AppendError(err error) {
c.AppendAndRepeatError(err, 1)
}
// AppendAndRepeatError adds the passed error to the response stack along with a repeat
// count. A negative repeat count will return the response for all remaining calls to Do.
func (c *Sender) AppendAndRepeatError(err error, repeat int) {
c.appendAndRepeat(response{e: err}, repeat)
}
func (c *Sender) appendAndRepeat(resp response, repeat int) {
if c.responses == nil {
c.responses = []response{resp}
c.repeatResponse = []int{repeat}
} else {
c.responses = append(c.responses, resp)
c.repeatResponse = append(c.repeatResponse, repeat)
}
c.numResponses++
}
// Attempts returns the number of times Do was called.
func (c *Sender) Attempts() int {
return c.attempts
}
// SetError sets the error Do should return.
func (c *Sender) SetError(err error) {
c.SetAndRepeatError(err, 1)
}
// SetAndRepeatError sets the error Do should return and how many calls to Do will return the error.
// A negative repeat value will return the error for all remaining calls to Do.
func (c *Sender) SetAndRepeatError(err error, repeat int) {
c.err = err
c.repeatError = repeat
}
// SetEmitErrorAfter sets the number of attempts to be made before errors are emitted.
func (c *Sender) SetEmitErrorAfter(ea int) {
c.emitErrorAfter = ea
}
// NumResponses returns the number of responses that have been added to the sender.
func (c *Sender) NumResponses() int {
return c.numResponses
}
// T is a simple testing struct.
type T struct {
Name string `json:"name" xml:"Name"`
Age int `json:"age" xml:"Age"`
}
module github.com/Azure/go-autorest/autorest/to module github.com/Azure/go-autorest/autorest/to
go 1.12 go 1.12
require github.com/Azure/go-autorest/autorest v0.9.0
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
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/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
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=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
// +build modhack
package to
// Copyright 2017 Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This file, and the github.com/Azure/go-autorest/autorest import, won't actually become part of
// the resultant binary.
// Necessary for safely adding multi-module repo.
// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository
import _ "github.com/Azure/go-autorest/autorest"
...@@ -2,7 +2,4 @@ module github.com/Azure/go-autorest/autorest/validation ...@@ -2,7 +2,4 @@ module github.com/Azure/go-autorest/autorest/validation
go 1.12 go 1.12
require ( require github.com/stretchr/testify v1.3.0
github.com/Azure/go-autorest/autorest v0.9.0
github.com/stretchr/testify v1.3.0
)
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
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/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
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/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/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/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/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
// +build modhack
package validation
// Copyright 2017 Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This file, and the github.com/Azure/go-autorest/autorest import, won't actually become part of
// the resultant binary.
// Necessary for safely adding multi-module repo.
// See: https://github.com/golang/go/wiki/Modules#is-it-possible-to-add-a-module-to-a-multi-module-repository
import _ "github.com/Azure/go-autorest/autorest"
...@@ -70,7 +70,7 @@ func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTer ...@@ -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
......
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
type Config struct { type Config struct {
Config *aws.Config Config *aws.Config
Handlers request.Handlers Handlers request.Handlers
PartitionID string
Endpoint string Endpoint string
SigningRegion string SigningRegion string
SigningName string SigningName string
......
...@@ -16,11 +16,11 @@ import ( ...@@ -16,11 +16,11 @@ import (
type DefaultRetryer struct { type DefaultRetryer struct {
// Num max Retries is the number of max retries that will be performed. // Num max Retries is the number of max retries that will be performed.
// By default, this is zero. // By default, this is zero.
NumMaxRetries int NumMaxRetries int
// MinRetryDelay is the minimum retry delay after which retry will be performed. // MinRetryDelay is the minimum retry delay after which retry will be performed.
// If not set, the value is 0ns. // If not set, the value is 0ns.
MinRetryDelay time.Duration MinRetryDelay time.Duration
// MinThrottleRetryDelay is the minimum retry delay when throttled. // MinThrottleRetryDelay is the minimum retry delay when throttled.
// If not set, the value is 0ns. // If not set, the value is 0ns.
...@@ -28,7 +28,7 @@ type DefaultRetryer struct { ...@@ -28,7 +28,7 @@ type DefaultRetryer struct {
// MaxRetryDelay is the maximum retry delay before which retry must be performed. // MaxRetryDelay is the maximum retry delay before which retry must be performed.
// If not set, the value is 0ns. // If not set, the value is 0ns.
MaxRetryDelay time.Duration MaxRetryDelay time.Duration
// MaxThrottleDelay is the maximum retry delay when throttled. // MaxThrottleDelay is the maximum retry delay when throttled.
// If not set, the value is 0ns. // If not set, the value is 0ns.
...@@ -140,11 +140,6 @@ func (d DefaultRetryer) ShouldRetry(r *request.Request) bool { ...@@ -140,11 +140,6 @@ func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
if r.Retryable != nil { if r.Retryable != nil {
return *r.Retryable return *r.Retryable
} }
if r.HTTPResponse.StatusCode >= 500 && r.HTTPResponse.StatusCode != 501 {
return true
}
return r.IsErrorRetryable() || r.IsErrorThrottle() return r.IsErrorRetryable() || r.IsErrorThrottle()
} }
......
...@@ -5,6 +5,7 @@ type ClientInfo struct { ...@@ -5,6 +5,7 @@ type ClientInfo struct {
ServiceName string ServiceName string
ServiceID string ServiceID string
APIVersion string APIVersion string
PartitionID string
Endpoint string Endpoint string
SigningName string SigningName string
SigningRegion string SigningRegion string
......
...@@ -161,6 +161,17 @@ type Config struct { ...@@ -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
...@@ -246,6 +257,12 @@ type Config struct { ...@@ -246,6 +257,12 @@ type Config struct {
// Disabling this feature is useful when you want to use local endpoints // Disabling this feature is useful when you want to use local endpoints
// for testing that do not support the modeled host prefix pattern. // for testing that do not support the modeled host prefix pattern.
DisableEndpointHostPrefix *bool DisableEndpointHostPrefix *bool
// STSRegionalEndpoint will enable regional or legacy endpoint resolving
STSRegionalEndpoint endpoints.STSRegionalEndpoint
// S3UsEast1RegionalEndpoint will enable regional or legacy endpoint resolving
S3UsEast1RegionalEndpoint endpoints.S3UsEast1RegionalEndpoint
} }
// NewConfig returns a new Config pointer that can be chained with builder // NewConfig returns a new Config pointer that can be chained with builder
...@@ -379,6 +396,13 @@ func (c *Config) WithS3DisableContentMD5Validation(enable bool) *Config { ...@@ -379,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 {
...@@ -420,6 +444,20 @@ func (c *Config) MergeIn(cfgs ...*Config) { ...@@ -420,6 +444,20 @@ func (c *Config) MergeIn(cfgs ...*Config) {
} }
} }
// WithSTSRegionalEndpoint will set whether or not to use regional endpoint flag
// when resolving the endpoint for a service
func (c *Config) WithSTSRegionalEndpoint(sre endpoints.STSRegionalEndpoint) *Config {
c.STSRegionalEndpoint = sre
return c
}
// WithS3UsEast1RegionalEndpoint will set whether or not to use regional endpoint flag
// when resolving the endpoint for a service
func (c *Config) WithS3UsEast1RegionalEndpoint(sre endpoints.S3UsEast1RegionalEndpoint) *Config {
c.S3UsEast1RegionalEndpoint = sre
return c
}
func mergeInConfig(dst *Config, other *Config) { func mergeInConfig(dst *Config, other *Config) {
if other == nil { if other == nil {
return return
...@@ -493,6 +531,10 @@ func mergeInConfig(dst *Config, other *Config) { ...@@ -493,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
} }
...@@ -520,6 +562,14 @@ func mergeInConfig(dst *Config, other *Config) { ...@@ -520,6 +562,14 @@ func mergeInConfig(dst *Config, other *Config) {
if other.DisableEndpointHostPrefix != nil { if other.DisableEndpointHostPrefix != nil {
dst.DisableEndpointHostPrefix = other.DisableEndpointHostPrefix dst.DisableEndpointHostPrefix = other.DisableEndpointHostPrefix
} }
if other.STSRegionalEndpoint != endpoints.UnsetSTSEndpoint {
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
......
...@@ -161,7 +161,7 @@ func handleSendError(r *request.Request, err error) { ...@@ -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()
......
...@@ -90,6 +90,7 @@ import ( ...@@ -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 ( ...@@ -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
......
...@@ -144,6 +144,13 @@ type AssumeRoleProvider struct { ...@@ -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) { ...@@ -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
......
...@@ -66,7 +66,6 @@ func (rep *Reporter) sendAPICallAttemptMetric(r *request.Request) { ...@@ -66,7 +66,6 @@ func (rep *Reporter) sendAPICallAttemptMetric(r *request.Request) {
XAmzRequestID: aws.String(r.RequestID), XAmzRequestID: aws.String(r.RequestID),
AttemptCount: aws.Int(r.RetryCount + 1),
AttemptLatency: aws.Int(int(now.Sub(r.AttemptTime).Nanoseconds() / int64(time.Millisecond))), AttemptLatency: aws.Int(int(now.Sub(r.AttemptTime).Nanoseconds() / int64(time.Millisecond))),
AccessKey: aws.String(creds.AccessKeyID), AccessKey: aws.String(creds.AccessKeyID),
} }
...@@ -90,7 +89,7 @@ func getMetricException(err awserr.Error) metricException { ...@@ -90,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{
......
...@@ -4,6 +4,7 @@ import ( ...@@ -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 ( ...@@ -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) { ...@@ -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) req := c.NewRequest(op, nil, output)
err := req.Send()
err := req.Send()
return output.Content, err return output.Content, err
} }
...@@ -41,13 +75,8 @@ func (c *EC2Metadata) GetUserData() (string, error) { ...@@ -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) { ...@@ -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) { ...@@ -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.
......
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
"io" "io"
"net/http" "net/http"
"os" "os"
"strconv"
"strings" "strings"
"time" "time"
...@@ -24,9 +25,25 @@ import ( ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 { ...@@ -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) {
......
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)
}
}
...@@ -83,6 +83,7 @@ func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resol ...@@ -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) { ...@@ -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 {
......
...@@ -3,6 +3,7 @@ package endpoints ...@@ -3,6 +3,7 @@ package endpoints
import ( import (
"fmt" "fmt"
"regexp" "regexp"
"strings"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
) )
...@@ -46,6 +47,108 @@ type Options struct { ...@@ -46,6 +47,108 @@ type Options struct {
// //
// This option is ignored if StrictMatching is enabled. // This option is ignored if StrictMatching is enabled.
ResolveUnknownService bool ResolveUnknownService bool
// STS Regional Endpoint flag helps with resolving the STS endpoint
STSRegionalEndpoint STSRegionalEndpoint
// S3 Regional Endpoint flag helps with resolving the S3 endpoint
S3UsEast1RegionalEndpoint S3UsEast1RegionalEndpoint
}
// STSRegionalEndpoint is an enum for the states of the STS Regional Endpoint
// options.
type STSRegionalEndpoint int
func (e STSRegionalEndpoint) String() string {
switch e {
case LegacySTSEndpoint:
return "legacy"
case RegionalSTSEndpoint:
return "regional"
case UnsetSTSEndpoint:
return ""
default:
return "unknown"
}
}
const (
// UnsetSTSEndpoint represents that STS Regional Endpoint flag is not specified.
UnsetSTSEndpoint STSRegionalEndpoint = iota
// LegacySTSEndpoint represents when STS Regional Endpoint flag is specified
// to use legacy endpoints.
LegacySTSEndpoint
// RegionalSTSEndpoint represents when STS Regional Endpoint flag is specified
// to use regional endpoints.
RegionalSTSEndpoint
)
// GetSTSRegionalEndpoint function returns the STSRegionalEndpointFlag based
// on the input string provided in env config or shared config by the user.
//
// `legacy`, `regional` are the only case-insensitive valid strings for
// resolving the STS regional Endpoint flag.
func GetSTSRegionalEndpoint(s string) (STSRegionalEndpoint, error) {
switch {
case strings.EqualFold(s, "legacy"):
return LegacySTSEndpoint, nil
case strings.EqualFold(s, "regional"):
return RegionalSTSEndpoint, nil
default:
return UnsetSTSEndpoint, fmt.Errorf("unable to resolve the value of STSRegionalEndpoint for %v", s)
}
}
// S3UsEast1RegionalEndpoint is an enum for the states of the S3 us-east-1
// Regional Endpoint options.
type S3UsEast1RegionalEndpoint int
func (e S3UsEast1RegionalEndpoint) String() string {
switch e {
case LegacyS3UsEast1Endpoint:
return "legacy"
case RegionalS3UsEast1Endpoint:
return "regional"
case UnsetS3UsEast1Endpoint:
return ""
default:
return "unknown"
}
}
const (
// UnsetS3UsEast1Endpoint represents that S3 Regional Endpoint flag is not
// specified.
UnsetS3UsEast1Endpoint S3UsEast1RegionalEndpoint = iota
// LegacyS3UsEast1Endpoint represents when S3 Regional Endpoint flag is
// specified to use legacy endpoints.
LegacyS3UsEast1Endpoint
// RegionalS3UsEast1Endpoint represents when S3 Regional Endpoint flag is
// specified to use regional endpoints.
RegionalS3UsEast1Endpoint
)
// GetS3UsEast1RegionalEndpoint function returns the S3UsEast1RegionalEndpointFlag based
// on the input string provided in env config or shared config by the user.
//
// `legacy`, `regional` are the only case-insensitive valid strings for
// resolving the S3 regional Endpoint flag.
func GetS3UsEast1RegionalEndpoint(s string) (S3UsEast1RegionalEndpoint, error) {
switch {
case strings.EqualFold(s, "legacy"):
return LegacyS3UsEast1Endpoint, nil
case strings.EqualFold(s, "regional"):
return RegionalS3UsEast1Endpoint, nil
default:
return UnsetS3UsEast1Endpoint,
fmt.Errorf("unable to resolve the value of S3UsEast1RegionalEndpoint for %v", s)
}
} }
// Set combines all of the option functions together. // Set combines all of the option functions together.
...@@ -79,6 +182,12 @@ func ResolveUnknownServiceOption(o *Options) { ...@@ -79,6 +182,12 @@ func ResolveUnknownServiceOption(o *Options) {
o.ResolveUnknownService = true o.ResolveUnknownService = true
} }
// STSRegionalEndpointOption enables the STS endpoint resolver behavior to resolve
// STS endpoint to their regional endpoint, instead of the global endpoint.
func STSRegionalEndpointOption(o *Options) {
o.STSRegionalEndpoint = RegionalSTSEndpoint
}
// A Resolver provides the interface for functionality to resolve endpoints. // A Resolver provides the interface for functionality to resolve endpoints.
// The build in Partition and DefaultResolver return value satisfy this interface. // The build in Partition and DefaultResolver return value satisfy this interface.
type Resolver interface { type Resolver interface {
...@@ -194,7 +303,7 @@ func (p Partition) ID() string { return p.id } ...@@ -194,7 +303,7 @@ func (p Partition) ID() string { return p.id }
// require the provided service and region to be known by the partition. // require the provided service and region to be known by the partition.
// If the endpoint cannot be strictly resolved an error will be returned. This // If the endpoint cannot be strictly resolved an error will be returned. This
// mode is useful to ensure the endpoint resolved is valid. Without // mode is useful to ensure the endpoint resolved is valid. Without
// StrictMatching enabled the endpoint returned my look valid but may not work. // StrictMatching enabled the endpoint returned may look valid but may not work.
// StrictMatching requires the SDK to be updated if you want to take advantage // StrictMatching requires the SDK to be updated if you want to take advantage
// of new regions and services expansions. // of new regions and services expansions.
// //
...@@ -208,7 +317,7 @@ func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) ( ...@@ -208,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,
...@@ -223,7 +332,7 @@ func (p Partition) Regions() map[string]Region { ...@@ -223,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,
...@@ -310,7 +419,7 @@ func (s Service) Regions() map[string]Region { ...@@ -310,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,
...@@ -350,6 +459,9 @@ type ResolvedEndpoint struct { ...@@ -350,6 +459,9 @@ type ResolvedEndpoint struct {
// The endpoint URL // The endpoint URL
URL string URL string
// The endpoint partition
PartitionID string
// The region that should be used for signing requests. // The region that should be used for signing requests.
SigningRegion string SigningRegion string
......
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": {},
},
}
...@@ -75,24 +75,56 @@ func (p partition) canResolveEndpoint(service, region string, strictMatch bool) ...@@ -75,24 +75,56 @@ func (p partition) canResolveEndpoint(service, region string, strictMatch bool)
return p.RegionRegex.MatchString(region) return p.RegionRegex.MatchString(region)
} }
func allowLegacyEmptyRegion(service string) bool {
legacy := map[string]struct{}{
"budgets": {},
"ce": {},
"chime": {},
"cloudfront": {},
"ec2metadata": {},
"iam": {},
"importexport": {},
"organizations": {},
"route53": {},
"sts": {},
"support": {},
"waf": {},
}
_, allowed := legacy[service]
return allowed
}
func (p partition) EndpointFor(service, region string, opts ...func(*Options)) (resolved ResolvedEndpoint, err error) { func (p partition) EndpointFor(service, region string, opts ...func(*Options)) (resolved ResolvedEndpoint, err error) {
var opt Options var opt Options
opt.Set(opts...) opt.Set(opts...)
s, hasService := p.Services[service] s, hasService := p.Services[service]
if !(hasService || opt.ResolveUnknownService) { if len(service) == 0 || !(hasService || opt.ResolveUnknownService) {
// Only return error if the resolver will not fallback to creating // Only return error if the resolver will not fallback to creating
// endpoint based on service endpoint ID passed in. // endpoint based on service endpoint ID passed in.
return resolved, NewUnknownServiceError(p.ID, service, serviceList(p.Services)) return resolved, NewUnknownServiceError(p.ID, service, serviceList(p.Services))
} }
if len(region) == 0 && allowLegacyEmptyRegion(service) && len(s.PartitionEndpoint) != 0 {
region = s.PartitionEndpoint
}
if (service == "sts" && opt.STSRegionalEndpoint != RegionalSTSEndpoint) ||
(service == "s3" && opt.S3UsEast1RegionalEndpoint != RegionalS3UsEast1Endpoint) {
if _, ok := legacyGlobalRegions[service][region]; ok {
region = "aws-global"
}
}
e, hasEndpoint := s.endpointForRegion(region) e, hasEndpoint := s.endpointForRegion(region)
if !hasEndpoint && opt.StrictMatching { if len(region) == 0 || (!hasEndpoint && opt.StrictMatching) {
return resolved, NewUnknownEndpointError(p.ID, service, region, endpointList(s.Endpoints)) return resolved, NewUnknownEndpointError(p.ID, service, region, endpointList(s.Endpoints))
} }
defs := []endpoint{p.Defaults, s.Defaults} defs := []endpoint{p.Defaults, s.Defaults}
return e.resolve(service, region, p.DNSSuffix, defs, opt), nil
return e.resolve(service, p.ID, region, p.DNSSuffix, defs, opt), nil
} }
func serviceList(ss services) []string { func serviceList(ss services) []string {
...@@ -201,7 +233,7 @@ func getByPriority(s []string, p []string, def string) string { ...@@ -201,7 +233,7 @@ func getByPriority(s []string, p []string, def string) string {
return s[0] return s[0]
} }
func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, opts Options) ResolvedEndpoint { func (e endpoint) resolve(service, partitionID, region, dnsSuffix string, defs []endpoint, opts Options) ResolvedEndpoint {
var merged endpoint var merged endpoint
for _, def := range defs { for _, def := range defs {
merged.mergeIn(def) merged.mergeIn(def)
...@@ -209,11 +241,23 @@ func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, op ...@@ -209,11 +241,23 @@ func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, op
merged.mergeIn(e) merged.mergeIn(e)
e = merged e = merged
hostname := e.Hostname signingRegion := e.CredentialScope.Region
if len(signingRegion) == 0 {
signingRegion = region
}
signingName := e.CredentialScope.Service
var signingNameDerived bool
if len(signingName) == 0 {
signingName = service
signingNameDerived = true
}
hostname := e.Hostname
// Offset the hostname for dualstack if enabled // Offset the hostname for dualstack if enabled
if opts.UseDualStack && e.HasDualStack == boxedTrue { if opts.UseDualStack && e.HasDualStack == boxedTrue {
hostname = e.DualStackHostname hostname = e.DualStackHostname
region = signingRegion
} }
u := strings.Replace(hostname, "{service}", service, 1) u := strings.Replace(hostname, "{service}", service, 1)
...@@ -223,20 +267,9 @@ func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, op ...@@ -223,20 +267,9 @@ func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, op
scheme := getEndpointScheme(e.Protocols, opts.DisableSSL) scheme := getEndpointScheme(e.Protocols, opts.DisableSSL)
u = fmt.Sprintf("%s://%s", scheme, u) u = fmt.Sprintf("%s://%s", scheme, u)
signingRegion := e.CredentialScope.Region
if len(signingRegion) == 0 {
signingRegion = region
}
signingName := e.CredentialScope.Service
var signingNameDerived bool
if len(signingName) == 0 {
signingName = service
signingNameDerived = true
}
return ResolvedEndpoint{ return ResolvedEndpoint{
URL: u, URL: u,
PartitionID: partitionID,
SigningRegion: signingRegion, SigningRegion: signingRegion,
SigningName: signingName, SigningName: signingName,
SigningNameDerived: signingNameDerived, SigningNameDerived: signingNameDerived,
......
...@@ -10,6 +10,7 @@ import ( ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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) { ...@@ -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}
}
}
...@@ -36,6 +36,10 @@ const ( ...@@ -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 { ...@@ -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
...@@ -99,8 +104,12 @@ type Operation struct { ...@@ -99,8 +104,12 @@ type Operation struct {
BeforePresignFn func(r *Request) error BeforePresignFn func(r *Request) error
} }
// New returns a new Request pointer for the service API // New returns a new Request pointer for the service API operation and
// operation and parameters. // parameters.
//
// A Retryer should be provided to direct how the request is retried. If
// Retryer is nil, a default no retry value will be used. You can use
// NoOpRetryer in the Client package to disable retry behavior directly.
// //
// Params is any value of input parameters to be the request payload. // Params is any value of input parameters to be the request payload.
// Data is pointer value to an object which the request's response // Data is pointer value to an object which the request's response
...@@ -108,6 +117,10 @@ type Operation struct { ...@@ -108,6 +117,10 @@ type Operation struct {
func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers, func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request { retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request {
if retryer == nil {
retryer = noOpRetryer{}
}
method := operation.HTTPMethod method := operation.HTTPMethod
if method == "" { if method == "" {
method = "POST" method = "POST"
...@@ -287,6 +300,13 @@ func (r *Request) SetReaderBody(reader io.ReadSeeker) { ...@@ -287,6 +300,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
...@@ -411,6 +431,10 @@ func (r *Request) Sign() error { ...@@ -411,6 +431,10 @@ func (r *Request) Sign() 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()
} }
......
...@@ -17,11 +17,13 @@ import ( ...@@ -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
......
...@@ -35,16 +35,47 @@ type Retryer interface { ...@@ -35,16 +35,47 @@ type Retryer interface {
} }
// WithRetryer sets a Retryer value to the given Config returning the Config // WithRetryer sets a Retryer value to the given Config returning the Config
// value for chaining. // value for chaining. The value must not be nil.
func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config { func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config {
if retryer == nil {
if cfg.Logger != nil {
cfg.Logger.Log("ERROR: Request.WithRetryer called with nil retryer. Replacing with retry disabled Retryer.")
}
retryer = noOpRetryer{}
}
cfg.Retryer = retryer cfg.Retryer = retryer
return cfg return cfg
}
// noOpRetryer is a internal no op retryer used when a request is created
// without a retryer.
//
// Provides a retryer that performs no retries.
// It should be used when we do not want retries to be performed.
type noOpRetryer struct{}
// MaxRetries returns the number of maximum returns the service will use to make
// an individual API; For NoOpRetryer the MaxRetries will always be zero.
func (d noOpRetryer) MaxRetries() int {
return 0
}
// ShouldRetry will always return false for NoOpRetryer, as it should never retry.
func (d noOpRetryer) ShouldRetry(_ *Request) bool {
return false
}
// RetryRules returns the delay duration before retrying this request again;
// since NoOpRetryer does not retry, RetryRules always returns 0.
func (d noOpRetryer) RetryRules(_ *Request) time.Duration {
return 0
} }
// 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
...@@ -52,6 +83,7 @@ var retryableCodes = map[string]struct{}{ ...@@ -52,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": {},
...@@ -145,8 +177,8 @@ func shouldRetryError(origErr error) bool { ...@@ -145,8 +177,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
} }
} }
...@@ -219,6 +251,16 @@ func (r *Request) IsErrorRetryable() bool { ...@@ -219,6 +251,16 @@ func (r *Request) IsErrorRetryable() bool {
return true return true
} }
// HTTP response status code 501 should not be retried.
// 501 represents Not Implemented which means the request method is not
// supported by the server and cannot be handled.
if r.HTTPResponse != nil {
// HTTP response status code 500 represents internal server error and
// should be retried without any throttle.
if r.HTTPResponse.StatusCode == 500 {
return true
}
}
return IsErrorRetryable(r.Error) return IsErrorRetryable(r.Error)
} }
...@@ -233,7 +275,11 @@ func (r *Request) IsErrorThrottle() bool { ...@@ -233,7 +275,11 @@ func (r *Request) IsErrorThrottle() bool {
if r.HTTPResponse != nil { if r.HTTPResponse != nil {
switch r.HTTPResponse.StatusCode { switch r.HTTPResponse.StatusCode {
case 429, 502, 503, 504: case
429, // error caused due to too many requests
502, // Bad Gateway error should be throttled
503, // caused when service is unavailable
504: // error occurred due to gateway timeout
return true return true
} }
} }
......
...@@ -47,10 +47,10 @@ func resolveCredentials(cfg *aws.Config, ...@@ -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)
......
package session package session
import ( import (
"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"
"github.com/aws/aws-sdk-go/aws/defaults" "github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/endpoints"
) )
// EnvProviderName provides a name of the provider when config is loaded from environment. // EnvProviderName provides a name of the provider when config is loaded from environment.
...@@ -125,6 +128,26 @@ type envConfig struct { ...@@ -125,6 +128,26 @@ type envConfig struct {
// //
// AWS_ROLE_SESSION_NAME=session_name // AWS_ROLE_SESSION_NAME=session_name
RoleSessionName string RoleSessionName string
// Specifies the STS Regional Endpoint flag for the SDK to resolve the endpoint
// for a service.
//
// AWS_STS_REGIONAL_ENDPOINTS=regional
// This can take value as `regional` or `legacy`
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 (
...@@ -179,6 +202,15 @@ var ( ...@@ -179,6 +202,15 @@ var (
roleSessionNameEnvKey = []string{ roleSessionNameEnvKey = []string{
"AWS_ROLE_SESSION_NAME", "AWS_ROLE_SESSION_NAME",
} }
stsRegionalEndpointKey = []string{
"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.
...@@ -187,7 +219,7 @@ var ( ...@@ -187,7 +219,7 @@ var (
// If the environment variable `AWS_SDK_LOAD_CONFIG` is set to a truthy value // If the environment variable `AWS_SDK_LOAD_CONFIG` is set to a truthy value
// the shared SDK config will be loaded in addition to the SDK's specific // the shared SDK config will be loaded in addition to the SDK's specific
// configuration values. // configuration values.
func loadEnvConfig() envConfig { func loadEnvConfig() (envConfig, error) {
enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG")) enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG"))
return envConfigLoad(enableSharedConfig) return envConfigLoad(enableSharedConfig)
} }
...@@ -198,11 +230,11 @@ func loadEnvConfig() envConfig { ...@@ -198,11 +230,11 @@ func loadEnvConfig() envConfig {
// Loads the shared configuration in addition to the SDK's specific configuration. // Loads the shared configuration in addition to the SDK's specific configuration.
// This will load the same values as `loadEnvConfig` if the `AWS_SDK_LOAD_CONFIG` // This will load the same values as `loadEnvConfig` if the `AWS_SDK_LOAD_CONFIG`
// environment variable is set. // environment variable is set.
func loadSharedEnvConfig() envConfig { func loadSharedEnvConfig() (envConfig, error) {
return envConfigLoad(true) return envConfigLoad(true)
} }
func envConfigLoad(enableSharedConfig bool) envConfig { func envConfigLoad(enableSharedConfig bool) (envConfig, error) {
cfg := envConfig{} cfg := envConfig{}
cfg.EnableSharedConfig = enableSharedConfig cfg.EnableSharedConfig = enableSharedConfig
...@@ -264,12 +296,48 @@ func envConfigLoad(enableSharedConfig bool) envConfig { ...@@ -264,12 +296,48 @@ func envConfigLoad(enableSharedConfig bool) envConfig {
cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE") cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE")
return cfg var err error
// STS Regional Endpoint variable
for _, k := range stsRegionalEndpointKey {
if v := os.Getenv(k); len(v) != 0 {
cfg.STSRegionalEndpoint, err = endpoints.GetSTSRegionalEndpoint(v)
if err != nil {
return cfg, fmt.Errorf("failed to load, %v from env config, %v", k, err)
}
}
}
// 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)
}
}
return cfg, nil
} }
func setFromEnvVal(dst *string, keys []string) { func setFromEnvVal(dst *string, keys []string) {
for _, k := range keys { for _, k := range keys {
if v := os.Getenv(k); len(v) > 0 { if v := os.Getenv(k); len(v) != 0 {
*dst = v *dst = v
break break
} }
......
...@@ -73,7 +73,7 @@ type Session struct { ...@@ -73,7 +73,7 @@ type Session struct {
// func is called instead of waiting to receive an error until a request is made. // func is called instead of waiting to receive an error until a request is made.
func New(cfgs ...*aws.Config) *Session { func New(cfgs ...*aws.Config) *Session {
// load initial config from environment // load initial config from environment
envCfg := loadEnvConfig() envCfg, envErr := loadEnvConfig()
if envCfg.EnableSharedConfig { if envCfg.EnableSharedConfig {
var cfg aws.Config var cfg aws.Config
...@@ -93,17 +93,17 @@ func New(cfgs ...*aws.Config) *Session { ...@@ -93,17 +93,17 @@ func New(cfgs ...*aws.Config) *Session {
// Session creation failed, need to report the error and prevent // Session creation failed, need to report the error and prevent
// any requests from succeeding. // any requests from succeeding.
s = &Session{Config: defaults.Config()} s = &Session{Config: defaults.Config()}
s.Config.MergeIn(cfgs...) s.logDeprecatedNewSessionError(msg, err, cfgs)
s.Config.Logger.Log("ERROR:", msg, "Error:", err)
s.Handlers.Validate.PushBack(func(r *request.Request) {
r.Error = err
})
} }
return s return s
} }
s := deprecatedNewSession(cfgs...) s := deprecatedNewSession(cfgs...)
if envErr != nil {
msg := "failed to load env config"
s.logDeprecatedNewSessionError(msg, envErr, cfgs)
}
if csmCfg, err := loadCSMConfig(envCfg, []string{}); err != nil { if csmCfg, err := loadCSMConfig(envCfg, []string{}); err != nil {
if l := s.Config.Logger; l != nil { if l := s.Config.Logger; l != nil {
...@@ -112,11 +112,8 @@ func New(cfgs ...*aws.Config) *Session { ...@@ -112,11 +112,8 @@ func New(cfgs ...*aws.Config) *Session {
} else if csmCfg.Enabled { } else if csmCfg.Enabled {
err := enableCSM(&s.Handlers, csmCfg, s.Config.Logger) err := enableCSM(&s.Handlers, csmCfg, s.Config.Logger)
if err != nil { if err != nil {
err = fmt.Errorf("failed to enable CSM, %v", err) msg := "failed to enable CSM"
s.Config.Logger.Log("ERROR:", err.Error()) s.logDeprecatedNewSessionError(msg, err, cfgs)
s.Handlers.Validate.PushBack(func(r *request.Request) {
r.Error = err
})
} }
} }
...@@ -279,10 +276,17 @@ type Options struct { ...@@ -279,10 +276,17 @@ type Options struct {
// })) // }))
func NewSessionWithOptions(opts Options) (*Session, error) { func NewSessionWithOptions(opts Options) (*Session, error) {
var envCfg envConfig var envCfg envConfig
var err error
if opts.SharedConfigState == SharedConfigEnable { if opts.SharedConfigState == SharedConfigEnable {
envCfg = loadSharedEnvConfig() envCfg, err = loadSharedEnvConfig()
if err != nil {
return nil, fmt.Errorf("failed to load shared config, %v", err)
}
} else { } else {
envCfg = loadEnvConfig() envCfg, err = loadEnvConfig()
if err != nil {
return nil, fmt.Errorf("failed to load environment config, %v", err)
}
} }
if len(opts.Profile) != 0 { if len(opts.Profile) != 0 {
...@@ -550,6 +554,22 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, ...@@ -550,6 +554,22 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config,
} }
} }
// Regional Endpoint flag for STS endpoint resolving
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.
if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil { if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
...@@ -560,9 +580,35 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, ...@@ -560,9 +580,35 @@ 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
} }
func mergeSTSRegionalEndpointConfig(cfg *aws.Config, values []endpoints.STSRegionalEndpoint) {
for _, v := range values {
if v != endpoints.UnsetSTSEndpoint {
cfg.STSRegionalEndpoint = v
break
}
}
}
func mergeS3UsEast1RegionalEndpointConfig(cfg *aws.Config, values []endpoints.S3UsEast1RegionalEndpoint) {
for _, v := range values {
if v != endpoints.UnsetS3UsEast1Endpoint {
cfg.S3UsEast1RegionalEndpoint = v
break
}
}
}
func initHandlers(s *Session) { func initHandlers(s *Session) {
// Add the Validate parameter handler if it is not disabled. // Add the Validate parameter handler if it is not disabled.
s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler) s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler)
...@@ -591,47 +637,67 @@ func (s *Session) Copy(cfgs ...*aws.Config) *Session { ...@@ -591,47 +637,67 @@ func (s *Session) Copy(cfgs ...*aws.Config) *Session {
// ClientConfig satisfies the client.ConfigProvider interface and is used to // ClientConfig satisfies the client.ConfigProvider interface and is used to
// configure the service client instances. Passing the Session to the service // configure the service client instances. Passing the Session to the service
// client's constructor (New) will use this method to configure the client. // client's constructor (New) will use this method to configure the client.
func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config { func (s *Session) ClientConfig(service string, cfgs ...*aws.Config) client.Config {
// Backwards compatibility, the error will be eaten if user calls ClientConfig
// directly. All SDK services will use ClientconfigWithError.
cfg, _ := s.clientConfigWithErr(serviceName, cfgs...)
return cfg
}
func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) (client.Config, error) {
s = s.Copy(cfgs...) s = s.Copy(cfgs...)
var resolved endpoints.ResolvedEndpoint
var err error
region := aws.StringValue(s.Config.Region) region := aws.StringValue(s.Config.Region)
resolved, err := s.resolveEndpoint(service, region, s.Config)
if endpoint := aws.StringValue(s.Config.Endpoint); len(endpoint) != 0 { if err != nil {
resolved.URL = endpoints.AddScheme(endpoint, aws.BoolValue(s.Config.DisableSSL)) s.Handlers.Validate.PushBack(func(r *request.Request) {
resolved.SigningRegion = region if len(r.ClientInfo.Endpoint) != 0 {
} else { // Error occurred while resolving endpoint, but the request
resolved, err = s.Config.EndpointResolver.EndpointFor( // being invoked has had an endpoint specified after the client
serviceName, region, // was created.
func(opt *endpoints.Options) { return
opt.DisableSSL = aws.BoolValue(s.Config.DisableSSL) }
opt.UseDualStack = aws.BoolValue(s.Config.UseDualStack) r.Error = err
})
// Support the condition where the service is modeled but its
// endpoint metadata is not available.
opt.ResolveUnknownService = true
},
)
} }
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,
SigningName: resolved.SigningName, SigningName: resolved.SigningName,
}, err }
}
func (s *Session) resolveEndpoint(service, region string, cfg *aws.Config) (endpoints.ResolvedEndpoint, error) {
if ep := aws.StringValue(cfg.Endpoint); len(ep) != 0 {
return endpoints.ResolvedEndpoint{
URL: endpoints.AddScheme(ep, aws.BoolValue(cfg.DisableSSL)),
SigningRegion: region,
}, nil
}
resolved, err := cfg.EndpointResolver.EndpointFor(service, region,
func(opt *endpoints.Options) {
opt.DisableSSL = aws.BoolValue(cfg.DisableSSL)
opt.UseDualStack = aws.BoolValue(cfg.UseDualStack)
// Support for STSRegionalEndpoint where the STSRegionalEndpoint is
// provided in envConfig or sharedConfig with envConfig getting
// precedence.
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
// endpoint metadata is not available.
opt.ResolveUnknownService = true
},
)
if err != nil {
return endpoints.ResolvedEndpoint{}, err
}
return resolved, nil
} }
// ClientConfigNoResolveEndpoint is the same as ClientConfig with the exception // ClientConfigNoResolveEndpoint is the same as ClientConfig with the exception
...@@ -641,12 +707,9 @@ func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Conf ...@@ -641,12 +707,9 @@ func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Conf
s = s.Copy(cfgs...) s = s.Copy(cfgs...)
var resolved endpoints.ResolvedEndpoint var resolved endpoints.ResolvedEndpoint
region := aws.StringValue(s.Config.Region)
if ep := aws.StringValue(s.Config.Endpoint); len(ep) > 0 { if ep := aws.StringValue(s.Config.Endpoint); len(ep) > 0 {
resolved.URL = endpoints.AddScheme(ep, aws.BoolValue(s.Config.DisableSSL)) resolved.URL = endpoints.AddScheme(ep, aws.BoolValue(s.Config.DisableSSL))
resolved.SigningRegion = region resolved.SigningRegion = aws.StringValue(s.Config.Region)
} }
return client.Config{ return client.Config{
...@@ -658,3 +721,14 @@ func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Conf ...@@ -658,3 +721,14 @@ func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Conf
SigningName: resolved.SigningName, SigningName: resolved.SigningName,
} }
} }
// logDeprecatedNewSessionError function enables error handling for session
func (s *Session) logDeprecatedNewSessionError(msg string, err error, cfgs []*aws.Config) {
// Session creation failed, need to report the error and prevent
// any requests from succeeding.
s.Config.MergeIn(cfgs...)
s.Config.Logger.Log("ERROR:", msg, "Error:", err)
s.Handlers.Validate.PushBack(func(r *request.Request) {
r.Error = err
})
}
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,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/aws/endpoints"
"github.com/aws/aws-sdk-go/internal/ini" "github.com/aws/aws-sdk-go/internal/ini"
) )
...@@ -40,10 +41,19 @@ const ( ...@@ -40,10 +41,19 @@ const (
// Web Identity Token File // Web Identity Token File
webIdentityTokenFileKey = `web_identity_token_file` // optional webIdentityTokenFileKey = `web_identity_token_file` // optional
// Additional config fields for regional or legacy 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.
...@@ -88,6 +98,24 @@ type sharedConfig struct { ...@@ -88,6 +98,24 @@ type sharedConfig struct {
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
//
// sts_regional_endpoints = regional
// This can take value as `LegacySTSEndpoint` or `RegionalSTSEndpoint`
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 {
...@@ -244,8 +272,25 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e ...@@ -244,8 +272,25 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e
updateString(&cfg.RoleSessionName, section, roleSessionNameKey) updateString(&cfg.RoleSessionName, section, roleSessionNameKey)
updateString(&cfg.SourceProfileName, section, sourceProfileKey) updateString(&cfg.SourceProfileName, section, sourceProfileKey)
updateString(&cfg.CredentialSource, section, credentialSourceKey) updateString(&cfg.CredentialSource, section, credentialSourceKey)
updateString(&cfg.Region, section, regionKey) updateString(&cfg.Region, section, regionKey)
if v := section.String(stsRegionalEndpointSharedKey); len(v) != 0 {
sre, err := endpoints.GetSTSRegionalEndpoint(v)
if err != nil {
return fmt.Errorf("failed to load %s from shared config, %s, %v",
stsRegionalEndpointSharedKey, file.Filename, err)
}
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)
...@@ -271,6 +316,8 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, e ...@@ -271,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
} }
...@@ -363,6 +410,15 @@ func updateString(dst *string, section ini.Section, key string) { ...@@ -363,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) {
......
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 ...@@ -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
} }
} }
......
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")
}
...@@ -76,9 +76,14 @@ import ( ...@@ -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 ( ...@@ -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 { ...@@ -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
...@@ -532,39 +535,56 @@ func (ctx *signingCtx) build(disableHeaderHoisting bool) error { ...@@ -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) { ...@@ -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() { ...@@ -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() { ...@@ -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) { ...@@ -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)
}
...@@ -2,6 +2,7 @@ package aws ...@@ -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 { ...@@ -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")
}
...@@ -5,4 +5,4 @@ package aws ...@@ -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.24.1" const SDKVersion = "1.28.2"
...@@ -162,7 +162,7 @@ loop: ...@@ -162,7 +162,7 @@ loop:
if len(tokens) == 0 { if len(tokens) == 0 {
break loop break loop
} }
// if should skip is true, we skip the tokens until should skip is set to false.
step = SkipTokenState step = SkipTokenState
} }
...@@ -218,7 +218,7 @@ loop: ...@@ -218,7 +218,7 @@ loop:
// S -> equal_expr' expr_stmt' // S -> equal_expr' expr_stmt'
switch k.Kind { switch k.Kind {
case ASTKindEqualExpr: case ASTKindEqualExpr:
// assiging a value to some key // assigning a value to some key
k.AppendChild(newExpression(tok)) k.AppendChild(newExpression(tok))
stack.Push(newExprStatement(k)) stack.Push(newExprStatement(k))
case ASTKindExpr: case ASTKindExpr:
...@@ -250,6 +250,13 @@ loop: ...@@ -250,6 +250,13 @@ loop:
if !runeCompare(tok.Raw(), openBrace) { if !runeCompare(tok.Raw(), openBrace) {
return nil, NewParseError("expected '['") return nil, NewParseError("expected '['")
} }
// If OpenScopeState is not at the start, we must mark the previous ast as complete
//
// for example: if previous ast was a skip statement;
// we should mark it as complete before we create a new statement
if k.Kind != ASTKindStart {
stack.MarkComplete(k)
}
stmt := newStatement() stmt := newStatement()
stack.Push(stmt) stack.Push(stmt)
......
...@@ -22,24 +22,24 @@ func newSkipper() skipper { ...@@ -22,24 +22,24 @@ func newSkipper() skipper {
} }
func (s *skipper) ShouldSkip(tok Token) bool { func (s *skipper) ShouldSkip(tok Token) bool {
// should skip state will be modified only if previous token was new line (NL);
// and the current token is not WhiteSpace (WS).
if s.shouldSkip && if s.shouldSkip &&
s.prevTok.Type() == TokenNL && s.prevTok.Type() == TokenNL &&
tok.Type() != TokenWS { tok.Type() != TokenWS {
s.Continue() s.Continue()
return false return false
} }
s.prevTok = tok s.prevTok = tok
return s.shouldSkip return s.shouldSkip
} }
func (s *skipper) Skip() { func (s *skipper) Skip() {
s.shouldSkip = true s.shouldSkip = true
s.prevTok = emptyToken
} }
func (s *skipper) Continue() { func (s *skipper) Continue() {
s.shouldSkip = false s.shouldSkip = false
// empty token is assigned as we return to default state, when should skip is false
s.prevTok = emptyToken s.prevTok = emptyToken
} }
package sdkio
const (
// Byte is 8 bits
Byte int64 = 1
// KibiByte (KiB) is 1024 Bytes
KibiByte = Byte * 1024
// MebiByte (MiB) is 1024 KiB
MebiByte = KibiByte * 1024
// GibiByte (GiB) is 1024 MiB
GibiByte = MebiByte * 1024
)
// +build go1.6
package sdkrand
import "math/rand"
// Read provides the stub for math.Rand.Read method support for go version's
// 1.6 and greater.
func Read(r *rand.Rand, p []byte) (int, error) {
return r.Read(p)
}
// +build !go1.6
package sdkrand
import "math/rand"
// Read backfills Go 1.6's math.Rand.Reader for Go 1.5
func Read(r *rand.Rand, p []byte) (n int, err error) {
// Copy of Go standard libraries math package's read function not added to
// standard library until Go 1.6.
var pos int8
var val int64
for n = 0; n < len(p); n++ {
if pos == 0 {
val = r.Int63()
pos = 7
}
p[n] = byte(val)
val >>= 8
pos--
}
return n, err
}
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)
}
...@@ -6,8 +6,6 @@ package jsonrpc ...@@ -6,8 +6,6 @@ package jsonrpc
//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/json.json unmarshal_test.go //go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/json.json unmarshal_test.go
import ( import (
"strings"
"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"
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil" "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
...@@ -16,17 +14,26 @@ import ( ...@@ -16,17 +14,26 @@ import (
var emptyJSON = []byte("{}") var emptyJSON = []byte("{}")
// BuildHandler is a named request handler for building jsonrpc protocol requests // BuildHandler is a named request handler for building jsonrpc protocol
var BuildHandler = request.NamedHandler{Name: "awssdk.jsonrpc.Build", Fn: Build} // requests
var BuildHandler = request.NamedHandler{
// UnmarshalHandler is a named request handler for unmarshaling jsonrpc protocol requests Name: "awssdk.jsonrpc.Build",
var UnmarshalHandler = request.NamedHandler{Name: "awssdk.jsonrpc.Unmarshal", Fn: Unmarshal} Fn: Build,
}
// UnmarshalMetaHandler is a named request handler for unmarshaling jsonrpc protocol request metadata // UnmarshalHandler is a named request handler for unmarshaling jsonrpc
var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.jsonrpc.UnmarshalMeta", Fn: UnmarshalMeta} // protocol requests
var UnmarshalHandler = request.NamedHandler{
Name: "awssdk.jsonrpc.Unmarshal",
Fn: Unmarshal,
}
// UnmarshalErrorHandler is a named request handler for unmarshaling jsonrpc protocol request errors // UnmarshalMetaHandler is a named request handler for unmarshaling jsonrpc
var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.jsonrpc.UnmarshalError", Fn: UnmarshalError} // protocol request metadata
var UnmarshalMetaHandler = request.NamedHandler{
Name: "awssdk.jsonrpc.UnmarshalMeta",
Fn: UnmarshalMeta,
}
// Build builds a JSON payload for a JSON RPC request. // Build builds a JSON payload for a JSON RPC request.
func Build(req *request.Request) { func Build(req *request.Request) {
...@@ -79,32 +86,3 @@ func Unmarshal(req *request.Request) { ...@@ -79,32 +86,3 @@ func Unmarshal(req *request.Request) {
func UnmarshalMeta(req *request.Request) { func UnmarshalMeta(req *request.Request) {
rest.UnmarshalMeta(req) rest.UnmarshalMeta(req)
} }
// UnmarshalError unmarshals an error response for a JSON RPC service.
func UnmarshalError(req *request.Request) {
defer req.HTTPResponse.Body.Close()
var jsonErr jsonErrorResponse
err := jsonutil.UnmarshalJSONError(&jsonErr, req.HTTPResponse.Body)
if err != nil {
req.Error = awserr.NewRequestFailure(
awserr.New(request.ErrCodeSerialization,
"failed to unmarshal error message", err),
req.HTTPResponse.StatusCode,
req.RequestID,
)
return
}
codes := strings.SplitN(jsonErr.Code, "#", 2)
req.Error = awserr.NewRequestFailure(
awserr.New(codes[len(codes)-1], jsonErr.Message, nil),
req.HTTPResponse.StatusCode,
req.RequestID,
)
}
type jsonErrorResponse struct {
Code string `json:"__type"`
Message string `json:"message"`
}
package jsonrpc
import (
"bytes"
"io"
"io/ioutil"
"net/http"
"strings"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol"
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
)
// UnmarshalTypedError provides unmarshaling errors API response errors
// for both typed and untyped errors.
type UnmarshalTypedError struct {
exceptions map[string]func(protocol.ResponseMetadata) error
}
// NewUnmarshalTypedError returns an UnmarshalTypedError initialized for the
// set of exception names to the error unmarshalers
func NewUnmarshalTypedError(exceptions map[string]func(protocol.ResponseMetadata) error) *UnmarshalTypedError {
return &UnmarshalTypedError{
exceptions: exceptions,
}
}
// UnmarshalError attempts to unmarshal the HTTP response error as a known
// error type. If unable to unmarshal the error type, the generic SDK error
// type will be used.
func (u *UnmarshalTypedError) UnmarshalError(
resp *http.Response,
respMeta protocol.ResponseMetadata,
) (error, error) {
var buf bytes.Buffer
var jsonErr jsonErrorResponse
teeReader := io.TeeReader(resp.Body, &buf)
err := jsonutil.UnmarshalJSONError(&jsonErr, teeReader)
if err != nil {
return nil, err
}
body := ioutil.NopCloser(&buf)
// Code may be separated by hash(#), with the last element being the code
// used by the SDK.
codeParts := strings.SplitN(jsonErr.Code, "#", 2)
code := codeParts[len(codeParts)-1]
msg := jsonErr.Message
if fn, ok := u.exceptions[code]; ok {
// If exception code is know, use associated constructor to get a value
// for the exception that the JSON body can be unmarshaled into.
v := fn(respMeta)
err := jsonutil.UnmarshalJSON(v, body)
if err != nil {
return nil, err
}
return v, nil
}
// fallback to unmodeled generic exceptions
return awserr.NewRequestFailure(
awserr.New(code, msg, nil),
respMeta.StatusCode,
respMeta.RequestID,
), nil
}
// UnmarshalErrorHandler is a named request handler for unmarshaling jsonrpc
// protocol request errors
var UnmarshalErrorHandler = request.NamedHandler{
Name: "awssdk.jsonrpc.UnmarshalError",
Fn: UnmarshalError,
}
// UnmarshalError unmarshals an error response for a JSON RPC service.
func UnmarshalError(req *request.Request) {
defer req.HTTPResponse.Body.Close()
var jsonErr jsonErrorResponse
err := jsonutil.UnmarshalJSONError(&jsonErr, req.HTTPResponse.Body)
if err != nil {
req.Error = awserr.NewRequestFailure(
awserr.New(request.ErrCodeSerialization,
"failed to unmarshal error message", err),
req.HTTPResponse.StatusCode,
req.RequestID,
)
return
}
codes := strings.SplitN(jsonErr.Code, "#", 2)
req.Error = awserr.NewRequestFailure(
awserr.New(codes[len(codes)-1], jsonErr.Message, nil),
req.HTTPResponse.StatusCode,
req.RequestID,
)
}
type jsonErrorResponse struct {
Code string `json:"__type"`
Message string `json:"message"`
}
...@@ -64,7 +64,7 @@ func (h HandlerPayloadMarshal) MarshalPayload(w io.Writer, v interface{}) error ...@@ -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,
) )
......
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,
)
}
...@@ -15,6 +15,7 @@ import ( ...@@ -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 ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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 ...@@ -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]
} }
} }
......
...@@ -19,3 +19,9 @@ func UnmarshalDiscardBody(r *request.Request) { ...@@ -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
}
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
}
package xmlutil
import (
"encoding/xml"
"strings"
)
type xmlAttrSlice []xml.Attr
func (x xmlAttrSlice) Len() int {
return len(x)
}
func (x xmlAttrSlice) Less(i, j int) bool {
spaceI, spaceJ := x[i].Name.Space, x[j].Name.Space
localI, localJ := x[i].Name.Local, x[j].Name.Local
valueI, valueJ := x[i].Value, x[j].Value
spaceCmp := strings.Compare(spaceI, spaceJ)
localCmp := strings.Compare(localI, localJ)
valueCmp := strings.Compare(valueI, valueJ)
if spaceCmp == -1 || (spaceCmp == 0 && (localCmp == -1 || (localCmp == 0 && valueCmp == -1))) {
return true
}
return false
}
func (x xmlAttrSlice) Swap(i, j int) {
x[i], x[j] = x[j], x[i]
}
...@@ -119,7 +119,18 @@ func (n *XMLNode) findElem(name string) (string, bool) { ...@@ -119,7 +119,18 @@ func (n *XMLNode) findElem(name string) (string, bool) {
// StructToXML writes an XMLNode to a xml.Encoder as tokens. // StructToXML writes an XMLNode to a xml.Encoder as tokens.
func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error { func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
e.EncodeToken(xml.StartElement{Name: node.Name, Attr: node.Attr}) // Sort Attributes
attrs := node.Attr
if sorted {
sortedAttrs := make([]xml.Attr, len(attrs))
for _, k := range node.Attr {
sortedAttrs = append(sortedAttrs, k)
}
sort.Sort(xmlAttrSlice(sortedAttrs))
attrs = sortedAttrs
}
e.EncodeToken(xml.StartElement{Name: node.Name, Attr: attrs})
if node.Text != "" { if node.Text != "" {
e.EncodeToken(xml.CharData([]byte(node.Text))) e.EncodeToken(xml.CharData([]byte(node.Text)))
......
...@@ -31,7 +31,7 @@ var initRequest func(*request.Request) ...@@ -31,7 +31,7 @@ var initRequest func(*request.Request)
const ( const (
ServiceName = "autoscaling" // Name of service. ServiceName = "autoscaling" // Name of service.
EndpointsID = ServiceName // ID to lookup a service endpoint with. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "Auto Scaling" // ServiceID is a unique identifer of a specific service. ServiceID = "Auto Scaling" // ServiceID is a unique identifier of a specific service.
) )
// New creates a new instance of the AutoScaling client with a session. // New creates a new instance of the AutoScaling client with a session.
...@@ -39,6 +39,8 @@ const ( ...@@ -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 AutoScaling client from just a session. // // Create a AutoScaling client from just a session.
// svc := autoscaling.New(mySession) // svc := autoscaling.New(mySession)
// //
...@@ -46,11 +48,11 @@ const ( ...@@ -46,11 +48,11 @@ const (
// svc := autoscaling.New(mySession, aws.NewConfig().WithRegion("us-west-2")) // svc := autoscaling.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *AutoScaling { func New(p client.ConfigProvider, cfgs ...*aws.Config) *AutoScaling {
c := p.ClientConfig(EndpointsID, cfgs...) c := p.ClientConfig(EndpointsID, cfgs...)
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName) return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName)
} }
// newClient creates, initializes and returns a new service client instance. // newClient creates, initializes and returns a new service client instance.
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *AutoScaling { func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName string) *AutoScaling {
svc := &AutoScaling{ svc := &AutoScaling{
Client: client.New( Client: client.New(
cfg, cfg,
...@@ -59,6 +61,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio ...@@ -59,6 +61,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
ServiceID: ServiceID, ServiceID: ServiceID,
SigningName: signingName, SigningName: signingName,
SigningRegion: signingRegion, SigningRegion: signingRegion,
PartitionID: partitionID,
Endpoint: endpoint, Endpoint: endpoint,
APIVersion: "2011-01-01", APIVersion: "2011-01-01",
}, },
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -31,7 +31,7 @@ var initRequest func(*request.Request) ...@@ -31,7 +31,7 @@ var initRequest func(*request.Request)
const ( const (
ServiceName = "ec2" // Name of service. ServiceName = "ec2" // Name of service.
EndpointsID = ServiceName // ID to lookup a service endpoint with. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "EC2" // ServiceID is a unique identifer of a specific service. ServiceID = "EC2" // ServiceID is a unique identifier of a specific service.
) )
// New creates a new instance of the EC2 client with a session. // New creates a new instance of the EC2 client with a session.
...@@ -39,6 +39,8 @@ const ( ...@@ -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 EC2 client from just a session. // // Create a EC2 client from just a session.
// svc := ec2.New(mySession) // svc := ec2.New(mySession)
// //
...@@ -46,11 +48,11 @@ const ( ...@@ -46,11 +48,11 @@ const (
// svc := ec2.New(mySession, aws.NewConfig().WithRegion("us-west-2")) // svc := ec2.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2 { func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2 {
c := p.ClientConfig(EndpointsID, cfgs...) c := p.ClientConfig(EndpointsID, cfgs...)
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName) return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName)
} }
// newClient creates, initializes and returns a new service client instance. // newClient creates, initializes and returns a new service client instance.
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *EC2 { func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName string) *EC2 {
svc := &EC2{ svc := &EC2{
Client: client.New( Client: client.New(
cfg, cfg,
...@@ -59,6 +61,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio ...@@ -59,6 +61,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
ServiceID: ServiceID, ServiceID: ServiceID,
SigningName: signingName, SigningName: signingName,
SigningRegion: signingRegion, SigningRegion: signingRegion,
PartitionID: partitionID,
Endpoint: endpoint, Endpoint: endpoint,
APIVersion: "2016-11-15", APIVersion: "2016-11-15",
}, },
......
...@@ -952,6 +952,57 @@ func (c *EC2) WaitUntilPasswordDataAvailableWithContext(ctx aws.Context, input * ...@@ -952,6 +952,57 @@ func (c *EC2) WaitUntilPasswordDataAvailableWithContext(ctx aws.Context, input *
return w.WaitWithContext(ctx) return w.WaitWithContext(ctx)
} }
// WaitUntilSecurityGroupExists uses the Amazon EC2 API operation
// DescribeSecurityGroups to wait for a condition to be met before returning.
// If the condition is not met within the max attempt window, an error will
// be returned.
func (c *EC2) WaitUntilSecurityGroupExists(input *DescribeSecurityGroupsInput) error {
return c.WaitUntilSecurityGroupExistsWithContext(aws.BackgroundContext(), input)
}
// WaitUntilSecurityGroupExistsWithContext is an extended version of WaitUntilSecurityGroupExists.
// With the support for passing in a context and options to configure the
// Waiter and the underlying request options.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *EC2) WaitUntilSecurityGroupExistsWithContext(ctx aws.Context, input *DescribeSecurityGroupsInput, opts ...request.WaiterOption) error {
w := request.Waiter{
Name: "WaitUntilSecurityGroupExists",
MaxAttempts: 6,
Delay: request.ConstantWaiterDelay(5 * time.Second),
Acceptors: []request.WaiterAcceptor{
{
State: request.SuccessWaiterState,
Matcher: request.PathWaiterMatch, Argument: "length(SecurityGroups[].GroupId) > `0`",
Expected: true,
},
{
State: request.RetryWaiterState,
Matcher: request.ErrorWaiterMatch,
Expected: "InvalidGroupNotFound",
},
},
Logger: c.Config.Logger,
NewRequest: func(opts []request.Option) (*request.Request, error) {
var inCpy *DescribeSecurityGroupsInput
if input != nil {
tmp := *input
inCpy = &tmp
}
req, _ := c.DescribeSecurityGroupsRequest(inCpy)
req.SetContext(ctx)
req.ApplyOptions(opts...)
return req, nil
},
}
w.ApplyOptions(opts...)
return w.WaitWithContext(ctx)
}
// WaitUntilSnapshotCompleted uses the Amazon EC2 API operation // WaitUntilSnapshotCompleted uses the Amazon EC2 API operation
// DescribeSnapshots to wait for a condition to be met before returning. // DescribeSnapshots to wait for a condition to be met before returning.
// If the condition is not met within the max attempt window, an error will // If the condition is not met within the max attempt window, an error will
......
...@@ -1807,10 +1807,12 @@ func (c *ELB) DescribeLoadBalancersPagesWithContext(ctx aws.Context, input *Desc ...@@ -1807,10 +1807,12 @@ func (c *ELB) DescribeLoadBalancersPagesWithContext(ctx aws.Context, input *Desc
}, },
} }
cont := true for p.Next() {
for p.Next() && cont { if !fn(p.Page().(*DescribeLoadBalancersOutput), !p.HasNextPage()) {
cont = fn(p.Page().(*DescribeLoadBalancersOutput), !p.HasNextPage()) break
}
} }
return p.Err() return p.Err()
} }
......
...@@ -31,7 +31,7 @@ var initRequest func(*request.Request) ...@@ -31,7 +31,7 @@ var initRequest func(*request.Request)
const ( const (
ServiceName = "elasticloadbalancing" // Name of service. ServiceName = "elasticloadbalancing" // Name of service.
EndpointsID = ServiceName // ID to lookup a service endpoint with. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "Elastic Load Balancing" // ServiceID is a unique identifer of a specific service. ServiceID = "Elastic Load Balancing" // ServiceID is a unique identifier of a specific service.
) )
// New creates a new instance of the ELB client with a session. // New creates a new instance of the ELB client with a session.
...@@ -39,6 +39,8 @@ const ( ...@@ -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 ELB client from just a session. // // Create a ELB client from just a session.
// svc := elb.New(mySession) // svc := elb.New(mySession)
// //
...@@ -46,11 +48,11 @@ const ( ...@@ -46,11 +48,11 @@ const (
// svc := elb.New(mySession, aws.NewConfig().WithRegion("us-west-2")) // svc := elb.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *ELB { func New(p client.ConfigProvider, cfgs ...*aws.Config) *ELB {
c := p.ClientConfig(EndpointsID, cfgs...) c := p.ClientConfig(EndpointsID, cfgs...)
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName) return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName)
} }
// newClient creates, initializes and returns a new service client instance. // newClient creates, initializes and returns a new service client instance.
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *ELB { func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName string) *ELB {
svc := &ELB{ svc := &ELB{
Client: client.New( Client: client.New(
cfg, cfg,
...@@ -59,6 +61,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio ...@@ -59,6 +61,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
ServiceID: ServiceID, ServiceID: ServiceID,
SigningName: signingName, SigningName: signingName,
SigningRegion: signingRegion, SigningRegion: signingRegion,
PartitionID: partitionID,
Endpoint: endpoint, Endpoint: endpoint,
APIVersion: "2012-06-01", APIVersion: "2012-06-01",
}, },
......
...@@ -211,6 +211,14 @@ const ( ...@@ -211,6 +211,14 @@ const (
// You've reached the limit on the number of targets. // You've reached the limit on the number of targets.
ErrCodeTooManyTargetsException = "TooManyTargets" ErrCodeTooManyTargetsException = "TooManyTargets"
// ErrCodeTooManyUniqueTargetGroupsPerLoadBalancerException for service response error code
// "TooManyUniqueTargetGroupsPerLoadBalancer".
//
// You've reached the limit on the number of unique target groups per load balancer
// across all listeners. If a target group is used by multiple actions for a
// load balancer, it is counted as only one use.
ErrCodeTooManyUniqueTargetGroupsPerLoadBalancerException = "TooManyUniqueTargetGroupsPerLoadBalancer"
// ErrCodeUnsupportedProtocolException for service response error code // ErrCodeUnsupportedProtocolException for service response error code
// "UnsupportedProtocol". // "UnsupportedProtocol".
// //
......
...@@ -31,7 +31,7 @@ var initRequest func(*request.Request) ...@@ -31,7 +31,7 @@ var initRequest func(*request.Request)
const ( const (
ServiceName = "elasticloadbalancing" // Name of service. ServiceName = "elasticloadbalancing" // Name of service.
EndpointsID = ServiceName // ID to lookup a service endpoint with. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "Elastic Load Balancing v2" // ServiceID is a unique identifer of a specific service. ServiceID = "Elastic Load Balancing v2" // ServiceID is a unique identifier of a specific service.
) )
// New creates a new instance of the ELBV2 client with a session. // New creates a new instance of the ELBV2 client with a session.
...@@ -39,6 +39,8 @@ const ( ...@@ -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 ELBV2 client from just a session. // // Create a ELBV2 client from just a session.
// svc := elbv2.New(mySession) // svc := elbv2.New(mySession)
// //
...@@ -46,11 +48,11 @@ const ( ...@@ -46,11 +48,11 @@ const (
// svc := elbv2.New(mySession, aws.NewConfig().WithRegion("us-west-2")) // svc := elbv2.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *ELBV2 { func New(p client.ConfigProvider, cfgs ...*aws.Config) *ELBV2 {
c := p.ClientConfig(EndpointsID, cfgs...) c := p.ClientConfig(EndpointsID, cfgs...)
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName) return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName)
} }
// newClient creates, initializes and returns a new service client instance. // newClient creates, initializes and returns a new service client instance.
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *ELBV2 { func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName string) *ELBV2 {
svc := &ELBV2{ svc := &ELBV2{
Client: client.New( Client: client.New(
cfg, cfg,
...@@ -59,6 +61,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio ...@@ -59,6 +61,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
ServiceID: ServiceID, ServiceID: ServiceID,
SigningName: signingName, SigningName: signingName,
SigningRegion: signingRegion, SigningRegion: signingRegion,
PartitionID: partitionID,
Endpoint: endpoint, Endpoint: endpoint,
APIVersion: "2015-12-01", APIVersion: "2015-12-01",
}, },
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
package kms package kms
import (
"github.com/aws/aws-sdk-go/private/protocol"
)
const ( const (
// ErrCodeAlreadyExistsException for service response error code // ErrCodeAlreadyExistsException for service response error code
...@@ -156,17 +160,25 @@ const ( ...@@ -156,17 +160,25 @@ const (
// ErrCodeExpiredImportTokenException for service response error code // ErrCodeExpiredImportTokenException for service response error code
// "ExpiredImportTokenException". // "ExpiredImportTokenException".
// //
// The request was rejected because the provided import token is expired. Use // The request was rejected because the specified import token is expired. Use
// GetParametersForImport to get a new import token and public key, use the // GetParametersForImport to get a new import token and public key, use the
// new public key to encrypt the key material, and then try the request again. // new public key to encrypt the key material, and then try the request again.
ErrCodeExpiredImportTokenException = "ExpiredImportTokenException" ErrCodeExpiredImportTokenException = "ExpiredImportTokenException"
// ErrCodeIncorrectKeyException for service response error code
// "IncorrectKeyException".
//
// The request was rejected because the specified CMK cannot decrypt the data.
// The KeyId in a Decrypt request and the SourceKeyId in a ReEncrypt request
// must identify the same CMK that was used to encrypt the ciphertext.
ErrCodeIncorrectKeyException = "IncorrectKeyException"
// ErrCodeIncorrectKeyMaterialException for service response error code // ErrCodeIncorrectKeyMaterialException for service response error code
// "IncorrectKeyMaterialException". // "IncorrectKeyMaterialException".
// //
// The request was rejected because the provided key material is invalid or // The request was rejected because the key material in the request is, expired,
// is not the same key material that was previously imported into this customer // invalid, or is not the same key material that was previously imported into
// master key (CMK). // this customer master key (CMK).
ErrCodeIncorrectKeyMaterialException = "IncorrectKeyMaterialException" ErrCodeIncorrectKeyMaterialException = "IncorrectKeyMaterialException"
// ErrCodeIncorrectTrustAnchorException for service response error code // ErrCodeIncorrectTrustAnchorException for service response error code
...@@ -203,9 +215,13 @@ const ( ...@@ -203,9 +215,13 @@ const (
// ErrCodeInvalidCiphertextException for service response error code // ErrCodeInvalidCiphertextException for service response error code
// "InvalidCiphertextException". // "InvalidCiphertextException".
// //
// The request was rejected because the specified ciphertext, or additional // From the Decrypt or ReEncrypt operation, the request was rejected because
// authenticated data incorporated into the ciphertext, such as the encryption // the specified ciphertext, or additional authenticated data incorporated into
// context, is corrupted, missing, or otherwise invalid. // the ciphertext, such as the encryption context, is corrupted, missing, or
// otherwise invalid.
//
// From the ImportKeyMaterial operation, the request was rejected because AWS
// KMS could not decrypt the encrypted (wrapped) key material.
ErrCodeInvalidCiphertextException = "InvalidCiphertextException" ErrCodeInvalidCiphertextException = "InvalidCiphertextException"
// ErrCodeInvalidGrantIdException for service response error code // ErrCodeInvalidGrantIdException for service response error code
...@@ -230,7 +246,19 @@ const ( ...@@ -230,7 +246,19 @@ const (
// ErrCodeInvalidKeyUsageException for service response error code // ErrCodeInvalidKeyUsageException for service response error code
// "InvalidKeyUsageException". // "InvalidKeyUsageException".
// //
// The request was rejected because the specified KeySpec value is not valid. // The request was rejected for one of the following reasons:
//
// * The KeyUsage value of the CMK is incompatible with the API operation.
//
// * The encryption algorithm or signing algorithm specified for the operation
// is incompatible with the type of key material in the CMK (CustomerMasterKeySpec).
//
// For encrypting, decrypting, re-encrypting, and generating data keys, the
// KeyUsage must be ENCRYPT_DECRYPT. For signing and verifying, the KeyUsage
// must be SIGN_VERIFY. To find the KeyUsage of a CMK, use the DescribeKey operation.
//
// To find the encryption or signing algorithms supported for a particular CMK,
// use the DescribeKey operation.
ErrCodeInvalidKeyUsageException = "InvalidKeyUsageException" ErrCodeInvalidKeyUsageException = "InvalidKeyUsageException"
// ErrCodeInvalidMarkerException for service response error code // ErrCodeInvalidMarkerException for service response error code
...@@ -248,14 +276,22 @@ const ( ...@@ -248,14 +276,22 @@ const (
// //
// For more information about how key state affects the use of a CMK, see How // For more information about how key state affects the use of a CMK, see How
// Key State Affects Use of a Customer Master Key (https://docs.aws.amazon.com/kms/latest/developerguide/key-state.html) // Key State Affects Use of a Customer Master Key (https://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide. // in the AWS Key Management Service Developer Guide .
ErrCodeInvalidStateException = "KMSInvalidStateException" ErrCodeInvalidStateException = "KMSInvalidStateException"
// ErrCodeKMSInvalidSignatureException for service response error code
// "KMSInvalidSignatureException".
//
// The request was rejected because the signature verification failed. Signature
// verification fails when it cannot confirm that signature was produced by
// signing the specified message with the specified CMK and signing algorithm.
ErrCodeKMSInvalidSignatureException = "KMSInvalidSignatureException"
// ErrCodeKeyUnavailableException for service response error code // ErrCodeKeyUnavailableException for service response error code
// "KeyUnavailableException". // "KeyUnavailableException".
// //
// The request was rejected because the specified CMK was not available. The // The request was rejected because the specified CMK was not available. You
// request can be retried. // can retry the request.
ErrCodeKeyUnavailableException = "KeyUnavailableException" ErrCodeKeyUnavailableException = "KeyUnavailableException"
// ErrCodeLimitExceededException for service response error code // ErrCodeLimitExceededException for service response error code
...@@ -293,3 +329,39 @@ const ( ...@@ -293,3 +329,39 @@ const (
// a specified resource is not valid for this operation. // a specified resource is not valid for this operation.
ErrCodeUnsupportedOperationException = "UnsupportedOperationException" ErrCodeUnsupportedOperationException = "UnsupportedOperationException"
) )
var exceptionFromCode = map[string]func(protocol.ResponseMetadata) error{
"AlreadyExistsException": newErrorAlreadyExistsException,
"CloudHsmClusterInUseException": newErrorCloudHsmClusterInUseException,
"CloudHsmClusterInvalidConfigurationException": newErrorCloudHsmClusterInvalidConfigurationException,
"CloudHsmClusterNotActiveException": newErrorCloudHsmClusterNotActiveException,
"CloudHsmClusterNotFoundException": newErrorCloudHsmClusterNotFoundException,
"CloudHsmClusterNotRelatedException": newErrorCloudHsmClusterNotRelatedException,
"CustomKeyStoreHasCMKsException": newErrorCustomKeyStoreHasCMKsException,
"CustomKeyStoreInvalidStateException": newErrorCustomKeyStoreInvalidStateException,
"CustomKeyStoreNameInUseException": newErrorCustomKeyStoreNameInUseException,
"CustomKeyStoreNotFoundException": newErrorCustomKeyStoreNotFoundException,
"DependencyTimeoutException": newErrorDependencyTimeoutException,
"DisabledException": newErrorDisabledException,
"ExpiredImportTokenException": newErrorExpiredImportTokenException,
"IncorrectKeyException": newErrorIncorrectKeyException,
"IncorrectKeyMaterialException": newErrorIncorrectKeyMaterialException,
"IncorrectTrustAnchorException": newErrorIncorrectTrustAnchorException,
"KMSInternalException": newErrorInternalException,
"InvalidAliasNameException": newErrorInvalidAliasNameException,
"InvalidArnException": newErrorInvalidArnException,
"InvalidCiphertextException": newErrorInvalidCiphertextException,
"InvalidGrantIdException": newErrorInvalidGrantIdException,
"InvalidGrantTokenException": newErrorInvalidGrantTokenException,
"InvalidImportTokenException": newErrorInvalidImportTokenException,
"InvalidKeyUsageException": newErrorInvalidKeyUsageException,
"InvalidMarkerException": newErrorInvalidMarkerException,
"KMSInvalidStateException": newErrorInvalidStateException,
"KMSInvalidSignatureException": newErrorKMSInvalidSignatureException,
"KeyUnavailableException": newErrorKeyUnavailableException,
"LimitExceededException": newErrorLimitExceededException,
"MalformedPolicyDocumentException": newErrorMalformedPolicyDocumentException,
"NotFoundException": newErrorNotFoundException,
"TagException": newErrorTagException,
"UnsupportedOperationException": newErrorUnsupportedOperationException,
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment