mirror of
https://github.com/kubernetes-sigs/descheduler.git
synced 2026-01-26 05:14:13 +01:00
Bump to k8s 1.25-rc.0
This commit is contained in:
@@ -33,9 +33,8 @@ import (
|
|||||||
apiserver "k8s.io/apiserver/pkg/server"
|
apiserver "k8s.io/apiserver/pkg/server"
|
||||||
"k8s.io/apiserver/pkg/server/mux"
|
"k8s.io/apiserver/pkg/server/mux"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/component-base/config"
|
registry "k8s.io/component-base/logs/api/v1"
|
||||||
_ "k8s.io/component-base/logs/json/register"
|
_ "k8s.io/component-base/logs/json/register"
|
||||||
"k8s.io/component-base/logs/registry"
|
|
||||||
"k8s.io/component-base/metrics/legacyregistry"
|
"k8s.io/component-base/metrics/legacyregistry"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
)
|
)
|
||||||
@@ -62,12 +61,14 @@ func NewDeschedulerCommand(out io.Writer) *cobra.Command {
|
|||||||
klog.ErrorS(err, "failed to apply secure server configuration")
|
klog.ErrorS(err, "failed to apply secure server configuration")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var factory registry.LogFormatFactory
|
||||||
factory, _ := registry.LogRegistry.Get(s.Logging.Format)
|
|
||||||
if factory == nil {
|
if factory == nil {
|
||||||
klog.ClearLogger()
|
klog.ClearLogger()
|
||||||
} else {
|
} else {
|
||||||
log, logrFlush := factory.Create(config.LoggingConfiguration{})
|
log, logrFlush := factory.Create(registry.LoggingConfiguration{
|
||||||
|
Format: s.Logging.Format,
|
||||||
|
})
|
||||||
|
|
||||||
defer logrFlush()
|
defer logrFlush()
|
||||||
klog.SetLogger(log)
|
klog.SetLogger(log)
|
||||||
}
|
}
|
||||||
|
|||||||
69
go.mod
69
go.mod
@@ -6,27 +6,20 @@ require (
|
|||||||
github.com/client9/misspell v0.3.4
|
github.com/client9/misspell v0.3.4
|
||||||
github.com/spf13/cobra v1.4.0
|
github.com/spf13/cobra v1.4.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
k8s.io/api v0.24.0
|
k8s.io/api v0.25.0-rc.0
|
||||||
k8s.io/apimachinery v0.24.0
|
k8s.io/apimachinery v0.25.0-rc.0
|
||||||
k8s.io/apiserver v0.24.0
|
k8s.io/apiserver v0.25.0-rc.0
|
||||||
k8s.io/client-go v0.24.0
|
k8s.io/client-go v0.25.0-rc.0
|
||||||
k8s.io/code-generator v0.24.0
|
k8s.io/code-generator v0.25.0-rc.0
|
||||||
k8s.io/component-base v0.24.0
|
k8s.io/component-base v0.25.0-rc.0
|
||||||
k8s.io/component-helpers v0.24.0
|
k8s.io/component-helpers v0.25.0-rc.0
|
||||||
k8s.io/klog/v2 v2.60.1
|
k8s.io/klog/v2 v2.70.1
|
||||||
k8s.io/kubectl v0.20.5
|
k8s.io/kubectl v0.20.5
|
||||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9
|
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed
|
||||||
sigs.k8s.io/mdtoc v1.0.1
|
sigs.k8s.io/mdtoc v1.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.81.0 // indirect
|
|
||||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
|
||||||
github.com/Azure/go-autorest/autorest v0.11.18 // indirect
|
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect
|
|
||||||
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
|
||||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
|
||||||
github.com/BurntSushi/toml v0.3.1 // indirect
|
github.com/BurntSushi/toml v0.3.1 // indirect
|
||||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||||
@@ -37,13 +30,12 @@ require (
|
|||||||
github.com/coreos/go-semver v0.3.0 // indirect
|
github.com/coreos/go-semver v0.3.0 // indirect
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/emicklei/go-restful v2.9.5+incompatible // indirect
|
github.com/emicklei/go-restful/v3 v3.8.0 // indirect
|
||||||
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
|
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.1 // indirect
|
github.com/felixge/httpsnoop v1.0.1 // indirect
|
||||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
|
|
||||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||||
github.com/go-logr/logr v1.2.0 // indirect
|
github.com/go-logr/logr v1.2.3 // indirect
|
||||||
github.com/go-logr/zapr v1.2.0 // indirect
|
github.com/go-logr/zapr v1.2.3 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.19.5 // indirect
|
github.com/go-openapi/jsonreference v0.19.5 // indirect
|
||||||
github.com/go-openapi/swag v0.19.14 // indirect
|
github.com/go-openapi/swag v0.19.14 // indirect
|
||||||
@@ -52,12 +44,12 @@ require (
|
|||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
github.com/gomarkdown/markdown v0.0.0-20200824053859-8c8b3816f167 // indirect
|
github.com/gomarkdown/markdown v0.0.0-20200824053859-8c8b3816f167 // indirect
|
||||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||||
github.com/google/go-cmp v0.5.5 // indirect
|
github.com/google/go-cmp v0.5.6 // indirect
|
||||||
github.com/google/gofuzz v1.1.0 // indirect
|
github.com/google/gofuzz v1.1.0 // indirect
|
||||||
github.com/google/uuid v1.1.2 // indirect
|
github.com/google/uuid v1.1.2 // indirect
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
|
||||||
github.com/imdario/mergo v0.3.5 // indirect
|
github.com/imdario/mergo v0.3.6 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
@@ -72,9 +64,9 @@ require (
|
|||||||
github.com/prometheus/client_model v0.2.0 // indirect
|
github.com/prometheus/client_model v0.2.0 // indirect
|
||||||
github.com/prometheus/common v0.32.1 // indirect
|
github.com/prometheus/common v0.32.1 // indirect
|
||||||
github.com/prometheus/procfs v0.7.3 // indirect
|
github.com/prometheus/procfs v0.7.3 // indirect
|
||||||
go.etcd.io/etcd/api/v3 v3.5.1 // indirect
|
go.etcd.io/etcd/api/v3 v3.5.4 // indirect
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.1 // indirect
|
go.etcd.io/etcd/client/pkg/v3 v3.5.4 // indirect
|
||||||
go.etcd.io/etcd/client/v3 v3.5.1 // indirect
|
go.etcd.io/etcd/client/v3 v3.5.4 // indirect
|
||||||
go.opentelemetry.io/contrib v0.20.0 // indirect
|
go.opentelemetry.io/contrib v0.20.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 // indirect
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 // indirect
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0 // indirect
|
||||||
@@ -90,28 +82,27 @@ require (
|
|||||||
go.uber.org/multierr v1.6.0 // indirect
|
go.uber.org/multierr v1.6.0 // indirect
|
||||||
go.uber.org/zap v1.19.0 // indirect
|
go.uber.org/zap v1.19.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 // indirect
|
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 // indirect
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
||||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||||
golang.org/x/text v0.3.7 // indirect
|
golang.org/x/text v0.3.7 // indirect
|
||||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
|
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
|
||||||
golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717 // indirect
|
golang.org/x/tools v0.1.12 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 // indirect
|
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect
|
||||||
google.golang.org/grpc v1.40.0 // indirect
|
google.golang.org/grpc v1.47.0 // indirect
|
||||||
google.golang.org/protobuf v1.27.1 // indirect
|
google.golang.org/protobuf v1.28.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect
|
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 // indirect
|
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30 // indirect
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
|
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||||
sigs.k8s.io/yaml v1.2.0 // indirect
|
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
280
go.sum
280
go.sum
@@ -13,12 +13,7 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
|
|||||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8=
|
||||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
|
||||||
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
|
||||||
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
|
||||||
cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8=
|
|
||||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||||
@@ -39,25 +34,14 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
|
|||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
|
||||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
|
||||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||||
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
|
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
|
||||||
github.com/Azure/go-autorest/autorest v0.11.18 h1:90Y4srNYrwOtAgVo3ndrQkTYn6kf1Eg/AjTFJ8Is2aM=
|
|
||||||
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
|
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
|
github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q=
|
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
|
||||||
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
|
||||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||||
github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk=
|
|
||||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
|
||||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
@@ -80,7 +64,6 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd
|
|||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
|
||||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||||
@@ -95,8 +78,6 @@ github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb
|
|||||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
|
||||||
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
|
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||||
@@ -108,15 +89,13 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
|
|||||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||||
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
|
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
|
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
|
|
||||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
@@ -126,7 +105,6 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
|
|||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -140,15 +118,15 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4
|
|||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||||
github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
|
|
||||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||||
|
github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw=
|
||||||
|
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
|
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
|
||||||
@@ -160,13 +138,10 @@ github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8S
|
|||||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=
|
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||||
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
|
|
||||||
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
|
||||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
@@ -180,10 +155,12 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
|
|||||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||||
github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE=
|
|
||||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro=
|
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||||
|
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A=
|
||||||
|
github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4=
|
||||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||||
@@ -218,7 +195,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
|||||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
@@ -234,7 +210,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
|
|||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
|
||||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
|
github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
|
||||||
@@ -245,7 +220,6 @@ github.com/gomarkdown/markdown v0.0.0-20200824053859-8c8b3816f167/go.mod h1:aii0
|
|||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
|
||||||
github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
|
github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
|
||||||
github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
|
github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
@@ -256,16 +230,15 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||||
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
@@ -273,10 +246,6 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
|
|||||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||||
@@ -285,13 +254,11 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
|||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
|
||||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
@@ -319,14 +286,13 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
|
|||||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
|
|
||||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
|
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
||||||
|
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
|
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
|
||||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||||
@@ -346,7 +312,6 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
|
|||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
@@ -380,9 +345,7 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
|
|||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mmarkdown/mmark v2.0.40+incompatible h1:vMeUeDzBK3H+/mU0oMVfMuhSXJlIA+DE/DMPQNAj5C4=
|
github.com/mmarkdown/mmark v2.0.40+incompatible h1:vMeUeDzBK3H+/mU0oMVfMuhSXJlIA+DE/DMPQNAj5C4=
|
||||||
github.com/mmarkdown/mmark v2.0.40+incompatible/go.mod h1:Uvmoz7tvsWpr7bMVxIpqZPyN3FbOtzDmnsJDFp7ltJs=
|
github.com/mmarkdown/mmark v2.0.40+incompatible/go.mod h1:Uvmoz7tvsWpr7bMVxIpqZPyN3FbOtzDmnsJDFp7ltJs=
|
||||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
|
||||||
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
|
||||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
@@ -398,22 +361,16 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
|
|||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
|
||||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY=
|
||||||
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
|
|
||||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
|
||||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
|
||||||
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
|
||||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
@@ -421,16 +378,15 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||||
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
|
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||||
|
github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||||
github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
|
github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
|
||||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
@@ -466,22 +422,17 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
|
|||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
|
||||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
|
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
|
||||||
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
|
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
|
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
|
||||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
|
||||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
|
||||||
github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q=
|
github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q=
|
||||||
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
|
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
@@ -504,7 +455,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
@@ -512,34 +462,23 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
|
||||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
go.etcd.io/etcd/api/v3 v3.5.4 h1:OHVyt3TopwtUQ2GKdd5wu3PmmipR4FTwCqoEjSyRdIc=
|
||||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
|
||||||
go.etcd.io/etcd/api/v3 v3.5.1 h1:v28cktvBq+7vGyJXF8G+rWJmj+1XUmMtqcLnH8hDocM=
|
go.etcd.io/etcd/client/pkg/v3 v3.5.4 h1:lrneYvz923dvC14R54XcA7FXoZ3mlGZAgmwhfm7HqOg=
|
||||||
go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
go.etcd.io/etcd/client/v2 v2.305.4 h1:Dcx3/MYyfKcPNLpR4VVQUP5KgYrBeJtktBwEKkw08Ao=
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.1 h1:XIQcHCFSG53bJETYeRJtIxdLv2EWRGxcfzR8lSnTH4E=
|
go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4=
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
|
||||||
go.etcd.io/etcd/client/v2 v2.305.0 h1:ftQ0nOOHMcbMS3KIaDQ0g5Qcd6bhaBrQT6b89DfwLTs=
|
go.etcd.io/etcd/pkg/v3 v3.5.4 h1:V5Dvl7S39ZDwjkKqJG2BfXgxZ3QREqqKifWQgIw5IM0=
|
||||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
go.etcd.io/etcd/raft/v3 v3.5.4 h1:YGrnAgRfgXloBNuqa+oBI/aRZMcK/1GS6trJePJ/Gqc=
|
||||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
go.etcd.io/etcd/server/v3 v3.5.4 h1:CMAZd0g8Bn5NRhynW6pKhc4FRg41/0QYy3d7aNm9874=
|
||||||
go.etcd.io/etcd/client/v3 v3.5.1 h1:oImGuV5LGKjCqXdjkMHCyWa5OO1gYKCnC/1sgdfj1Uk=
|
|
||||||
go.etcd.io/etcd/client/v3 v3.5.1/go.mod h1:OnjH4M8OnAotwaB2l9bVgZzRFKru7/ZMoS46OtKyd3Q=
|
|
||||||
go.etcd.io/etcd/pkg/v3 v3.5.0 h1:ntrg6vvKRW26JRmHTE0iNlDgYK6JX3hg/4cD62X0ixk=
|
|
||||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE=
|
|
||||||
go.etcd.io/etcd/raft/v3 v3.5.0 h1:kw2TmO3yFTgE+F0mdKkG7xMxkit2duBDa2Hu6D/HMlw=
|
|
||||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc=
|
|
||||||
go.etcd.io/etcd/server/v3 v3.5.0 h1:jk8D/lwGEDlQU9kZXUFMSANkE22Sg5+mW27ip8xcF9E=
|
|
||||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4=
|
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
|
||||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
|
||||||
go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0=
|
go.opentelemetry.io/contrib v0.20.0 h1:ubFQUn0VCZ0gPwIoJfBJVpeBlyRMxu8Mm/huKWYd9p0=
|
||||||
go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc=
|
go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc=
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 h1:sO4WKdPAudZGKPcpZT4MJn6JaDmpyLrMPDGGyA1SttE=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0 h1:sO4WKdPAudZGKPcpZT4MJn6JaDmpyLrMPDGGyA1SttE=
|
||||||
@@ -583,12 +522,9 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
|
||||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
||||||
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 h1:SLP7Q4Di66FONjDJbCYrCRrh97focO6sLogHO7/g8F0=
|
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 h1:SLP7Q4Di66FONjDJbCYrCRrh97focO6sLogHO7/g8F0=
|
||||||
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@@ -613,7 +549,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
|
|||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||||
@@ -624,11 +559,9 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
|||||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -658,36 +591,21 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
|
|||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
|
|
||||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
|
||||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
@@ -701,8 +619,9 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -720,11 +639,8 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -739,36 +655,23 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
|
||||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@@ -786,7 +689,6 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
|
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
|
||||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@@ -839,17 +741,10 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
|
|||||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
|
||||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
|
||||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||||
golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717 h1:hI3jKY4Hpf63ns040onEbB3dAkR/H/P83hw1TG8dD3Y=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -871,11 +766,6 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
|
|||||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
|
||||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
|
||||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
|
||||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
|
||||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
@@ -905,7 +795,6 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG
|
|||||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
@@ -915,20 +804,10 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
|
|||||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
|
||||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||||
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 h1:Et6SkiuvnBn+SgrSYXs/BrUpGB4mbdwt4R3vaPIlicA=
|
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I=
|
||||||
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
@@ -941,17 +820,13 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
|
|||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
|
||||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
|
||||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
|
||||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
|
||||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||||
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
|
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=
|
||||||
|
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
@@ -964,8 +839,9 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
|||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
|
||||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
|
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||||
|
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
@@ -980,8 +856,6 @@ gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
@@ -995,11 +869,11 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
|||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
@@ -1008,59 +882,57 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
|
|||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/api v0.20.5/go.mod h1:FQjAceXnVaWDeov2YUWhOb6Yt+5UjErkp6UO3nczO1Y=
|
k8s.io/api v0.20.5/go.mod h1:FQjAceXnVaWDeov2YUWhOb6Yt+5UjErkp6UO3nczO1Y=
|
||||||
k8s.io/api v0.24.0 h1:J0hann2hfxWr1hinZIDefw7Q96wmCBx6SSB8IY0MdDg=
|
k8s.io/api v0.25.0-rc.0 h1:JzQmjOfEAkOyCzDyFTayWB3nCQeS4TcCldrl2Q+417g=
|
||||||
k8s.io/api v0.24.0/go.mod h1:5Jl90IUrJHUJYEMANRURMiVvJ0g7Ax7r3R1bqO8zx8I=
|
k8s.io/api v0.25.0-rc.0/go.mod h1:H8qkBzdcUEFJEhgA14ip3PpzUFN0XXPgnlDnu/KaDf0=
|
||||||
k8s.io/apimachinery v0.20.5/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
k8s.io/apimachinery v0.20.5/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||||
k8s.io/apimachinery v0.24.0 h1:ydFCyC/DjCvFCHK5OPMKBlxayQytB8pxy8YQInd5UyQ=
|
k8s.io/apimachinery v0.25.0-rc.0 h1:k3n1k01fFHrTsRHM8xt+z9yOpak7KmO/pbmD0/tAkzs=
|
||||||
k8s.io/apimachinery v0.24.0/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
|
k8s.io/apimachinery v0.25.0-rc.0/go.mod h1:qMx9eAk0sZQGsXGu86fab8tZdffHbwUfsvzqKn4mfB0=
|
||||||
k8s.io/apiserver v0.24.0 h1:GR7kGsjOMfilRvlG3Stxv/3uz/ryvJ/aZXc5pqdsNV0=
|
k8s.io/apiserver v0.25.0-rc.0 h1:PCLYM37Cq9SEbb6jFhA1E7NpfW6GddG2AzgECMU5jlw=
|
||||||
k8s.io/apiserver v0.24.0/go.mod h1:WFx2yiOMawnogNToVvUYT9nn1jaIkMKj41ZYCVycsBA=
|
k8s.io/apiserver v0.25.0-rc.0/go.mod h1:a6uerzON2mpu3JWvoU+MZEj491B0faS6J0w8e10ZOy8=
|
||||||
k8s.io/cli-runtime v0.20.5/go.mod h1:ihjPeQWDk7NGVIkNEvpwxA3gJvqtU+LtkDj11TvyXn4=
|
k8s.io/cli-runtime v0.20.5/go.mod h1:ihjPeQWDk7NGVIkNEvpwxA3gJvqtU+LtkDj11TvyXn4=
|
||||||
k8s.io/client-go v0.20.5/go.mod h1:Ee5OOMMYvlH8FCZhDsacjMlCBwetbGZETwo1OA+e6Zw=
|
k8s.io/client-go v0.20.5/go.mod h1:Ee5OOMMYvlH8FCZhDsacjMlCBwetbGZETwo1OA+e6Zw=
|
||||||
k8s.io/client-go v0.24.0 h1:lbE4aB1gTHvYFSwm6eD3OF14NhFDKCejlnsGYlSJe5U=
|
k8s.io/client-go v0.25.0-rc.0 h1:KL7AczVvcnYc8FpU04Cr8fIe8xwgFnU/UTrc/I73vgQ=
|
||||||
k8s.io/client-go v0.24.0/go.mod h1:VFPQET+cAFpYxh6Bq6f4xyMY80G6jKKktU6G0m00VDw=
|
k8s.io/client-go v0.25.0-rc.0/go.mod h1:XjkJ50b7aujTzt+YY6krr3tthIEunuABtlw414f80EU=
|
||||||
k8s.io/code-generator v0.20.5/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
|
k8s.io/code-generator v0.20.5/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
|
||||||
k8s.io/code-generator v0.24.0 h1:7v52LjqCntfGxV9x8c57gkhDqkMHd0Z2jfRqGr6it6g=
|
k8s.io/code-generator v0.25.0-rc.0 h1:nan4F7AjF1ObxV/4PNUUYCYqDK7MV76xX7aoK9dQ1uw=
|
||||||
k8s.io/code-generator v0.24.0/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w=
|
k8s.io/code-generator v0.25.0-rc.0/go.mod h1:B6jZgI3DvDFAualltPitbYMQ74NjaCFxum3YeKZZ+3w=
|
||||||
k8s.io/component-base v0.20.5/go.mod h1:l0isoBLGyQKwRoTWbPHR6jNDd3/VqQD43cNlsjddGng=
|
k8s.io/component-base v0.20.5/go.mod h1:l0isoBLGyQKwRoTWbPHR6jNDd3/VqQD43cNlsjddGng=
|
||||||
k8s.io/component-base v0.24.0 h1:h5jieHZQoHrY/lHG+HyrSbJeyfuitheBvqvKwKHVC0g=
|
k8s.io/component-base v0.25.0-rc.0 h1:2zlYDXYA5DhMmyhIMR5Ekktb2WfAs3Euc138ymPgnCA=
|
||||||
k8s.io/component-base v0.24.0/go.mod h1:Dgazgon0i7KYUsS8krG8muGiMVtUZxG037l1MKyXgrA=
|
k8s.io/component-base v0.25.0-rc.0/go.mod h1:zDon61JoEHGHW3yhXG/7z0urHK9a/Qgk85g7sh3QWCc=
|
||||||
k8s.io/component-helpers v0.20.5/go.mod h1:AzTdoPj6YAN2SUfhBX/FUUU3ntfFuse03q/VMLovEsE=
|
k8s.io/component-helpers v0.20.5/go.mod h1:AzTdoPj6YAN2SUfhBX/FUUU3ntfFuse03q/VMLovEsE=
|
||||||
k8s.io/component-helpers v0.24.0 h1:hZIHGfdd55thhqd9oxjDTw68OAPauDMJ+8hC69aNw1I=
|
k8s.io/component-helpers v0.25.0-rc.0 h1:qhBrleCmYKT4fghr3QSODg7k1gC16o7bfRwL4OoOA64=
|
||||||
k8s.io/component-helpers v0.24.0/go.mod h1:Q2SlLm4h6g6lPTC9GMMfzdywfLSvJT2f1hOnnjaWD8c=
|
k8s.io/component-helpers v0.25.0-rc.0/go.mod h1:b/Rgjl3TdxI12x4HdPrG2KXm5feuG49SfIa68aRmObY=
|
||||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||||
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
|
||||||
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 h1:TT1WdmqqXareKxZ/oNXEUSwKlLiHzPMyB0t8BaFeBYI=
|
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 h1:TT1WdmqqXareKxZ/oNXEUSwKlLiHzPMyB0t8BaFeBYI=
|
||||||
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
k8s.io/klog/v2 v2.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc=
|
k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
|
||||||
k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||||
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42 h1:Gii5eqf+GmIEwGNKQYQClCayuJCe2/4fZUvF7VG99sU=
|
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA=
|
||||||
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk=
|
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU=
|
||||||
k8s.io/kubectl v0.20.5 h1:/wndy8hw5TsL8G8KWPDJrtPKS8D34uSdWS0BMRmtzWs=
|
k8s.io/kubectl v0.20.5 h1:/wndy8hw5TsL8G8KWPDJrtPKS8D34uSdWS0BMRmtzWs=
|
||||||
k8s.io/kubectl v0.20.5/go.mod h1:mlNQgyV18D4XFt5BmfSkrxQNS+arT2pXDQxxnH5lMiw=
|
k8s.io/kubectl v0.20.5/go.mod h1:mlNQgyV18D4XFt5BmfSkrxQNS+arT2pXDQxxnH5lMiw=
|
||||||
k8s.io/metrics v0.20.5/go.mod h1:vsptOayjKWKWHvWR1vFQY++vxydzaEo/2+JC7kSDKPU=
|
k8s.io/metrics v0.20.5/go.mod h1:vsptOayjKWKWHvWR1vFQY++vxydzaEo/2+JC7kSDKPU=
|
||||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4=
|
||||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19Vz2GdbOCyI4qqhc=
|
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30 h1:dUk62HQ3ZFhD48Qr8MIXCiKA8wInBQCtuE4QGfFW7yA=
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ=
|
||||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
|
||||||
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
|
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
|
||||||
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
|
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||||
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
||||||
sigs.k8s.io/mdtoc v1.0.1 h1:6ECKhQnbetwZBR6R2IeT2LH+1w+2Zsip0iXjikgaXIk=
|
sigs.k8s.io/mdtoc v1.0.1 h1:6ECKhQnbetwZBR6R2IeT2LH+1w+2Zsip0iXjikgaXIk=
|
||||||
sigs.k8s.io/mdtoc v1.0.1/go.mod h1:COYBtOjsaCg7o7SC4eaLwEXPuVRSuiVuLLRrHd7kShw=
|
sigs.k8s.io/mdtoc v1.0.1/go.mod h1:COYBtOjsaCg7o7SC4eaLwEXPuVRSuiVuLLRrHd7kShw=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
|
||||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import (
|
|||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
componentbaseconfig "k8s.io/component-base/config"
|
componentbaseconfig "k8s.io/component-base/config"
|
||||||
|
registry "k8s.io/component-base/logs/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
@@ -57,6 +58,6 @@ type DeschedulerConfiguration struct {
|
|||||||
LeaderElection componentbaseconfig.LeaderElectionConfiguration
|
LeaderElection componentbaseconfig.LeaderElectionConfiguration
|
||||||
|
|
||||||
// Logging specifies the options of logging.
|
// Logging specifies the options of logging.
|
||||||
// Refer [Logs Options](https://github.com/kubernetes/component-base/blob/master/logs/options.go) for more information.
|
// Refer [Logs Options](https://github.com/kubernetes/component-base/blob/master/logs/api/v1/options.go) for more information.
|
||||||
Logging componentbaseconfig.LoggingConfiguration
|
Logging registry.LoggingConfiguration
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ package v1alpha1
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
componentbaseconfig "k8s.io/component-base/config"
|
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
componentbaseconfig "k8s.io/component-base/config"
|
||||||
|
registry "k8s.io/component-base/logs/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||||
@@ -58,6 +58,6 @@ type DeschedulerConfiguration struct {
|
|||||||
LeaderElection componentbaseconfig.LeaderElectionConfiguration `json:"leaderElection,omitempty"`
|
LeaderElection componentbaseconfig.LeaderElectionConfiguration `json:"leaderElection,omitempty"`
|
||||||
|
|
||||||
// Logging specifies the options of logging.
|
// Logging specifies the options of logging.
|
||||||
// Refer [Logs Options](https://github.com/kubernetes/component-base/blob/master/logs/options.go) for more information.
|
// Refer [Logs Options](https://github.com/kubernetes/component-base/blob/master/logs/api/v1/options.go) for more information.
|
||||||
Logging componentbaseconfig.LoggingConfiguration `json:"logging,omitempty"`
|
Logging registry.LoggingConfiguration `json:"logging,omitempty"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import (
|
|||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
policy "k8s.io/api/policy/v1beta1"
|
policy "k8s.io/api/policy/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ package descheduler
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
policy "k8s.io/api/policy/v1"
|
||||||
|
//policy "k8s.io/api/policy/v1beta1"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
fakeclientset "k8s.io/client-go/kubernetes/fake"
|
fakeclientset "k8s.io/client-go/kubernetes/fake"
|
||||||
@@ -46,7 +48,7 @@ func TestTaintsUpdated(t *testing.T) {
|
|||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
defer close(errChan)
|
defer close(errChan)
|
||||||
go func() {
|
go func() {
|
||||||
err := RunDeschedulerStrategies(ctx, rs, dp, "v1beta1")
|
err := RunDeschedulerStrategies(ctx, rs, dp, "v1")
|
||||||
errChan <- err
|
errChan <- err
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
@@ -97,7 +99,87 @@ func TestTaintsUpdated(t *testing.T) {
|
|||||||
|
|
||||||
return false, nil
|
return false, nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
t.Fatalf("Unable to evict pod, node taint did not get propagated to descheduler strategies")
|
t.Fatalf("Unable to evict pod, node taint did not get propagated to descheduler strategies %v\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDuplicate(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
node1 := test.BuildTestNode("n1", 2000, 3000, 10, nil)
|
||||||
|
node2 := test.BuildTestNode("n2", 2000, 3000, 10, nil)
|
||||||
|
|
||||||
|
p1 := test.BuildTestPod("p1", 100, 0, node1.Name, nil)
|
||||||
|
p1.Namespace = "dev"
|
||||||
|
p2 := test.BuildTestPod("p2", 100, 0, node1.Name, nil)
|
||||||
|
p2.Namespace = "dev"
|
||||||
|
p3 := test.BuildTestPod("p3", 100, 0, node1.Name, nil)
|
||||||
|
p3.Namespace = "dev"
|
||||||
|
|
||||||
|
ownerRef1 := test.GetReplicaSetOwnerRefList()
|
||||||
|
p1.ObjectMeta.OwnerReferences = ownerRef1
|
||||||
|
p2.ObjectMeta.OwnerReferences = ownerRef1
|
||||||
|
p3.ObjectMeta.OwnerReferences = ownerRef1
|
||||||
|
|
||||||
|
client := fakeclientset.NewSimpleClientset(node1, node2, p1, p2, p3)
|
||||||
|
eventClient := fakeclientset.NewSimpleClientset(node1, node2, p1, p2, p3)
|
||||||
|
dp := &api.DeschedulerPolicy{
|
||||||
|
Strategies: api.StrategyList{
|
||||||
|
"RemoveDuplicates": api.DeschedulerStrategy{
|
||||||
|
Enabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
rs, err := options.NewDeschedulerServer()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to initialize server: %v", err)
|
||||||
|
}
|
||||||
|
rs.Client = client
|
||||||
|
rs.EventClient = eventClient
|
||||||
|
rs.DeschedulingInterval = 100 * time.Millisecond
|
||||||
|
errChan := make(chan error, 1)
|
||||||
|
defer close(errChan)
|
||||||
|
go func() {
|
||||||
|
err := RunDeschedulerStrategies(ctx, rs, dp, "v1")
|
||||||
|
errChan <- err
|
||||||
|
}()
|
||||||
|
select {
|
||||||
|
case err := <-errChan:
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unable to run descheduler strategies: %v", err)
|
||||||
|
}
|
||||||
|
case <-time.After(1 * time.Second):
|
||||||
|
// Wait for few cycles and then verify the only pod still exists
|
||||||
|
}
|
||||||
|
|
||||||
|
pods, err := client.CoreV1().Pods(p1.Namespace).List(ctx, metav1.ListOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unable to list pods: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(pods.Items) != 3 {
|
||||||
|
t.Errorf("Pods number should be 3 before evict")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := wait.PollImmediate(100*time.Millisecond, 5*time.Second, func() (bool, error) {
|
||||||
|
// Get over evicted pod result in panic
|
||||||
|
//pods, err := client.CoreV1().Pods(p1.Namespace).Get(p1.Name, metav1.GetOptions{})
|
||||||
|
// List is better, it does not panic.
|
||||||
|
// Though once the pod is evicted, List starts to error with "can't assign or convert v1beta1.Eviction into v1.Pod"
|
||||||
|
pods, err := client.CoreV1().Pods(p1.Namespace).List(ctx, metav1.ListOptions{})
|
||||||
|
if err == nil {
|
||||||
|
if len(pods.Items) > 2 {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if strings.Contains(err.Error(), "can't assign or convert v1beta1.Eviction into v1.Pod") {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}); err != nil {
|
||||||
|
t.Fatalf("Unable to evict pod, node taint did not get propagated to descheduler strategies %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,3 +252,54 @@ func TestRootCancelWithNoInterval(t *testing.T) {
|
|||||||
t.Fatal("Root ctx should have canceled immediately")
|
t.Fatal("Root ctx should have canceled immediately")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewSimpleClientset(t *testing.T) {
|
||||||
|
client := fakeclientset.NewSimpleClientset()
|
||||||
|
client.CoreV1().Pods("default").Create(context.Background(), &v1.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "pod-1",
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
|
}, metav1.CreateOptions{})
|
||||||
|
client.CoreV1().Pods("default").Create(context.Background(), &v1.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "pod-2",
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
|
}, metav1.CreateOptions{})
|
||||||
|
err := client.CoreV1().Pods("default").EvictV1(context.Background(), &policy.Eviction{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "pod-2",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TestNewSimpleClientset() res = %v", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
pods, err := client.CoreV1().Pods("default").List(context.Background(), metav1.ListOptions{})
|
||||||
|
// err: item[0]: can't assign or convert v1beta1.Eviction into v1.Pod
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TestNewSimpleClientset() res = %v", err.Error())
|
||||||
|
} else {
|
||||||
|
t.Log(len(pods.Items))
|
||||||
|
t.Logf("TestNewSimpleClientset() res = %v", pods)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.PolicyV1().Evictions("default").Evict(context.Background(), &policy.Eviction{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "pod-1",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
pods, err = client.CoreV1().Pods("default").List(context.Background(), metav1.ListOptions{})
|
||||||
|
// err: item[0]: can't assign or convert v1beta1.Eviction into v1.Pod
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("TestNewSimpleClientset() res = %v", err.Error())
|
||||||
|
} else {
|
||||||
|
t.Log(len(pods.Items))
|
||||||
|
t.Logf("TestNewSimpleClientset() res = %v", pods)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
policy "k8s.io/api/policy/v1beta1"
|
policy "k8s.io/api/policy/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
@@ -193,7 +193,7 @@ func evictPod(ctx context.Context, client clientset.Interface, pod *v1.Pod, poli
|
|||||||
},
|
},
|
||||||
DeleteOptions: deleteOptions,
|
DeleteOptions: deleteOptions,
|
||||||
}
|
}
|
||||||
err := client.PolicyV1beta1().Evictions(eviction.Namespace).Evict(ctx, eviction)
|
err := client.PolicyV1().Evictions(eviction.Namespace).Evict(ctx, eviction)
|
||||||
|
|
||||||
if apierrors.IsTooManyRequests(err) {
|
if apierrors.IsTooManyRequests(err) {
|
||||||
return fmt.Errorf("error when evicting pod (ignoring) %q: %v", pod.Name, err)
|
return fmt.Errorf("error when evicting pod (ignoring) %q: %v", pod.Name, err)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
policy "k8s.io/api/policy/v1beta1"
|
policy "k8s.io/api/policy/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
|||||||
202
vendor/cloud.google.com/go/LICENSE
generated
vendored
202
vendor/cloud.google.com/go/LICENSE
generated
vendored
@@ -1,202 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
519
vendor/cloud.google.com/go/compute/metadata/metadata.go
generated
vendored
519
vendor/cloud.google.com/go/compute/metadata/metadata.go
generated
vendored
@@ -1,519 +0,0 @@
|
|||||||
// Copyright 2014 Google LLC
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Package metadata provides access to Google Compute Engine (GCE)
|
|
||||||
// metadata and API service accounts.
|
|
||||||
//
|
|
||||||
// This package is a wrapper around the GCE metadata service,
|
|
||||||
// as documented at https://developers.google.com/compute/docs/metadata.
|
|
||||||
package metadata // import "cloud.google.com/go/compute/metadata"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// metadataIP is the documented metadata server IP address.
|
|
||||||
metadataIP = "169.254.169.254"
|
|
||||||
|
|
||||||
// metadataHostEnv is the environment variable specifying the
|
|
||||||
// GCE metadata hostname. If empty, the default value of
|
|
||||||
// metadataIP ("169.254.169.254") is used instead.
|
|
||||||
// This is variable name is not defined by any spec, as far as
|
|
||||||
// I know; it was made up for the Go package.
|
|
||||||
metadataHostEnv = "GCE_METADATA_HOST"
|
|
||||||
|
|
||||||
userAgent = "gcloud-golang/0.1"
|
|
||||||
)
|
|
||||||
|
|
||||||
type cachedValue struct {
|
|
||||||
k string
|
|
||||||
trim bool
|
|
||||||
mu sync.Mutex
|
|
||||||
v string
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
projID = &cachedValue{k: "project/project-id", trim: true}
|
|
||||||
projNum = &cachedValue{k: "project/numeric-project-id", trim: true}
|
|
||||||
instID = &cachedValue{k: "instance/id", trim: true}
|
|
||||||
)
|
|
||||||
|
|
||||||
var defaultClient = &Client{hc: &http.Client{
|
|
||||||
Transport: &http.Transport{
|
|
||||||
Dial: (&net.Dialer{
|
|
||||||
Timeout: 2 * time.Second,
|
|
||||||
KeepAlive: 30 * time.Second,
|
|
||||||
}).Dial,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
|
|
||||||
// NotDefinedError is returned when requested metadata is not defined.
|
|
||||||
//
|
|
||||||
// The underlying string is the suffix after "/computeMetadata/v1/".
|
|
||||||
//
|
|
||||||
// This error is not returned if the value is defined to be the empty
|
|
||||||
// string.
|
|
||||||
type NotDefinedError string
|
|
||||||
|
|
||||||
func (suffix NotDefinedError) Error() string {
|
|
||||||
return fmt.Sprintf("metadata: GCE metadata %q not defined", string(suffix))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *cachedValue) get(cl *Client) (v string, err error) {
|
|
||||||
defer c.mu.Unlock()
|
|
||||||
c.mu.Lock()
|
|
||||||
if c.v != "" {
|
|
||||||
return c.v, nil
|
|
||||||
}
|
|
||||||
if c.trim {
|
|
||||||
v, err = cl.getTrimmed(c.k)
|
|
||||||
} else {
|
|
||||||
v, err = cl.Get(c.k)
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
c.v = v
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
onGCEOnce sync.Once
|
|
||||||
onGCE bool
|
|
||||||
)
|
|
||||||
|
|
||||||
// OnGCE reports whether this process is running on Google Compute Engine.
|
|
||||||
func OnGCE() bool {
|
|
||||||
onGCEOnce.Do(initOnGCE)
|
|
||||||
return onGCE
|
|
||||||
}
|
|
||||||
|
|
||||||
func initOnGCE() {
|
|
||||||
onGCE = testOnGCE()
|
|
||||||
}
|
|
||||||
|
|
||||||
func testOnGCE() bool {
|
|
||||||
// The user explicitly said they're on GCE, so trust them.
|
|
||||||
if os.Getenv(metadataHostEnv) != "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
resc := make(chan bool, 2)
|
|
||||||
|
|
||||||
// Try two strategies in parallel.
|
|
||||||
// See https://github.com/googleapis/google-cloud-go/issues/194
|
|
||||||
go func() {
|
|
||||||
req, _ := http.NewRequest("GET", "http://"+metadataIP, nil)
|
|
||||||
req.Header.Set("User-Agent", userAgent)
|
|
||||||
res, err := defaultClient.hc.Do(req.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
resc <- false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
resc <- res.Header.Get("Metadata-Flavor") == "Google"
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
addrs, err := net.DefaultResolver.LookupHost(ctx, "metadata.google.internal")
|
|
||||||
if err != nil || len(addrs) == 0 {
|
|
||||||
resc <- false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
resc <- strsContains(addrs, metadataIP)
|
|
||||||
}()
|
|
||||||
|
|
||||||
tryHarder := systemInfoSuggestsGCE()
|
|
||||||
if tryHarder {
|
|
||||||
res := <-resc
|
|
||||||
if res {
|
|
||||||
// The first strategy succeeded, so let's use it.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// Wait for either the DNS or metadata server probe to
|
|
||||||
// contradict the other one and say we are running on
|
|
||||||
// GCE. Give it a lot of time to do so, since the system
|
|
||||||
// info already suggests we're running on a GCE BIOS.
|
|
||||||
timer := time.NewTimer(5 * time.Second)
|
|
||||||
defer timer.Stop()
|
|
||||||
select {
|
|
||||||
case res = <-resc:
|
|
||||||
return res
|
|
||||||
case <-timer.C:
|
|
||||||
// Too slow. Who knows what this system is.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There's no hint from the system info that we're running on
|
|
||||||
// GCE, so use the first probe's result as truth, whether it's
|
|
||||||
// true or false. The goal here is to optimize for speed for
|
|
||||||
// users who are NOT running on GCE. We can't assume that
|
|
||||||
// either a DNS lookup or an HTTP request to a blackholed IP
|
|
||||||
// address is fast. Worst case this should return when the
|
|
||||||
// metaClient's Transport.ResponseHeaderTimeout or
|
|
||||||
// Transport.Dial.Timeout fires (in two seconds).
|
|
||||||
return <-resc
|
|
||||||
}
|
|
||||||
|
|
||||||
// systemInfoSuggestsGCE reports whether the local system (without
|
|
||||||
// doing network requests) suggests that we're running on GCE. If this
|
|
||||||
// returns true, testOnGCE tries a bit harder to reach its metadata
|
|
||||||
// server.
|
|
||||||
func systemInfoSuggestsGCE() bool {
|
|
||||||
if runtime.GOOS != "linux" {
|
|
||||||
// We don't have any non-Linux clues available, at least yet.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
slurp, _ := ioutil.ReadFile("/sys/class/dmi/id/product_name")
|
|
||||||
name := strings.TrimSpace(string(slurp))
|
|
||||||
return name == "Google" || name == "Google Compute Engine"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subscribe calls Client.Subscribe on the default client.
|
|
||||||
func Subscribe(suffix string, fn func(v string, ok bool) error) error {
|
|
||||||
return defaultClient.Subscribe(suffix, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get calls Client.Get on the default client.
|
|
||||||
func Get(suffix string) (string, error) { return defaultClient.Get(suffix) }
|
|
||||||
|
|
||||||
// ProjectID returns the current instance's project ID string.
|
|
||||||
func ProjectID() (string, error) { return defaultClient.ProjectID() }
|
|
||||||
|
|
||||||
// NumericProjectID returns the current instance's numeric project ID.
|
|
||||||
func NumericProjectID() (string, error) { return defaultClient.NumericProjectID() }
|
|
||||||
|
|
||||||
// InternalIP returns the instance's primary internal IP address.
|
|
||||||
func InternalIP() (string, error) { return defaultClient.InternalIP() }
|
|
||||||
|
|
||||||
// ExternalIP returns the instance's primary external (public) IP address.
|
|
||||||
func ExternalIP() (string, error) { return defaultClient.ExternalIP() }
|
|
||||||
|
|
||||||
// Email calls Client.Email on the default client.
|
|
||||||
func Email(serviceAccount string) (string, error) { return defaultClient.Email(serviceAccount) }
|
|
||||||
|
|
||||||
// Hostname returns the instance's hostname. This will be of the form
|
|
||||||
// "<instanceID>.c.<projID>.internal".
|
|
||||||
func Hostname() (string, error) { return defaultClient.Hostname() }
|
|
||||||
|
|
||||||
// InstanceTags returns the list of user-defined instance tags,
|
|
||||||
// assigned when initially creating a GCE instance.
|
|
||||||
func InstanceTags() ([]string, error) { return defaultClient.InstanceTags() }
|
|
||||||
|
|
||||||
// InstanceID returns the current VM's numeric instance ID.
|
|
||||||
func InstanceID() (string, error) { return defaultClient.InstanceID() }
|
|
||||||
|
|
||||||
// InstanceName returns the current VM's instance ID string.
|
|
||||||
func InstanceName() (string, error) { return defaultClient.InstanceName() }
|
|
||||||
|
|
||||||
// Zone returns the current VM's zone, such as "us-central1-b".
|
|
||||||
func Zone() (string, error) { return defaultClient.Zone() }
|
|
||||||
|
|
||||||
// InstanceAttributes calls Client.InstanceAttributes on the default client.
|
|
||||||
func InstanceAttributes() ([]string, error) { return defaultClient.InstanceAttributes() }
|
|
||||||
|
|
||||||
// ProjectAttributes calls Client.ProjectAttributes on the default client.
|
|
||||||
func ProjectAttributes() ([]string, error) { return defaultClient.ProjectAttributes() }
|
|
||||||
|
|
||||||
// InstanceAttributeValue calls Client.InstanceAttributeValue on the default client.
|
|
||||||
func InstanceAttributeValue(attr string) (string, error) {
|
|
||||||
return defaultClient.InstanceAttributeValue(attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectAttributeValue calls Client.ProjectAttributeValue on the default client.
|
|
||||||
func ProjectAttributeValue(attr string) (string, error) {
|
|
||||||
return defaultClient.ProjectAttributeValue(attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scopes calls Client.Scopes on the default client.
|
|
||||||
func Scopes(serviceAccount string) ([]string, error) { return defaultClient.Scopes(serviceAccount) }
|
|
||||||
|
|
||||||
func strsContains(ss []string, s string) bool {
|
|
||||||
for _, v := range ss {
|
|
||||||
if v == s {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Client provides metadata.
|
|
||||||
type Client struct {
|
|
||||||
hc *http.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClient returns a Client that can be used to fetch metadata.
|
|
||||||
// Returns the client that uses the specified http.Client for HTTP requests.
|
|
||||||
// If nil is specified, returns the default client.
|
|
||||||
func NewClient(c *http.Client) *Client {
|
|
||||||
if c == nil {
|
|
||||||
return defaultClient
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Client{hc: c}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getETag returns a value from the metadata service as well as the associated ETag.
|
|
||||||
// This func is otherwise equivalent to Get.
|
|
||||||
func (c *Client) getETag(suffix string) (value, etag string, err error) {
|
|
||||||
// Using a fixed IP makes it very difficult to spoof the metadata service in
|
|
||||||
// a container, which is an important use-case for local testing of cloud
|
|
||||||
// deployments. To enable spoofing of the metadata service, the environment
|
|
||||||
// variable GCE_METADATA_HOST is first inspected to decide where metadata
|
|
||||||
// requests shall go.
|
|
||||||
host := os.Getenv(metadataHostEnv)
|
|
||||||
if host == "" {
|
|
||||||
// Using 169.254.169.254 instead of "metadata" here because Go
|
|
||||||
// binaries built with the "netgo" tag and without cgo won't
|
|
||||||
// know the search suffix for "metadata" is
|
|
||||||
// ".google.internal", and this IP address is documented as
|
|
||||||
// being stable anyway.
|
|
||||||
host = metadataIP
|
|
||||||
}
|
|
||||||
suffix = strings.TrimLeft(suffix, "/")
|
|
||||||
u := "http://" + host + "/computeMetadata/v1/" + suffix
|
|
||||||
req, err := http.NewRequest("GET", u, nil)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
req.Header.Set("Metadata-Flavor", "Google")
|
|
||||||
req.Header.Set("User-Agent", userAgent)
|
|
||||||
res, err := c.hc.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
if res.StatusCode == http.StatusNotFound {
|
|
||||||
return "", "", NotDefinedError(suffix)
|
|
||||||
}
|
|
||||||
all, err := ioutil.ReadAll(res.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
if res.StatusCode != 200 {
|
|
||||||
return "", "", &Error{Code: res.StatusCode, Message: string(all)}
|
|
||||||
}
|
|
||||||
return string(all), res.Header.Get("Etag"), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns a value from the metadata service.
|
|
||||||
// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/".
|
|
||||||
//
|
|
||||||
// If the GCE_METADATA_HOST environment variable is not defined, a default of
|
|
||||||
// 169.254.169.254 will be used instead.
|
|
||||||
//
|
|
||||||
// If the requested metadata is not defined, the returned error will
|
|
||||||
// be of type NotDefinedError.
|
|
||||||
func (c *Client) Get(suffix string) (string, error) {
|
|
||||||
val, _, err := c.getETag(suffix)
|
|
||||||
return val, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) getTrimmed(suffix string) (s string, err error) {
|
|
||||||
s, err = c.Get(suffix)
|
|
||||||
s = strings.TrimSpace(s)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) lines(suffix string) ([]string, error) {
|
|
||||||
j, err := c.Get(suffix)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
s := strings.Split(strings.TrimSpace(j), "\n")
|
|
||||||
for i := range s {
|
|
||||||
s[i] = strings.TrimSpace(s[i])
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectID returns the current instance's project ID string.
|
|
||||||
func (c *Client) ProjectID() (string, error) { return projID.get(c) }
|
|
||||||
|
|
||||||
// NumericProjectID returns the current instance's numeric project ID.
|
|
||||||
func (c *Client) NumericProjectID() (string, error) { return projNum.get(c) }
|
|
||||||
|
|
||||||
// InstanceID returns the current VM's numeric instance ID.
|
|
||||||
func (c *Client) InstanceID() (string, error) { return instID.get(c) }
|
|
||||||
|
|
||||||
// InternalIP returns the instance's primary internal IP address.
|
|
||||||
func (c *Client) InternalIP() (string, error) {
|
|
||||||
return c.getTrimmed("instance/network-interfaces/0/ip")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Email returns the email address associated with the service account.
|
|
||||||
// The account may be empty or the string "default" to use the instance's
|
|
||||||
// main account.
|
|
||||||
func (c *Client) Email(serviceAccount string) (string, error) {
|
|
||||||
if serviceAccount == "" {
|
|
||||||
serviceAccount = "default"
|
|
||||||
}
|
|
||||||
return c.getTrimmed("instance/service-accounts/" + serviceAccount + "/email")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExternalIP returns the instance's primary external (public) IP address.
|
|
||||||
func (c *Client) ExternalIP() (string, error) {
|
|
||||||
return c.getTrimmed("instance/network-interfaces/0/access-configs/0/external-ip")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hostname returns the instance's hostname. This will be of the form
|
|
||||||
// "<instanceID>.c.<projID>.internal".
|
|
||||||
func (c *Client) Hostname() (string, error) {
|
|
||||||
return c.getTrimmed("instance/hostname")
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstanceTags returns the list of user-defined instance tags,
|
|
||||||
// assigned when initially creating a GCE instance.
|
|
||||||
func (c *Client) InstanceTags() ([]string, error) {
|
|
||||||
var s []string
|
|
||||||
j, err := c.Get("instance/tags")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := json.NewDecoder(strings.NewReader(j)).Decode(&s); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstanceName returns the current VM's instance ID string.
|
|
||||||
func (c *Client) InstanceName() (string, error) {
|
|
||||||
return c.getTrimmed("instance/name")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zone returns the current VM's zone, such as "us-central1-b".
|
|
||||||
func (c *Client) Zone() (string, error) {
|
|
||||||
zone, err := c.getTrimmed("instance/zone")
|
|
||||||
// zone is of the form "projects/<projNum>/zones/<zoneName>".
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return zone[strings.LastIndex(zone, "/")+1:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InstanceAttributes returns the list of user-defined attributes,
|
|
||||||
// assigned when initially creating a GCE VM instance. The value of an
|
|
||||||
// attribute can be obtained with InstanceAttributeValue.
|
|
||||||
func (c *Client) InstanceAttributes() ([]string, error) { return c.lines("instance/attributes/") }
|
|
||||||
|
|
||||||
// ProjectAttributes returns the list of user-defined attributes
|
|
||||||
// applying to the project as a whole, not just this VM. The value of
|
|
||||||
// an attribute can be obtained with ProjectAttributeValue.
|
|
||||||
func (c *Client) ProjectAttributes() ([]string, error) { return c.lines("project/attributes/") }
|
|
||||||
|
|
||||||
// InstanceAttributeValue returns the value of the provided VM
|
|
||||||
// instance attribute.
|
|
||||||
//
|
|
||||||
// If the requested attribute is not defined, the returned error will
|
|
||||||
// be of type NotDefinedError.
|
|
||||||
//
|
|
||||||
// InstanceAttributeValue may return ("", nil) if the attribute was
|
|
||||||
// defined to be the empty string.
|
|
||||||
func (c *Client) InstanceAttributeValue(attr string) (string, error) {
|
|
||||||
return c.Get("instance/attributes/" + attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectAttributeValue returns the value of the provided
|
|
||||||
// project attribute.
|
|
||||||
//
|
|
||||||
// If the requested attribute is not defined, the returned error will
|
|
||||||
// be of type NotDefinedError.
|
|
||||||
//
|
|
||||||
// ProjectAttributeValue may return ("", nil) if the attribute was
|
|
||||||
// defined to be the empty string.
|
|
||||||
func (c *Client) ProjectAttributeValue(attr string) (string, error) {
|
|
||||||
return c.Get("project/attributes/" + attr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scopes returns the service account scopes for the given account.
|
|
||||||
// The account may be empty or the string "default" to use the instance's
|
|
||||||
// main account.
|
|
||||||
func (c *Client) Scopes(serviceAccount string) ([]string, error) {
|
|
||||||
if serviceAccount == "" {
|
|
||||||
serviceAccount = "default"
|
|
||||||
}
|
|
||||||
return c.lines("instance/service-accounts/" + serviceAccount + "/scopes")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subscribe subscribes to a value from the metadata service.
|
|
||||||
// The suffix is appended to "http://${GCE_METADATA_HOST}/computeMetadata/v1/".
|
|
||||||
// The suffix may contain query parameters.
|
|
||||||
//
|
|
||||||
// Subscribe calls fn with the latest metadata value indicated by the provided
|
|
||||||
// suffix. If the metadata value is deleted, fn is called with the empty string
|
|
||||||
// and ok false. Subscribe blocks until fn returns a non-nil error or the value
|
|
||||||
// is deleted. Subscribe returns the error value returned from the last call to
|
|
||||||
// fn, which may be nil when ok == false.
|
|
||||||
func (c *Client) Subscribe(suffix string, fn func(v string, ok bool) error) error {
|
|
||||||
const failedSubscribeSleep = time.Second * 5
|
|
||||||
|
|
||||||
// First check to see if the metadata value exists at all.
|
|
||||||
val, lastETag, err := c.getETag(suffix)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := fn(val, true); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ok := true
|
|
||||||
if strings.ContainsRune(suffix, '?') {
|
|
||||||
suffix += "&wait_for_change=true&last_etag="
|
|
||||||
} else {
|
|
||||||
suffix += "?wait_for_change=true&last_etag="
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
val, etag, err := c.getETag(suffix + url.QueryEscape(lastETag))
|
|
||||||
if err != nil {
|
|
||||||
if _, deleted := err.(NotDefinedError); !deleted {
|
|
||||||
time.Sleep(failedSubscribeSleep)
|
|
||||||
continue // Retry on other errors.
|
|
||||||
}
|
|
||||||
ok = false
|
|
||||||
}
|
|
||||||
lastETag = etag
|
|
||||||
|
|
||||||
if err := fn(val, ok); err != nil || !ok {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error contains an error response from the server.
|
|
||||||
type Error struct {
|
|
||||||
// Code is the HTTP response status code.
|
|
||||||
Code int
|
|
||||||
// Message is the server response message.
|
|
||||||
Message string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Error) Error() string {
|
|
||||||
return fmt.Sprintf("compute: Received %d `%s`", e.Code, e.Message)
|
|
||||||
}
|
|
||||||
32
vendor/github.com/Azure/go-autorest/.gitignore
generated
vendored
32
vendor/github.com/Azure/go-autorest/.gitignore
generated
vendored
@@ -1,32 +0,0 @@
|
|||||||
# The standard Go .gitignore file follows. (Sourced from: github.com/github/gitignore/master/Go.gitignore)
|
|
||||||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
|
||||||
*.o
|
|
||||||
*.a
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Folders
|
|
||||||
_obj
|
|
||||||
_test
|
|
||||||
.DS_Store
|
|
||||||
.idea/
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
# Architecture specific extensions/prefixes
|
|
||||||
*.[568vq]
|
|
||||||
[568vq].out
|
|
||||||
|
|
||||||
*.cgo1.go
|
|
||||||
*.cgo2.c
|
|
||||||
_cgo_defun.c
|
|
||||||
_cgo_gotypes.go
|
|
||||||
_cgo_export.*
|
|
||||||
|
|
||||||
_testmain.go
|
|
||||||
|
|
||||||
*.exe
|
|
||||||
*.test
|
|
||||||
*.prof
|
|
||||||
|
|
||||||
# go-autorest specific
|
|
||||||
vendor/
|
|
||||||
autorest/azure/example/example
|
|
||||||
1004
vendor/github.com/Azure/go-autorest/CHANGELOG.md
generated
vendored
1004
vendor/github.com/Azure/go-autorest/CHANGELOG.md
generated
vendored
File diff suppressed because it is too large
Load Diff
23
vendor/github.com/Azure/go-autorest/GNUmakefile
generated
vendored
23
vendor/github.com/Azure/go-autorest/GNUmakefile
generated
vendored
@@ -1,23 +0,0 @@
|
|||||||
DIR?=./autorest/
|
|
||||||
|
|
||||||
default: build
|
|
||||||
|
|
||||||
build: fmt
|
|
||||||
go install $(DIR)
|
|
||||||
|
|
||||||
test:
|
|
||||||
go test $(DIR) || exit 1
|
|
||||||
|
|
||||||
vet:
|
|
||||||
@echo "go vet ."
|
|
||||||
@go vet $(DIR)... ; if [ $$? -eq 1 ]; then \
|
|
||||||
echo ""; \
|
|
||||||
echo "Vet found suspicious constructs. Please check the reported constructs"; \
|
|
||||||
echo "and fix them if necessary before submitting the code for review."; \
|
|
||||||
exit 1; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
fmt:
|
|
||||||
gofmt -w $(DIR)
|
|
||||||
|
|
||||||
.PHONY: build test vet fmt
|
|
||||||
324
vendor/github.com/Azure/go-autorest/Gopkg.lock
generated
vendored
324
vendor/github.com/Azure/go-autorest/Gopkg.lock
generated
vendored
@@ -1,324 +0,0 @@
|
|||||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
|
||||||
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:892e39e5c083d0943f1e80ab8351690f183c6a5ab24e1d280adcad424c26255e"
|
|
||||||
name = "contrib.go.opencensus.io/exporter/ocagent"
|
|
||||||
packages = ["."]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "a8a6f458bbc1d5042322ad1f9b65eeb0b69be9ea"
|
|
||||||
version = "v0.6.0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:8f5acd4d4462b5136af644d25101f0968a7a94ee90fcb2059cec5b7cc42e0b20"
|
|
||||||
name = "github.com/census-instrumentation/opencensus-proto"
|
|
||||||
packages = [
|
|
||||||
"gen-go/agent/common/v1",
|
|
||||||
"gen-go/agent/metrics/v1",
|
|
||||||
"gen-go/agent/trace/v1",
|
|
||||||
"gen-go/metrics/v1",
|
|
||||||
"gen-go/resource/v1",
|
|
||||||
"gen-go/trace/v1",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "d89fa54de508111353cb0b06403c00569be780d8"
|
|
||||||
version = "v0.2.1"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec"
|
|
||||||
name = "github.com/davecgh/go-spew"
|
|
||||||
packages = ["spew"]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
|
|
||||||
version = "v1.1.1"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:76dc72490af7174349349838f2fe118996381b31ea83243812a97e5a0fd5ed55"
|
|
||||||
name = "github.com/dgrijalva/jwt-go"
|
|
||||||
packages = ["."]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e"
|
|
||||||
version = "v3.2.0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:cf0d2e435fd4ce45b789e93ef24b5f08e86be0e9807a16beb3694e2d8c9af965"
|
|
||||||
name = "github.com/dimchansky/utfbom"
|
|
||||||
packages = ["."]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "d2133a1ce379ef6fa992b0514a77146c60db9d1c"
|
|
||||||
version = "v1.1.0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
digest = "1:b7cb6054d3dff43b38ad2e92492f220f57ae6087ee797dca298139776749ace8"
|
|
||||||
name = "github.com/golang/groupcache"
|
|
||||||
packages = ["lru"]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "611e8accdfc92c4187d399e95ce826046d4c8d73"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:e3839df32927e8d3403cd5aa7253d966e8ff80fc8f10e2e35d146461cd83fcfa"
|
|
||||||
name = "github.com/golang/protobuf"
|
|
||||||
packages = [
|
|
||||||
"descriptor",
|
|
||||||
"jsonpb",
|
|
||||||
"proto",
|
|
||||||
"protoc-gen-go/descriptor",
|
|
||||||
"ptypes",
|
|
||||||
"ptypes/any",
|
|
||||||
"ptypes/duration",
|
|
||||||
"ptypes/struct",
|
|
||||||
"ptypes/timestamp",
|
|
||||||
"ptypes/wrappers",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "6c65a5562fc06764971b7c5d05c76c75e84bdbf7"
|
|
||||||
version = "v1.3.2"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:c560cd79300fac84f124b96225181a637a70b60155919a3c36db50b7cca6b806"
|
|
||||||
name = "github.com/grpc-ecosystem/grpc-gateway"
|
|
||||||
packages = [
|
|
||||||
"internal",
|
|
||||||
"runtime",
|
|
||||||
"utilities",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "f7120437bb4f6c71f7f5076ad65a45310de2c009"
|
|
||||||
version = "v1.12.1"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:5d231480e1c64a726869bc4142d270184c419749d34f167646baa21008eb0a79"
|
|
||||||
name = "github.com/mitchellh/go-homedir"
|
|
||||||
packages = ["."]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "af06845cf3004701891bf4fdb884bfe4920b3727"
|
|
||||||
version = "v1.1.0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe"
|
|
||||||
name = "github.com/pmezard/go-difflib"
|
|
||||||
packages = ["difflib"]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
|
|
||||||
version = "v1.0.0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:99d32780e5238c2621fff621123997c3e3cca96db8be13179013aea77dfab551"
|
|
||||||
name = "github.com/stretchr/testify"
|
|
||||||
packages = [
|
|
||||||
"assert",
|
|
||||||
"require",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "221dbe5ed46703ee255b1da0dec05086f5035f62"
|
|
||||||
version = "v1.4.0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:7c5e00383399fe13de0b4b65c9fdde16275407ce8ac02d867eafeaa916edcc71"
|
|
||||||
name = "go.opencensus.io"
|
|
||||||
packages = [
|
|
||||||
".",
|
|
||||||
"internal",
|
|
||||||
"internal/tagencoding",
|
|
||||||
"metric/metricdata",
|
|
||||||
"metric/metricproducer",
|
|
||||||
"plugin/ocgrpc",
|
|
||||||
"plugin/ochttp",
|
|
||||||
"plugin/ochttp/propagation/b3",
|
|
||||||
"plugin/ochttp/propagation/tracecontext",
|
|
||||||
"resource",
|
|
||||||
"stats",
|
|
||||||
"stats/internal",
|
|
||||||
"stats/view",
|
|
||||||
"tag",
|
|
||||||
"trace",
|
|
||||||
"trace/internal",
|
|
||||||
"trace/propagation",
|
|
||||||
"trace/tracestate",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "aad2c527c5defcf89b5afab7f37274304195a6b2"
|
|
||||||
version = "v0.22.2"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
digest = "1:f604f5e2ee721b6757d962dfe7bab4f28aae50c456e39cfb2f3819762a44a6ae"
|
|
||||||
name = "golang.org/x/crypto"
|
|
||||||
packages = [
|
|
||||||
"pkcs12",
|
|
||||||
"pkcs12/internal/rc2",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "e9b2fee46413994441b28dfca259d911d963dfed"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
digest = "1:334b27eac455cb6567ea28cd424230b07b1a64334a2f861a8075ac26ce10af43"
|
|
||||||
name = "golang.org/x/lint"
|
|
||||||
packages = [
|
|
||||||
".",
|
|
||||||
"golint",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "fdd1cda4f05fd1fd86124f0ef9ce31a0b72c8448"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
digest = "1:257a75d024975428ab9192bfc334c3490882f8cb21322ea5784ca8eca000a910"
|
|
||||||
name = "golang.org/x/net"
|
|
||||||
packages = [
|
|
||||||
"http/httpguts",
|
|
||||||
"http2",
|
|
||||||
"http2/hpack",
|
|
||||||
"idna",
|
|
||||||
"internal/timeseries",
|
|
||||||
"trace",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "1ddd1de85cb0337b623b740a609d35817d516a8d"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
digest = "1:382bb5a7fb4034db3b6a2d19e5a4a6bcf52f4750530603c01ca18a172fa3089b"
|
|
||||||
name = "golang.org/x/sync"
|
|
||||||
packages = ["semaphore"]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "cd5d95a43a6e21273425c7ae415d3df9ea832eeb"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
digest = "1:4da420ceda5f68e8d748aa2169d0ed44ffadb1bbd6537cf778a49563104189b8"
|
|
||||||
name = "golang.org/x/sys"
|
|
||||||
packages = ["unix"]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "ce4227a45e2eb77e5c847278dcc6a626742e2945"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:8d8faad6b12a3a4c819a3f9618cb6ee1fa1cfc33253abeeea8b55336721e3405"
|
|
||||||
name = "golang.org/x/text"
|
|
||||||
packages = [
|
|
||||||
"collate",
|
|
||||||
"collate/build",
|
|
||||||
"internal/colltab",
|
|
||||||
"internal/gen",
|
|
||||||
"internal/language",
|
|
||||||
"internal/language/compact",
|
|
||||||
"internal/tag",
|
|
||||||
"internal/triegen",
|
|
||||||
"internal/ucd",
|
|
||||||
"language",
|
|
||||||
"secure/bidirule",
|
|
||||||
"transform",
|
|
||||||
"unicode/bidi",
|
|
||||||
"unicode/cldr",
|
|
||||||
"unicode/norm",
|
|
||||||
"unicode/rangetable",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475"
|
|
||||||
version = "v0.3.2"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
digest = "1:4eb5ea8395fb60212dd58b92c9db80bab59d5e99c7435f9a6a0a528c373b60e7"
|
|
||||||
name = "golang.org/x/tools"
|
|
||||||
packages = [
|
|
||||||
"go/ast/astutil",
|
|
||||||
"go/gcexportdata",
|
|
||||||
"go/internal/gcimporter",
|
|
||||||
"go/types/typeutil",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "259af5ff87bdcd4abf2ecda8edc3f13f04f26a42"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:964bb30febc27fabfbec4759fa530c6ec35e77a7c85fed90b9317ea39a054877"
|
|
||||||
name = "google.golang.org/api"
|
|
||||||
packages = ["support/bundler"]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "8a410c21381766a810817fd6200fce8838ecb277"
|
|
||||||
version = "v0.14.0"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
branch = "master"
|
|
||||||
digest = "1:a8d5c2c6e746b3485e36908ab2a9e3d77b86b81f8156d88403c7d2b462431dfd"
|
|
||||||
name = "google.golang.org/genproto"
|
|
||||||
packages = [
|
|
||||||
"googleapis/api/httpbody",
|
|
||||||
"googleapis/rpc/status",
|
|
||||||
"protobuf/field_mask",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "51378566eb590fa106d1025ea12835a4416dda84"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:b59ce3ddb11daeeccccc9cb3183b58ebf8e9a779f1c853308cd91612e817a301"
|
|
||||||
name = "google.golang.org/grpc"
|
|
||||||
packages = [
|
|
||||||
".",
|
|
||||||
"backoff",
|
|
||||||
"balancer",
|
|
||||||
"balancer/base",
|
|
||||||
"balancer/roundrobin",
|
|
||||||
"binarylog/grpc_binarylog_v1",
|
|
||||||
"codes",
|
|
||||||
"connectivity",
|
|
||||||
"credentials",
|
|
||||||
"credentials/internal",
|
|
||||||
"encoding",
|
|
||||||
"encoding/proto",
|
|
||||||
"grpclog",
|
|
||||||
"internal",
|
|
||||||
"internal/backoff",
|
|
||||||
"internal/balancerload",
|
|
||||||
"internal/binarylog",
|
|
||||||
"internal/buffer",
|
|
||||||
"internal/channelz",
|
|
||||||
"internal/envconfig",
|
|
||||||
"internal/grpcrand",
|
|
||||||
"internal/grpcsync",
|
|
||||||
"internal/resolver/dns",
|
|
||||||
"internal/resolver/passthrough",
|
|
||||||
"internal/syscall",
|
|
||||||
"internal/transport",
|
|
||||||
"keepalive",
|
|
||||||
"metadata",
|
|
||||||
"naming",
|
|
||||||
"peer",
|
|
||||||
"resolver",
|
|
||||||
"serviceconfig",
|
|
||||||
"stats",
|
|
||||||
"status",
|
|
||||||
"tap",
|
|
||||||
]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "1a3960e4bd028ac0cec0a2afd27d7d8e67c11514"
|
|
||||||
version = "v1.25.1"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
digest = "1:b75b3deb2bce8bc079e16bb2aecfe01eb80098f5650f9e93e5643ca8b7b73737"
|
|
||||||
name = "gopkg.in/yaml.v2"
|
|
||||||
packages = ["."]
|
|
||||||
pruneopts = "UT"
|
|
||||||
revision = "1f64d6156d11335c3f22d9330b0ad14fc1e789ce"
|
|
||||||
version = "v2.2.7"
|
|
||||||
|
|
||||||
[solve-meta]
|
|
||||||
analyzer-name = "dep"
|
|
||||||
analyzer-version = 1
|
|
||||||
input-imports = [
|
|
||||||
"contrib.go.opencensus.io/exporter/ocagent",
|
|
||||||
"github.com/dgrijalva/jwt-go",
|
|
||||||
"github.com/dimchansky/utfbom",
|
|
||||||
"github.com/mitchellh/go-homedir",
|
|
||||||
"github.com/stretchr/testify/require",
|
|
||||||
"go.opencensus.io/plugin/ochttp",
|
|
||||||
"go.opencensus.io/plugin/ochttp/propagation/tracecontext",
|
|
||||||
"go.opencensus.io/stats/view",
|
|
||||||
"go.opencensus.io/trace",
|
|
||||||
"golang.org/x/crypto/pkcs12",
|
|
||||||
"golang.org/x/lint/golint",
|
|
||||||
]
|
|
||||||
solver-name = "gps-cdcl"
|
|
||||||
solver-version = 1
|
|
||||||
59
vendor/github.com/Azure/go-autorest/Gopkg.toml
generated
vendored
59
vendor/github.com/Azure/go-autorest/Gopkg.toml
generated
vendored
@@ -1,59 +0,0 @@
|
|||||||
# Gopkg.toml example
|
|
||||||
#
|
|
||||||
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
|
|
||||||
# for detailed Gopkg.toml documentation.
|
|
||||||
#
|
|
||||||
# required = ["github.com/user/thing/cmd/thing"]
|
|
||||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
|
||||||
#
|
|
||||||
# [[constraint]]
|
|
||||||
# name = "github.com/user/project"
|
|
||||||
# version = "1.0.0"
|
|
||||||
#
|
|
||||||
# [[constraint]]
|
|
||||||
# name = "github.com/user/project2"
|
|
||||||
# branch = "dev"
|
|
||||||
# source = "github.com/myfork/project2"
|
|
||||||
#
|
|
||||||
# [[override]]
|
|
||||||
# name = "github.com/x/y"
|
|
||||||
# version = "2.4.0"
|
|
||||||
#
|
|
||||||
# [prune]
|
|
||||||
# non-go = false
|
|
||||||
# go-tests = true
|
|
||||||
# unused-packages = true
|
|
||||||
|
|
||||||
required = ["golang.org/x/lint/golint"]
|
|
||||||
|
|
||||||
[prune]
|
|
||||||
go-tests = true
|
|
||||||
unused-packages = true
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "contrib.go.opencensus.io/exporter/ocagent"
|
|
||||||
version = "0.6.0"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "github.com/dgrijalva/jwt-go"
|
|
||||||
version = "3.2.0"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "github.com/dimchansky/utfbom"
|
|
||||||
version = "1.1.0"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "github.com/mitchellh/go-homedir"
|
|
||||||
version = "1.1.0"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "github.com/stretchr/testify"
|
|
||||||
version = "1.3.0"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
name = "go.opencensus.io"
|
|
||||||
version = "0.22.0"
|
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
branch = "master"
|
|
||||||
name = "golang.org/x/crypto"
|
|
||||||
191
vendor/github.com/Azure/go-autorest/LICENSE
generated
vendored
191
vendor/github.com/Azure/go-autorest/LICENSE
generated
vendored
@@ -1,191 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
Copyright 2015 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.
|
|
||||||
165
vendor/github.com/Azure/go-autorest/README.md
generated
vendored
165
vendor/github.com/Azure/go-autorest/README.md
generated
vendored
@@ -1,165 +0,0 @@
|
|||||||
# go-autorest
|
|
||||||
|
|
||||||
[](https://godoc.org/github.com/Azure/go-autorest/autorest)
|
|
||||||
[](https://dev.azure.com/azure-sdk/public/_build/latest?definitionId=625&branchName=master)
|
|
||||||
[](https://goreportcard.com/report/Azure/go-autorest)
|
|
||||||
|
|
||||||
Package go-autorest provides an HTTP request client for use with [Autorest](https://github.com/Azure/autorest.go)-generated API client packages.
|
|
||||||
|
|
||||||
An authentication client tested with Azure Active Directory (AAD) is also
|
|
||||||
provided in this repo in the package
|
|
||||||
`github.com/Azure/go-autorest/autorest/adal`. Despite its name, this package
|
|
||||||
is maintained only as part of the Azure Go SDK and is not related to other
|
|
||||||
"ADAL" libraries in [github.com/AzureAD](https://github.com/AzureAD).
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
Package go-autorest implements an HTTP request pipeline suitable for use across
|
|
||||||
multiple goroutines and provides the shared routines used by packages generated
|
|
||||||
by [Autorest](https://github.com/Azure/autorest.go).
|
|
||||||
|
|
||||||
The package breaks sending and responding to HTTP requests into three phases: Preparing, Sending,
|
|
||||||
and Responding. A typical pattern is:
|
|
||||||
|
|
||||||
```go
|
|
||||||
req, err := Prepare(&http.Request{},
|
|
||||||
token.WithAuthorization())
|
|
||||||
|
|
||||||
resp, err := Send(req,
|
|
||||||
WithLogging(logger),
|
|
||||||
DoErrorIfStatusCode(http.StatusInternalServerError),
|
|
||||||
DoCloseIfError(),
|
|
||||||
DoRetryForAttempts(5, time.Second))
|
|
||||||
|
|
||||||
err = Respond(resp,
|
|
||||||
ByDiscardingBody(),
|
|
||||||
ByClosing())
|
|
||||||
```
|
|
||||||
|
|
||||||
Each phase relies on decorators to modify and / or manage processing. Decorators may first modify
|
|
||||||
and then pass the data along, pass the data first and then modify the result, or wrap themselves
|
|
||||||
around passing the data (such as a logger might do). Decorators run in the order provided. For
|
|
||||||
example, the following:
|
|
||||||
|
|
||||||
```go
|
|
||||||
req, err := Prepare(&http.Request{},
|
|
||||||
WithBaseURL("https://microsoft.com/"),
|
|
||||||
WithPath("a"),
|
|
||||||
WithPath("b"),
|
|
||||||
WithPath("c"))
|
|
||||||
```
|
|
||||||
|
|
||||||
will set the URL to:
|
|
||||||
|
|
||||||
```
|
|
||||||
https://microsoft.com/a/b/c
|
|
||||||
```
|
|
||||||
|
|
||||||
Preparers and Responders may be shared and re-used (assuming the underlying decorators support
|
|
||||||
sharing and re-use). Performant use is obtained by creating one or more Preparers and Responders
|
|
||||||
shared among multiple go-routines, and a single Sender shared among multiple sending go-routines,
|
|
||||||
all bound together by means of input / output channels.
|
|
||||||
|
|
||||||
Decorators hold their passed state within a closure (such as the path components in the example
|
|
||||||
above). Be careful to share Preparers and Responders only in a context where such held state
|
|
||||||
applies. For example, it may not make sense to share a Preparer that applies a query string from a
|
|
||||||
fixed set of values. Similarly, sharing a Responder that reads the response body into a passed
|
|
||||||
struct (e.g., `ByUnmarshallingJson`) is likely incorrect.
|
|
||||||
|
|
||||||
Errors raised by autorest objects and methods will conform to the `autorest.Error` interface.
|
|
||||||
|
|
||||||
See the included examples for more detail. For details on the suggested use of this package by
|
|
||||||
generated clients, see the Client described below.
|
|
||||||
|
|
||||||
## Helpers
|
|
||||||
|
|
||||||
### Handling Swagger Dates
|
|
||||||
|
|
||||||
The Swagger specification (https://swagger.io) that drives AutoRest
|
|
||||||
(https://github.com/Azure/autorest/) precisely defines two date forms: date and date-time. The
|
|
||||||
github.com/Azure/go-autorest/autorest/date package provides time.Time derivations to ensure correct
|
|
||||||
parsing and formatting.
|
|
||||||
|
|
||||||
### Handling Empty Values
|
|
||||||
|
|
||||||
In JSON, missing values have different semantics than empty values. This is especially true for
|
|
||||||
services using the HTTP PATCH verb. The JSON submitted with a PATCH request generally contains
|
|
||||||
only those values to modify. Missing values are to be left unchanged. Developers, then, require a
|
|
||||||
means to both specify an empty value and to leave the value out of the submitted JSON.
|
|
||||||
|
|
||||||
The Go JSON package (`encoding/json`) supports the `omitempty` tag. When specified, it omits
|
|
||||||
empty values from the rendered JSON. Since Go defines default values for all base types (such as ""
|
|
||||||
for string and 0 for int) and provides no means to mark a value as actually empty, the JSON package
|
|
||||||
treats default values as meaning empty, omitting them from the rendered JSON. This means that, using
|
|
||||||
the Go base types encoded through the default JSON package, it is not possible to create JSON to
|
|
||||||
clear a value at the server.
|
|
||||||
|
|
||||||
The workaround within the Go community is to use pointers to base types in lieu of base types within
|
|
||||||
structures that map to JSON. For example, instead of a value of type `string`, the workaround uses
|
|
||||||
`*string`. While this enables distinguishing empty values from those to be unchanged, creating
|
|
||||||
pointers to a base type (notably constant, in-line values) requires additional variables. This, for
|
|
||||||
example,
|
|
||||||
|
|
||||||
```go
|
|
||||||
s := struct {
|
|
||||||
S *string
|
|
||||||
}{ S: &"foo" }
|
|
||||||
```
|
|
||||||
fails, while, this
|
|
||||||
|
|
||||||
```go
|
|
||||||
v := "foo"
|
|
||||||
s := struct {
|
|
||||||
S *string
|
|
||||||
}{ S: &v }
|
|
||||||
```
|
|
||||||
succeeds.
|
|
||||||
|
|
||||||
To ease using pointers, the subpackage `to` contains helpers that convert to and from pointers for
|
|
||||||
Go base types which have Swagger analogs. It also provides a helper that converts between
|
|
||||||
`map[string]string` and `map[string]*string`, enabling the JSON to specify that the value
|
|
||||||
associated with a key should be cleared. With the helpers, the previous example becomes
|
|
||||||
|
|
||||||
```go
|
|
||||||
s := struct {
|
|
||||||
S *string
|
|
||||||
}{ S: to.StringPtr("foo") }
|
|
||||||
```
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go get github.com/Azure/go-autorest/autorest
|
|
||||||
go get github.com/Azure/go-autorest/autorest/azure
|
|
||||||
go get github.com/Azure/go-autorest/autorest/date
|
|
||||||
go get github.com/Azure/go-autorest/autorest/to
|
|
||||||
```
|
|
||||||
|
|
||||||
### Using with Go Modules
|
|
||||||
In [v12.0.1](https://github.com/Azure/go-autorest/pull/386), this repository introduced the following modules.
|
|
||||||
|
|
||||||
- autorest/adal
|
|
||||||
- autorest/azure/auth
|
|
||||||
- autorest/azure/cli
|
|
||||||
- autorest/date
|
|
||||||
- autorest/mocks
|
|
||||||
- autorest/to
|
|
||||||
- autorest/validation
|
|
||||||
- autorest
|
|
||||||
- logger
|
|
||||||
- tracing
|
|
||||||
|
|
||||||
Tagging cumulative SDK releases as a whole (e.g. `v12.3.0`) is still enabled to support consumers of this repo that have not yet migrated to modules.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
See LICENSE file.
|
|
||||||
|
|
||||||
-----
|
|
||||||
|
|
||||||
This project has adopted the [Microsoft Open Source Code of
|
|
||||||
Conduct](https://opensource.microsoft.com/codeofconduct/). For more information
|
|
||||||
see the [Code of Conduct
|
|
||||||
FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact
|
|
||||||
[opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional
|
|
||||||
questions or comments.
|
|
||||||
191
vendor/github.com/Azure/go-autorest/autorest/LICENSE
generated
vendored
191
vendor/github.com/Azure/go-autorest/autorest/LICENSE
generated
vendored
@@ -1,191 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
Copyright 2015 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.
|
|
||||||
191
vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE
generated
vendored
191
vendor/github.com/Azure/go-autorest/autorest/adal/LICENSE
generated
vendored
@@ -1,191 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
Copyright 2015 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.
|
|
||||||
292
vendor/github.com/Azure/go-autorest/autorest/adal/README.md
generated
vendored
292
vendor/github.com/Azure/go-autorest/autorest/adal/README.md
generated
vendored
@@ -1,292 +0,0 @@
|
|||||||
# Azure Active Directory authentication for Go
|
|
||||||
|
|
||||||
This is a standalone package for authenticating with Azure Active
|
|
||||||
Directory from other Go libraries and applications, in particular the [Azure SDK
|
|
||||||
for Go](https://github.com/Azure/azure-sdk-for-go).
|
|
||||||
|
|
||||||
Note: Despite the package's name it is not related to other "ADAL" libraries
|
|
||||||
maintained in the [github.com/AzureAD](https://github.com/AzureAD) org. Issues
|
|
||||||
should be opened in [this repo's](https://github.com/Azure/go-autorest/issues)
|
|
||||||
or [the SDK's](https://github.com/Azure/azure-sdk-for-go/issues) issue
|
|
||||||
trackers.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```bash
|
|
||||||
go get -u github.com/Azure/go-autorest/autorest/adal
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
An Active Directory application is required in order to use this library. An application can be registered in the [Azure Portal](https://portal.azure.com/) by following these [guidelines](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications) or using the [Azure CLI](https://github.com/Azure/azure-cli).
|
|
||||||
|
|
||||||
### Register an Azure AD Application with secret
|
|
||||||
|
|
||||||
|
|
||||||
1. Register a new application with a `secret` credential
|
|
||||||
|
|
||||||
```
|
|
||||||
az ad app create \
|
|
||||||
--display-name example-app \
|
|
||||||
--homepage https://example-app/home \
|
|
||||||
--identifier-uris https://example-app/app \
|
|
||||||
--password secret
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Create a service principal using the `Application ID` from previous step
|
|
||||||
|
|
||||||
```
|
|
||||||
az ad sp create --id "Application ID"
|
|
||||||
```
|
|
||||||
|
|
||||||
* Replace `Application ID` with `appId` from step 1.
|
|
||||||
|
|
||||||
### Register an Azure AD Application with certificate
|
|
||||||
|
|
||||||
1. Create a private key
|
|
||||||
|
|
||||||
```
|
|
||||||
openssl genrsa -out "example-app.key" 2048
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Create the certificate
|
|
||||||
|
|
||||||
```
|
|
||||||
openssl req -new -key "example-app.key" -subj "/CN=example-app" -out "example-app.csr"
|
|
||||||
openssl x509 -req -in "example-app.csr" -signkey "example-app.key" -out "example-app.crt" -days 10000
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Create the PKCS12 version of the certificate containing also the private key
|
|
||||||
|
|
||||||
```
|
|
||||||
openssl pkcs12 -export -out "example-app.pfx" -inkey "example-app.key" -in "example-app.crt" -passout pass:
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
4. Register a new application with the certificate content form `example-app.crt`
|
|
||||||
|
|
||||||
```
|
|
||||||
certificateContents="$(tail -n+2 "example-app.crt" | head -n-1)"
|
|
||||||
|
|
||||||
az ad app create \
|
|
||||||
--display-name example-app \
|
|
||||||
--homepage https://example-app/home \
|
|
||||||
--identifier-uris https://example-app/app \
|
|
||||||
--key-usage Verify --end-date 2018-01-01 \
|
|
||||||
--key-value "${certificateContents}"
|
|
||||||
```
|
|
||||||
|
|
||||||
5. Create a service principal using the `Application ID` from previous step
|
|
||||||
|
|
||||||
```
|
|
||||||
az ad sp create --id "APPLICATION_ID"
|
|
||||||
```
|
|
||||||
|
|
||||||
* Replace `APPLICATION_ID` with `appId` from step 4.
|
|
||||||
|
|
||||||
|
|
||||||
### Grant the necessary permissions
|
|
||||||
|
|
||||||
Azure relies on a Role-Based Access Control (RBAC) model to manage the access to resources at a fine-grained
|
|
||||||
level. There is a set of [pre-defined roles](https://docs.microsoft.com/en-us/azure/active-directory/role-based-access-built-in-roles)
|
|
||||||
which can be assigned to a service principal of an Azure AD application depending of your needs.
|
|
||||||
|
|
||||||
```
|
|
||||||
az role assignment create --assigner "SERVICE_PRINCIPAL_ID" --role "ROLE_NAME"
|
|
||||||
```
|
|
||||||
|
|
||||||
* Replace the `SERVICE_PRINCIPAL_ID` with the `appId` from previous step.
|
|
||||||
* Replace the `ROLE_NAME` with a role name of your choice.
|
|
||||||
|
|
||||||
It is also possible to define custom role definitions.
|
|
||||||
|
|
||||||
```
|
|
||||||
az role definition create --role-definition role-definition.json
|
|
||||||
```
|
|
||||||
|
|
||||||
* Check [custom roles](https://docs.microsoft.com/en-us/azure/active-directory/role-based-access-control-custom-roles) for more details regarding the content of `role-definition.json` file.
|
|
||||||
|
|
||||||
|
|
||||||
### Acquire Access Token
|
|
||||||
|
|
||||||
The common configuration used by all flows:
|
|
||||||
|
|
||||||
```Go
|
|
||||||
const activeDirectoryEndpoint = "https://login.microsoftonline.com/"
|
|
||||||
tenantID := "TENANT_ID"
|
|
||||||
oauthConfig, err := adal.NewOAuthConfig(activeDirectoryEndpoint, tenantID)
|
|
||||||
|
|
||||||
applicationID := "APPLICATION_ID"
|
|
||||||
|
|
||||||
callback := func(token adal.Token) error {
|
|
||||||
// This is called after the token is acquired
|
|
||||||
}
|
|
||||||
|
|
||||||
// The resource for which the token is acquired
|
|
||||||
resource := "https://management.core.windows.net/"
|
|
||||||
```
|
|
||||||
|
|
||||||
* Replace the `TENANT_ID` with your tenant ID.
|
|
||||||
* Replace the `APPLICATION_ID` with the value from previous section.
|
|
||||||
|
|
||||||
#### Client Credentials
|
|
||||||
|
|
||||||
```Go
|
|
||||||
applicationSecret := "APPLICATION_SECRET"
|
|
||||||
|
|
||||||
spt, err := adal.NewServicePrincipalToken(
|
|
||||||
*oauthConfig,
|
|
||||||
appliationID,
|
|
||||||
applicationSecret,
|
|
||||||
resource,
|
|
||||||
callbacks...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Acquire a new access token
|
|
||||||
err = spt.Refresh()
|
|
||||||
if (err == nil) {
|
|
||||||
token := spt.Token
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
* Replace the `APPLICATION_SECRET` with the `password` value from previous section.
|
|
||||||
|
|
||||||
#### Client Certificate
|
|
||||||
|
|
||||||
```Go
|
|
||||||
certificatePath := "./example-app.pfx"
|
|
||||||
|
|
||||||
certData, err := ioutil.ReadFile(certificatePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to read the certificate file (%s): %v", certificatePath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the certificate and private key from pfx file
|
|
||||||
certificate, rsaPrivateKey, err := decodePkcs12(certData, "")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to decode pkcs12 certificate while creating spt: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
spt, err := adal.NewServicePrincipalTokenFromCertificate(
|
|
||||||
*oauthConfig,
|
|
||||||
applicationID,
|
|
||||||
certificate,
|
|
||||||
rsaPrivateKey,
|
|
||||||
resource,
|
|
||||||
callbacks...)
|
|
||||||
|
|
||||||
// Acquire a new access token
|
|
||||||
err = spt.Refresh()
|
|
||||||
if (err == nil) {
|
|
||||||
token := spt.Token
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
* Update the certificate path to point to the example-app.pfx file which was created in previous section.
|
|
||||||
|
|
||||||
|
|
||||||
#### Device Code
|
|
||||||
|
|
||||||
```Go
|
|
||||||
oauthClient := &http.Client{}
|
|
||||||
|
|
||||||
// Acquire the device code
|
|
||||||
deviceCode, err := adal.InitiateDeviceAuth(
|
|
||||||
oauthClient,
|
|
||||||
*oauthConfig,
|
|
||||||
applicationID,
|
|
||||||
resource)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Failed to start device auth flow: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the authentication message
|
|
||||||
fmt.Println(*deviceCode.Message)
|
|
||||||
|
|
||||||
// Wait here until the user is authenticated
|
|
||||||
token, err := adal.WaitForUserCompletion(oauthClient, deviceCode)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Failed to finish device auth flow: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
spt, err := adal.NewServicePrincipalTokenFromManualToken(
|
|
||||||
*oauthConfig,
|
|
||||||
applicationID,
|
|
||||||
resource,
|
|
||||||
*token,
|
|
||||||
callbacks...)
|
|
||||||
|
|
||||||
if (err == nil) {
|
|
||||||
token := spt.Token
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Username password authenticate
|
|
||||||
|
|
||||||
```Go
|
|
||||||
spt, err := adal.NewServicePrincipalTokenFromUsernamePassword(
|
|
||||||
*oauthConfig,
|
|
||||||
applicationID,
|
|
||||||
username,
|
|
||||||
password,
|
|
||||||
resource,
|
|
||||||
callbacks...)
|
|
||||||
|
|
||||||
if (err == nil) {
|
|
||||||
token := spt.Token
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Authorization code authenticate
|
|
||||||
|
|
||||||
``` Go
|
|
||||||
spt, err := adal.NewServicePrincipalTokenFromAuthorizationCode(
|
|
||||||
*oauthConfig,
|
|
||||||
applicationID,
|
|
||||||
clientSecret,
|
|
||||||
authorizationCode,
|
|
||||||
redirectURI,
|
|
||||||
resource,
|
|
||||||
callbacks...)
|
|
||||||
|
|
||||||
err = spt.Refresh()
|
|
||||||
if (err == nil) {
|
|
||||||
token := spt.Token
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Command Line Tool
|
|
||||||
|
|
||||||
A command line tool is available in `cmd/adal.go` that can acquire a token for a given resource. It supports all flows mentioned above.
|
|
||||||
|
|
||||||
```
|
|
||||||
adal -h
|
|
||||||
|
|
||||||
Usage of ./adal:
|
|
||||||
-applicationId string
|
|
||||||
application id
|
|
||||||
-certificatePath string
|
|
||||||
path to pk12/PFC application certificate
|
|
||||||
-mode string
|
|
||||||
authentication mode (device, secret, cert, refresh) (default "device")
|
|
||||||
-resource string
|
|
||||||
resource for which the token is requested
|
|
||||||
-secret string
|
|
||||||
application secret
|
|
||||||
-tenantId string
|
|
||||||
tenant id
|
|
||||||
-tokenCachePath string
|
|
||||||
location of oath token cache (default "/home/cgc/.adal/accessToken.json")
|
|
||||||
```
|
|
||||||
|
|
||||||
Example acquire a token for `https://management.core.windows.net/` using device code flow:
|
|
||||||
|
|
||||||
```
|
|
||||||
adal -mode device \
|
|
||||||
-applicationId "APPLICATION_ID" \
|
|
||||||
-tenantId "TENANT_ID" \
|
|
||||||
-resource https://management.core.windows.net/
|
|
||||||
|
|
||||||
```
|
|
||||||
151
vendor/github.com/Azure/go-autorest/autorest/adal/config.go
generated
vendored
151
vendor/github.com/Azure/go-autorest/autorest/adal/config.go
generated
vendored
@@ -1,151 +0,0 @@
|
|||||||
package adal
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
activeDirectoryEndpointTemplate = "%s/oauth2/%s%s"
|
|
||||||
)
|
|
||||||
|
|
||||||
// OAuthConfig represents the endpoints needed
|
|
||||||
// in OAuth operations
|
|
||||||
type OAuthConfig struct {
|
|
||||||
AuthorityEndpoint url.URL `json:"authorityEndpoint"`
|
|
||||||
AuthorizeEndpoint url.URL `json:"authorizeEndpoint"`
|
|
||||||
TokenEndpoint url.URL `json:"tokenEndpoint"`
|
|
||||||
DeviceCodeEndpoint url.URL `json:"deviceCodeEndpoint"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsZero returns true if the OAuthConfig object is zero-initialized.
|
|
||||||
func (oac OAuthConfig) IsZero() bool {
|
|
||||||
return oac == OAuthConfig{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateStringParam(param, name string) error {
|
|
||||||
if len(param) == 0 {
|
|
||||||
return fmt.Errorf("parameter '" + name + "' cannot be empty")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewOAuthConfig returns an OAuthConfig with tenant specific urls
|
|
||||||
func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) {
|
|
||||||
apiVer := "1.0"
|
|
||||||
return NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID, &apiVer)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewOAuthConfigWithAPIVersion returns an OAuthConfig with tenant specific urls.
|
|
||||||
// If apiVersion is not nil the "api-version" query parameter will be appended to the endpoint URLs with the specified value.
|
|
||||||
func NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, tenantID string, apiVersion *string) (*OAuthConfig, error) {
|
|
||||||
if err := validateStringParam(activeDirectoryEndpoint, "activeDirectoryEndpoint"); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
api := ""
|
|
||||||
// it's legal for tenantID to be empty so don't validate it
|
|
||||||
if apiVersion != nil {
|
|
||||||
if err := validateStringParam(*apiVersion, "apiVersion"); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
api = fmt.Sprintf("?api-version=%s", *apiVersion)
|
|
||||||
}
|
|
||||||
u, err := url.Parse(activeDirectoryEndpoint)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
authorityURL, err := u.Parse(tenantID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
authorizeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "authorize", api))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
tokenURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "token", api))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
deviceCodeURL, err := u.Parse(fmt.Sprintf(activeDirectoryEndpointTemplate, tenantID, "devicecode", api))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &OAuthConfig{
|
|
||||||
AuthorityEndpoint: *authorityURL,
|
|
||||||
AuthorizeEndpoint: *authorizeURL,
|
|
||||||
TokenEndpoint: *tokenURL,
|
|
||||||
DeviceCodeEndpoint: *deviceCodeURL,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MultiTenantOAuthConfig provides endpoints for primary and aulixiary tenant IDs.
|
|
||||||
type MultiTenantOAuthConfig interface {
|
|
||||||
PrimaryTenant() *OAuthConfig
|
|
||||||
AuxiliaryTenants() []*OAuthConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
// OAuthOptions contains optional OAuthConfig creation arguments.
|
|
||||||
type OAuthOptions struct {
|
|
||||||
APIVersion string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c OAuthOptions) apiVersion() string {
|
|
||||||
if c.APIVersion != "" {
|
|
||||||
return fmt.Sprintf("?api-version=%s", c.APIVersion)
|
|
||||||
}
|
|
||||||
return "1.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMultiTenantOAuthConfig creates an object that support multitenant OAuth configuration.
|
|
||||||
// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/authenticate-multi-tenant for more information.
|
|
||||||
func NewMultiTenantOAuthConfig(activeDirectoryEndpoint, primaryTenantID string, auxiliaryTenantIDs []string, options OAuthOptions) (MultiTenantOAuthConfig, error) {
|
|
||||||
if len(auxiliaryTenantIDs) == 0 || len(auxiliaryTenantIDs) > 3 {
|
|
||||||
return nil, errors.New("must specify one to three auxiliary tenants")
|
|
||||||
}
|
|
||||||
mtCfg := multiTenantOAuthConfig{
|
|
||||||
cfgs: make([]*OAuthConfig, len(auxiliaryTenantIDs)+1),
|
|
||||||
}
|
|
||||||
apiVer := options.apiVersion()
|
|
||||||
pri, err := NewOAuthConfigWithAPIVersion(activeDirectoryEndpoint, primaryTenantID, &apiVer)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to create OAuthConfig for primary tenant: %v", err)
|
|
||||||
}
|
|
||||||
mtCfg.cfgs[0] = pri
|
|
||||||
for i := range auxiliaryTenantIDs {
|
|
||||||
aux, err := NewOAuthConfig(activeDirectoryEndpoint, auxiliaryTenantIDs[i])
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to create OAuthConfig for tenant '%s': %v", auxiliaryTenantIDs[i], err)
|
|
||||||
}
|
|
||||||
mtCfg.cfgs[i+1] = aux
|
|
||||||
}
|
|
||||||
return mtCfg, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type multiTenantOAuthConfig struct {
|
|
||||||
// first config in the slice is the primary tenant
|
|
||||||
cfgs []*OAuthConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m multiTenantOAuthConfig) PrimaryTenant() *OAuthConfig {
|
|
||||||
return m.cfgs[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m multiTenantOAuthConfig) AuxiliaryTenants() []*OAuthConfig {
|
|
||||||
return m.cfgs[1:]
|
|
||||||
}
|
|
||||||
273
vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go
generated
vendored
273
vendor/github.com/Azure/go-autorest/autorest/adal/devicetoken.go
generated
vendored
@@ -1,273 +0,0 @@
|
|||||||
package adal
|
|
||||||
|
|
||||||
// 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 is largely based on rjw57/oauth2device's code, with the follow differences:
|
|
||||||
* scope -> resource, and only allow a single one
|
|
||||||
* receive "Message" in the DeviceCode struct and show it to users as the prompt
|
|
||||||
* azure-xplat-cli has the following behavior that this emulates:
|
|
||||||
- does not send client_secret during the token exchange
|
|
||||||
- sends resource again in the token exchange request
|
|
||||||
*/
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
logPrefix = "autorest/adal/devicetoken:"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrDeviceGeneric represents an unknown error from the token endpoint when using device flow
|
|
||||||
ErrDeviceGeneric = fmt.Errorf("%s Error while retrieving OAuth token: Unknown Error", logPrefix)
|
|
||||||
|
|
||||||
// ErrDeviceAccessDenied represents an access denied error from the token endpoint when using device flow
|
|
||||||
ErrDeviceAccessDenied = fmt.Errorf("%s Error while retrieving OAuth token: Access Denied", logPrefix)
|
|
||||||
|
|
||||||
// ErrDeviceAuthorizationPending represents the server waiting on the user to complete the device flow
|
|
||||||
ErrDeviceAuthorizationPending = fmt.Errorf("%s Error while retrieving OAuth token: Authorization Pending", logPrefix)
|
|
||||||
|
|
||||||
// ErrDeviceCodeExpired represents the server timing out and expiring the code during device flow
|
|
||||||
ErrDeviceCodeExpired = fmt.Errorf("%s Error while retrieving OAuth token: Code Expired", logPrefix)
|
|
||||||
|
|
||||||
// ErrDeviceSlowDown represents the service telling us we're polling too often during device flow
|
|
||||||
ErrDeviceSlowDown = fmt.Errorf("%s Error while retrieving OAuth token: Slow Down", logPrefix)
|
|
||||||
|
|
||||||
// ErrDeviceCodeEmpty represents an empty device code from the device endpoint while using device flow
|
|
||||||
ErrDeviceCodeEmpty = fmt.Errorf("%s Error while retrieving device code: Device Code Empty", logPrefix)
|
|
||||||
|
|
||||||
// ErrOAuthTokenEmpty represents an empty OAuth token from the token endpoint when using device flow
|
|
||||||
ErrOAuthTokenEmpty = fmt.Errorf("%s Error while retrieving OAuth token: Token Empty", logPrefix)
|
|
||||||
|
|
||||||
errCodeSendingFails = "Error occurred while sending request for Device Authorization Code"
|
|
||||||
errCodeHandlingFails = "Error occurred while handling response from the Device Endpoint"
|
|
||||||
errTokenSendingFails = "Error occurred while sending request with device code for a token"
|
|
||||||
errTokenHandlingFails = "Error occurred while handling response from the Token Endpoint (during device flow)"
|
|
||||||
errStatusNotOK = "Error HTTP status != 200"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DeviceCode is the object returned by the device auth endpoint
|
|
||||||
// It contains information to instruct the user to complete the auth flow
|
|
||||||
type DeviceCode struct {
|
|
||||||
DeviceCode *string `json:"device_code,omitempty"`
|
|
||||||
UserCode *string `json:"user_code,omitempty"`
|
|
||||||
VerificationURL *string `json:"verification_url,omitempty"`
|
|
||||||
ExpiresIn *int64 `json:"expires_in,string,omitempty"`
|
|
||||||
Interval *int64 `json:"interval,string,omitempty"`
|
|
||||||
|
|
||||||
Message *string `json:"message"` // Azure specific
|
|
||||||
Resource string // store the following, stored when initiating, used when exchanging
|
|
||||||
OAuthConfig OAuthConfig
|
|
||||||
ClientID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenError is the object returned by the token exchange endpoint
|
|
||||||
// when something is amiss
|
|
||||||
type TokenError struct {
|
|
||||||
Error *string `json:"error,omitempty"`
|
|
||||||
ErrorCodes []int `json:"error_codes,omitempty"`
|
|
||||||
ErrorDescription *string `json:"error_description,omitempty"`
|
|
||||||
Timestamp *string `json:"timestamp,omitempty"`
|
|
||||||
TraceID *string `json:"trace_id,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeviceToken is the object return by the token exchange endpoint
|
|
||||||
// It can either look like a Token or an ErrorToken, so put both here
|
|
||||||
// and check for presence of "Error" to know if we are in error state
|
|
||||||
type deviceToken struct {
|
|
||||||
Token
|
|
||||||
TokenError
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitiateDeviceAuth initiates a device auth flow. It returns a DeviceCode
|
|
||||||
// that can be used with CheckForUserCompletion or WaitForUserCompletion.
|
|
||||||
// Deprecated: use InitiateDeviceAuthWithContext() instead.
|
|
||||||
func InitiateDeviceAuth(sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) {
|
|
||||||
return InitiateDeviceAuthWithContext(context.Background(), sender, oauthConfig, clientID, resource)
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitiateDeviceAuthWithContext initiates a device auth flow. It returns a DeviceCode
|
|
||||||
// that can be used with CheckForUserCompletion or WaitForUserCompletion.
|
|
||||||
func InitiateDeviceAuthWithContext(ctx context.Context, sender Sender, oauthConfig OAuthConfig, clientID, resource string) (*DeviceCode, error) {
|
|
||||||
v := url.Values{
|
|
||||||
"client_id": []string{clientID},
|
|
||||||
"resource": []string{resource},
|
|
||||||
}
|
|
||||||
|
|
||||||
s := v.Encode()
|
|
||||||
body := ioutil.NopCloser(strings.NewReader(s))
|
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, oauthConfig.DeviceCodeEndpoint.String(), body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
req.ContentLength = int64(len(s))
|
|
||||||
req.Header.Set(contentType, mimeTypeFormPost)
|
|
||||||
resp, err := sender.Do(req.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeSendingFails, err.Error())
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
rb, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, errStatusNotOK)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(strings.Trim(string(rb), " ")) == 0 {
|
|
||||||
return nil, ErrDeviceCodeEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
var code DeviceCode
|
|
||||||
err = json.Unmarshal(rb, &code)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errCodeHandlingFails, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
code.ClientID = clientID
|
|
||||||
code.Resource = resource
|
|
||||||
code.OAuthConfig = oauthConfig
|
|
||||||
|
|
||||||
return &code, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckForUserCompletion takes a DeviceCode and checks with the Azure AD OAuth endpoint
|
|
||||||
// to see if the device flow has: been completed, timed out, or otherwise failed
|
|
||||||
// Deprecated: use CheckForUserCompletionWithContext() instead.
|
|
||||||
func CheckForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
|
|
||||||
return CheckForUserCompletionWithContext(context.Background(), sender, code)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckForUserCompletionWithContext takes a DeviceCode and checks with the Azure AD OAuth endpoint
|
|
||||||
// to see if the device flow has: been completed, timed out, or otherwise failed
|
|
||||||
func CheckForUserCompletionWithContext(ctx context.Context, sender Sender, code *DeviceCode) (*Token, error) {
|
|
||||||
v := url.Values{
|
|
||||||
"client_id": []string{code.ClientID},
|
|
||||||
"code": []string{*code.DeviceCode},
|
|
||||||
"grant_type": []string{OAuthGrantTypeDeviceCode},
|
|
||||||
"resource": []string{code.Resource},
|
|
||||||
}
|
|
||||||
|
|
||||||
s := v.Encode()
|
|
||||||
body := ioutil.NopCloser(strings.NewReader(s))
|
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, code.OAuthConfig.TokenEndpoint.String(), body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
req.ContentLength = int64(len(s))
|
|
||||||
req.Header.Set(contentType, mimeTypeFormPost)
|
|
||||||
resp, err := sender.Do(req.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenSendingFails, err.Error())
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
rb, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK && len(strings.Trim(string(rb), " ")) == 0 {
|
|
||||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, errStatusNotOK)
|
|
||||||
}
|
|
||||||
if len(strings.Trim(string(rb), " ")) == 0 {
|
|
||||||
return nil, ErrOAuthTokenEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
var token deviceToken
|
|
||||||
err = json.Unmarshal(rb, &token)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, errTokenHandlingFails, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
if token.Error == nil {
|
|
||||||
return &token.Token, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch *token.Error {
|
|
||||||
case "authorization_pending":
|
|
||||||
return nil, ErrDeviceAuthorizationPending
|
|
||||||
case "slow_down":
|
|
||||||
return nil, ErrDeviceSlowDown
|
|
||||||
case "access_denied":
|
|
||||||
return nil, ErrDeviceAccessDenied
|
|
||||||
case "code_expired":
|
|
||||||
return nil, ErrDeviceCodeExpired
|
|
||||||
default:
|
|
||||||
// return a more meaningful error message if available
|
|
||||||
if token.ErrorDescription != nil {
|
|
||||||
return nil, fmt.Errorf("%s %s: %s", logPrefix, *token.Error, *token.ErrorDescription)
|
|
||||||
}
|
|
||||||
return nil, ErrDeviceGeneric
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WaitForUserCompletion calls CheckForUserCompletion repeatedly until a token is granted or an error state occurs.
|
|
||||||
// This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'.
|
|
||||||
// Deprecated: use WaitForUserCompletionWithContext() instead.
|
|
||||||
func WaitForUserCompletion(sender Sender, code *DeviceCode) (*Token, error) {
|
|
||||||
return WaitForUserCompletionWithContext(context.Background(), sender, code)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WaitForUserCompletionWithContext calls CheckForUserCompletion repeatedly until a token is granted or an error
|
|
||||||
// state occurs. This prevents the user from looping and checking against 'ErrDeviceAuthorizationPending'.
|
|
||||||
func WaitForUserCompletionWithContext(ctx context.Context, sender Sender, code *DeviceCode) (*Token, error) {
|
|
||||||
intervalDuration := time.Duration(*code.Interval) * time.Second
|
|
||||||
waitDuration := intervalDuration
|
|
||||||
|
|
||||||
for {
|
|
||||||
token, err := CheckForUserCompletionWithContext(ctx, sender, code)
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
return token, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch err {
|
|
||||||
case ErrDeviceSlowDown:
|
|
||||||
waitDuration += waitDuration
|
|
||||||
case ErrDeviceAuthorizationPending:
|
|
||||||
// noop
|
|
||||||
default: // everything else is "fatal" to us
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if waitDuration > (intervalDuration * 3) {
|
|
||||||
return nil, fmt.Errorf("%s Error waiting for user to complete device flow. Server told us to slow_down too much", logPrefix)
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-time.After(waitDuration):
|
|
||||||
// noop
|
|
||||||
case <-ctx.Done():
|
|
||||||
return nil, ctx.Err()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
24
vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go
generated
vendored
24
vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go
generated
vendored
@@ -1,24 +0,0 @@
|
|||||||
// +build modhack
|
|
||||||
|
|
||||||
package adal
|
|
||||||
|
|
||||||
// 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 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"
|
|
||||||
135
vendor/github.com/Azure/go-autorest/autorest/adal/persist.go
generated
vendored
135
vendor/github.com/Azure/go-autorest/autorest/adal/persist.go
generated
vendored
@@ -1,135 +0,0 @@
|
|||||||
package adal
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/pkcs12"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrMissingCertificate is returned when no local certificate is found in the provided PFX data.
|
|
||||||
ErrMissingCertificate = errors.New("adal: certificate missing")
|
|
||||||
|
|
||||||
// ErrMissingPrivateKey is returned when no private key is found in the provided PFX data.
|
|
||||||
ErrMissingPrivateKey = errors.New("adal: private key missing")
|
|
||||||
)
|
|
||||||
|
|
||||||
// LoadToken restores a Token object from a file located at 'path'.
|
|
||||||
func LoadToken(path string) (*Token, error) {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to open file (%s) while loading token: %v", path, err)
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
var token Token
|
|
||||||
|
|
||||||
dec := json.NewDecoder(file)
|
|
||||||
if err = dec.Decode(&token); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to decode contents of file (%s) into Token representation: %v", path, err)
|
|
||||||
}
|
|
||||||
return &token, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SaveToken persists an oauth token at the given location on disk.
|
|
||||||
// It moves the new file into place so it can safely be used to replace an existing file
|
|
||||||
// that maybe accessed by multiple processes.
|
|
||||||
func SaveToken(path string, mode os.FileMode, token Token) error {
|
|
||||||
dir := filepath.Dir(path)
|
|
||||||
err := os.MkdirAll(dir, os.ModePerm)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to create directory (%s) to store token in: %v", dir, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
newFile, err := ioutil.TempFile(dir, "token")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to create the temp file to write the token: %v", err)
|
|
||||||
}
|
|
||||||
tempPath := newFile.Name()
|
|
||||||
|
|
||||||
if err := json.NewEncoder(newFile).Encode(token); err != nil {
|
|
||||||
return fmt.Errorf("failed to encode token to file (%s) while saving token: %v", tempPath, err)
|
|
||||||
}
|
|
||||||
if err := newFile.Close(); err != nil {
|
|
||||||
return fmt.Errorf("failed to close temp file %s: %v", tempPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Atomic replace to avoid multi-writer file corruptions
|
|
||||||
if err := os.Rename(tempPath, path); err != nil {
|
|
||||||
return fmt.Errorf("failed to move temporary token to desired output location. src=%s dst=%s: %v", tempPath, path, err)
|
|
||||||
}
|
|
||||||
if err := os.Chmod(path, mode); err != nil {
|
|
||||||
return fmt.Errorf("failed to chmod the token file %s: %v", path, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodePfxCertificateData extracts the x509 certificate and RSA private key from the provided PFX data.
|
|
||||||
// The PFX data must contain a private key along with a certificate whose public key matches that of the
|
|
||||||
// private key or an error is returned.
|
|
||||||
// If the private key is not password protected pass the empty string for password.
|
|
||||||
func DecodePfxCertificateData(pfxData []byte, password string) (*x509.Certificate, *rsa.PrivateKey, error) {
|
|
||||||
blocks, err := pkcs12.ToPEM(pfxData, password)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
// first extract the private key
|
|
||||||
var priv *rsa.PrivateKey
|
|
||||||
for _, block := range blocks {
|
|
||||||
if block.Type == "PRIVATE KEY" {
|
|
||||||
priv, err = x509.ParsePKCS1PrivateKey(block.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if priv == nil {
|
|
||||||
return nil, nil, ErrMissingPrivateKey
|
|
||||||
}
|
|
||||||
// now find the certificate with the matching public key of our private key
|
|
||||||
var cert *x509.Certificate
|
|
||||||
for _, block := range blocks {
|
|
||||||
if block.Type == "CERTIFICATE" {
|
|
||||||
pcert, err := x509.ParseCertificate(block.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
certKey, ok := pcert.PublicKey.(*rsa.PublicKey)
|
|
||||||
if !ok {
|
|
||||||
// keep looking
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if priv.E == certKey.E && priv.N.Cmp(certKey.N) == 0 {
|
|
||||||
// found a match
|
|
||||||
cert = pcert
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if cert == nil {
|
|
||||||
return nil, nil, ErrMissingCertificate
|
|
||||||
}
|
|
||||||
return cert, priv, nil
|
|
||||||
}
|
|
||||||
96
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
96
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
@@ -1,96 +0,0 @@
|
|||||||
package adal
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"crypto/tls"
|
|
||||||
"net/http"
|
|
||||||
"net/http/cookiejar"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/Azure/go-autorest/tracing"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
contentType = "Content-Type"
|
|
||||||
mimeTypeFormPost = "application/x-www-form-urlencoded"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DO NOT ACCESS THIS DIRECTLY. go through sender()
|
|
||||||
var defaultSender Sender
|
|
||||||
var defaultSenderInit = &sync.Once{}
|
|
||||||
|
|
||||||
// Sender is the interface that wraps the Do method to send HTTP requests.
|
|
||||||
//
|
|
||||||
// The standard http.Client conforms to this interface.
|
|
||||||
type Sender interface {
|
|
||||||
Do(*http.Request) (*http.Response, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SenderFunc is a method that implements the Sender interface.
|
|
||||||
type SenderFunc func(*http.Request) (*http.Response, error)
|
|
||||||
|
|
||||||
// Do implements the Sender interface on SenderFunc.
|
|
||||||
func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) {
|
|
||||||
return sf(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendDecorator takes and possibly decorates, by wrapping, a Sender. Decorators may affect the
|
|
||||||
// http.Request and pass it along or, first, pass the http.Request along then react to the
|
|
||||||
// http.Response result.
|
|
||||||
type SendDecorator func(Sender) Sender
|
|
||||||
|
|
||||||
// CreateSender creates, decorates, and returns, as a Sender, the default http.Client.
|
|
||||||
func CreateSender(decorators ...SendDecorator) Sender {
|
|
||||||
return DecorateSender(sender(), decorators...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to
|
|
||||||
// the Sender. Decorators are applied in the order received, but their affect upon the request
|
|
||||||
// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a
|
|
||||||
// post-decorator (pass the http.Request along and react to the results in http.Response).
|
|
||||||
func DecorateSender(s Sender, decorators ...SendDecorator) Sender {
|
|
||||||
for _, decorate := range decorators {
|
|
||||||
s = decorate(s)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func sender() Sender {
|
|
||||||
// note that we can't init defaultSender in init() since it will
|
|
||||||
// execute before calling code has had a chance to enable tracing
|
|
||||||
defaultSenderInit.Do(func() {
|
|
||||||
// Use behaviour compatible with DefaultTransport, but require TLS minimum version.
|
|
||||||
defaultTransport := http.DefaultTransport.(*http.Transport)
|
|
||||||
transport := &http.Transport{
|
|
||||||
Proxy: defaultTransport.Proxy,
|
|
||||||
DialContext: defaultTransport.DialContext,
|
|
||||||
MaxIdleConns: defaultTransport.MaxIdleConns,
|
|
||||||
IdleConnTimeout: defaultTransport.IdleConnTimeout,
|
|
||||||
TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout,
|
|
||||||
ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout,
|
|
||||||
TLSClientConfig: &tls.Config{
|
|
||||||
MinVersion: tls.VersionTLS12,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
var roundTripper http.RoundTripper = transport
|
|
||||||
if tracing.IsEnabled() {
|
|
||||||
roundTripper = tracing.NewTransport(transport)
|
|
||||||
}
|
|
||||||
j, _ := cookiejar.New(nil)
|
|
||||||
defaultSender = &http.Client{Jar: j, Transport: roundTripper}
|
|
||||||
})
|
|
||||||
return defaultSender
|
|
||||||
}
|
|
||||||
1336
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
1336
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
File diff suppressed because it is too large
Load Diff
75
vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go
generated
vendored
75
vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go
generated
vendored
@@ -1,75 +0,0 @@
|
|||||||
// +build go1.13
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
package adal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) {
|
|
||||||
tempCtx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
|
|
||||||
defer cancel()
|
|
||||||
// http.NewRequestWithContext() was added in Go 1.13
|
|
||||||
req, _ := http.NewRequestWithContext(tempCtx, http.MethodGet, msiEndpoint, nil)
|
|
||||||
q := req.URL.Query()
|
|
||||||
q.Add("api-version", msiAPIVersion)
|
|
||||||
req.URL.RawQuery = q.Encode()
|
|
||||||
return sender.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by
|
|
||||||
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
|
|
||||||
func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error {
|
|
||||||
if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil {
|
|
||||||
return fmt.Errorf("failed to refresh primary token: %w", err)
|
|
||||||
}
|
|
||||||
for _, aux := range mt.AuxiliaryTokens {
|
|
||||||
if err := aux.EnsureFreshWithContext(ctx); err != nil {
|
|
||||||
return fmt.Errorf("failed to refresh auxiliary token: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RefreshWithContext obtains a fresh token for the Service Principal.
|
|
||||||
func (mt *MultiTenantServicePrincipalToken) RefreshWithContext(ctx context.Context) error {
|
|
||||||
if err := mt.PrimaryToken.RefreshWithContext(ctx); err != nil {
|
|
||||||
return fmt.Errorf("failed to refresh primary token: %w", err)
|
|
||||||
}
|
|
||||||
for _, aux := range mt.AuxiliaryTokens {
|
|
||||||
if err := aux.RefreshWithContext(ctx); err != nil {
|
|
||||||
return fmt.Errorf("failed to refresh auxiliary token: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RefreshExchangeWithContext refreshes the token, but for a different resource.
|
|
||||||
func (mt *MultiTenantServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error {
|
|
||||||
if err := mt.PrimaryToken.RefreshExchangeWithContext(ctx, resource); err != nil {
|
|
||||||
return fmt.Errorf("failed to refresh primary token: %w", err)
|
|
||||||
}
|
|
||||||
for _, aux := range mt.AuxiliaryTokens {
|
|
||||||
if err := aux.RefreshExchangeWithContext(ctx, resource); err != nil {
|
|
||||||
return fmt.Errorf("failed to refresh auxiliary token: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
74
vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go
generated
vendored
74
vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go
generated
vendored
@@ -1,74 +0,0 @@
|
|||||||
// +build !go1.13
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
package adal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getMSIEndpoint(ctx context.Context, sender Sender) (*http.Response, error) {
|
|
||||||
tempCtx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
|
|
||||||
defer cancel()
|
|
||||||
req, _ := http.NewRequest(http.MethodGet, msiEndpoint, nil)
|
|
||||||
req = req.WithContext(tempCtx)
|
|
||||||
q := req.URL.Query()
|
|
||||||
q.Add("api-version", msiAPIVersion)
|
|
||||||
req.URL.RawQuery = q.Encode()
|
|
||||||
return sender.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by
|
|
||||||
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
|
|
||||||
func (mt *MultiTenantServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error {
|
|
||||||
if err := mt.PrimaryToken.EnsureFreshWithContext(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, aux := range mt.AuxiliaryTokens {
|
|
||||||
if err := aux.EnsureFreshWithContext(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RefreshWithContext obtains a fresh token for the Service Principal.
|
|
||||||
func (mt *MultiTenantServicePrincipalToken) RefreshWithContext(ctx context.Context) error {
|
|
||||||
if err := mt.PrimaryToken.RefreshWithContext(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, aux := range mt.AuxiliaryTokens {
|
|
||||||
if err := aux.RefreshWithContext(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RefreshExchangeWithContext refreshes the token, but for a different resource.
|
|
||||||
func (mt *MultiTenantServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error {
|
|
||||||
if err := mt.PrimaryToken.RefreshExchangeWithContext(ctx, resource); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, aux := range mt.AuxiliaryTokens {
|
|
||||||
if err := aux.RefreshExchangeWithContext(ctx, resource); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
45
vendor/github.com/Azure/go-autorest/autorest/adal/version.go
generated
vendored
45
vendor/github.com/Azure/go-autorest/autorest/adal/version.go
generated
vendored
@@ -1,45 +0,0 @@
|
|||||||
package adal
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
const number = "v1.0.0"
|
|
||||||
|
|
||||||
var (
|
|
||||||
ua = fmt.Sprintf("Go/%s (%s-%s) go-autorest/adal/%s",
|
|
||||||
runtime.Version(),
|
|
||||||
runtime.GOARCH,
|
|
||||||
runtime.GOOS,
|
|
||||||
number,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
// UserAgent returns a string containing the Go version, system architecture and OS, and the adal version.
|
|
||||||
func UserAgent() string {
|
|
||||||
return ua
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddToUserAgent adds an extension to the current user agent
|
|
||||||
func AddToUserAgent(extension string) error {
|
|
||||||
if extension != "" {
|
|
||||||
ua = fmt.Sprintf("%s %s", ua, extension)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("Extension was empty, User Agent remained as '%s'", ua)
|
|
||||||
}
|
|
||||||
353
vendor/github.com/Azure/go-autorest/autorest/authorization.go
generated
vendored
353
vendor/github.com/Azure/go-autorest/autorest/authorization.go
generated
vendored
@@ -1,353 +0,0 @@
|
|||||||
package autorest
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"crypto/tls"
|
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/Azure/go-autorest/autorest/adal"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
bearerChallengeHeader = "Www-Authenticate"
|
|
||||||
bearer = "Bearer"
|
|
||||||
tenantID = "tenantID"
|
|
||||||
apiKeyAuthorizerHeader = "Ocp-Apim-Subscription-Key"
|
|
||||||
bingAPISdkHeader = "X-BingApis-SDK-Client"
|
|
||||||
golangBingAPISdkHeaderValue = "Go-SDK"
|
|
||||||
authorization = "Authorization"
|
|
||||||
basic = "Basic"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Authorizer is the interface that provides a PrepareDecorator used to supply request
|
|
||||||
// authorization. Most often, the Authorizer decorator runs last so it has access to the full
|
|
||||||
// state of the formed HTTP request.
|
|
||||||
type Authorizer interface {
|
|
||||||
WithAuthorization() PrepareDecorator
|
|
||||||
}
|
|
||||||
|
|
||||||
// NullAuthorizer implements a default, "do nothing" Authorizer.
|
|
||||||
type NullAuthorizer struct{}
|
|
||||||
|
|
||||||
// WithAuthorization returns a PrepareDecorator that does nothing.
|
|
||||||
func (na NullAuthorizer) WithAuthorization() PrepareDecorator {
|
|
||||||
return WithNothing()
|
|
||||||
}
|
|
||||||
|
|
||||||
// APIKeyAuthorizer implements API Key authorization.
|
|
||||||
type APIKeyAuthorizer struct {
|
|
||||||
headers map[string]interface{}
|
|
||||||
queryParameters map[string]interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAPIKeyAuthorizerWithHeaders creates an ApiKeyAuthorizer with headers.
|
|
||||||
func NewAPIKeyAuthorizerWithHeaders(headers map[string]interface{}) *APIKeyAuthorizer {
|
|
||||||
return NewAPIKeyAuthorizer(headers, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAPIKeyAuthorizerWithQueryParameters creates an ApiKeyAuthorizer with query parameters.
|
|
||||||
func NewAPIKeyAuthorizerWithQueryParameters(queryParameters map[string]interface{}) *APIKeyAuthorizer {
|
|
||||||
return NewAPIKeyAuthorizer(nil, queryParameters)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAPIKeyAuthorizer creates an ApiKeyAuthorizer with headers.
|
|
||||||
func NewAPIKeyAuthorizer(headers map[string]interface{}, queryParameters map[string]interface{}) *APIKeyAuthorizer {
|
|
||||||
return &APIKeyAuthorizer{headers: headers, queryParameters: queryParameters}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP headers and Query Parameters.
|
|
||||||
func (aka *APIKeyAuthorizer) WithAuthorization() PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return DecoratePreparer(p, WithHeaders(aka.headers), WithQueryParameters(aka.queryParameters))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CognitiveServicesAuthorizer implements authorization for Cognitive Services.
|
|
||||||
type CognitiveServicesAuthorizer struct {
|
|
||||||
subscriptionKey string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCognitiveServicesAuthorizer is
|
|
||||||
func NewCognitiveServicesAuthorizer(subscriptionKey string) *CognitiveServicesAuthorizer {
|
|
||||||
return &CognitiveServicesAuthorizer{subscriptionKey: subscriptionKey}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAuthorization is
|
|
||||||
func (csa *CognitiveServicesAuthorizer) WithAuthorization() PrepareDecorator {
|
|
||||||
headers := make(map[string]interface{})
|
|
||||||
headers[apiKeyAuthorizerHeader] = csa.subscriptionKey
|
|
||||||
headers[bingAPISdkHeader] = golangBingAPISdkHeaderValue
|
|
||||||
|
|
||||||
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
|
|
||||||
}
|
|
||||||
|
|
||||||
// BearerAuthorizer implements the bearer authorization
|
|
||||||
type BearerAuthorizer struct {
|
|
||||||
tokenProvider adal.OAuthTokenProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBearerAuthorizer crates a BearerAuthorizer using the given token provider
|
|
||||||
func NewBearerAuthorizer(tp adal.OAuthTokenProvider) *BearerAuthorizer {
|
|
||||||
return &BearerAuthorizer{tokenProvider: tp}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
|
||||||
// value is "Bearer " followed by the token.
|
|
||||||
//
|
|
||||||
// By default, the token will be automatically refreshed through the Refresher interface.
|
|
||||||
func (ba *BearerAuthorizer) WithAuthorization() PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
// the ordering is important here, prefer RefresherWithContext if available
|
|
||||||
if refresher, ok := ba.tokenProvider.(adal.RefresherWithContext); ok {
|
|
||||||
err = refresher.EnsureFreshWithContext(r.Context())
|
|
||||||
} else if refresher, ok := ba.tokenProvider.(adal.Refresher); ok {
|
|
||||||
err = refresher.EnsureFresh()
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
var resp *http.Response
|
|
||||||
if tokError, ok := err.(adal.TokenRefreshError); ok {
|
|
||||||
resp = tokError.Response()
|
|
||||||
}
|
|
||||||
return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", resp,
|
|
||||||
"Failed to refresh the Token for request to %s", r.URL)
|
|
||||||
}
|
|
||||||
return Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", ba.tokenProvider.OAuthToken())))
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenProvider returns OAuthTokenProvider so that it can be used for authorization outside the REST.
|
|
||||||
func (ba *BearerAuthorizer) TokenProvider() adal.OAuthTokenProvider {
|
|
||||||
return ba.tokenProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
// BearerAuthorizerCallbackFunc is the authentication callback signature.
|
|
||||||
type BearerAuthorizerCallbackFunc func(tenantID, resource string) (*BearerAuthorizer, error)
|
|
||||||
|
|
||||||
// BearerAuthorizerCallback implements bearer authorization via a callback.
|
|
||||||
type BearerAuthorizerCallback struct {
|
|
||||||
sender Sender
|
|
||||||
callback BearerAuthorizerCallbackFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBearerAuthorizerCallback creates a bearer authorization callback. The callback
|
|
||||||
// is invoked when the HTTP request is submitted.
|
|
||||||
func NewBearerAuthorizerCallback(s Sender, callback BearerAuthorizerCallbackFunc) *BearerAuthorizerCallback {
|
|
||||||
if s == nil {
|
|
||||||
s = sender(tls.RenegotiateNever)
|
|
||||||
}
|
|
||||||
return &BearerAuthorizerCallback{sender: s, callback: callback}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose value
|
|
||||||
// is "Bearer " followed by the token. The BearerAuthorizer is obtained via a user-supplied callback.
|
|
||||||
//
|
|
||||||
// By default, the token will be automatically refreshed through the Refresher interface.
|
|
||||||
func (bacb *BearerAuthorizerCallback) WithAuthorization() PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
// make a copy of the request and remove the body as it's not
|
|
||||||
// required and avoids us having to create a copy of it.
|
|
||||||
rCopy := *r
|
|
||||||
removeRequestBody(&rCopy)
|
|
||||||
|
|
||||||
resp, err := bacb.sender.Do(&rCopy)
|
|
||||||
if err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
DrainResponseBody(resp)
|
|
||||||
if resp.StatusCode == 401 && hasBearerChallenge(resp.Header) {
|
|
||||||
bc, err := newBearerChallenge(resp.Header)
|
|
||||||
if err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
if bacb.callback != nil {
|
|
||||||
ba, err := bacb.callback(bc.values[tenantID], bc.values["resource"])
|
|
||||||
if err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
return Prepare(r, ba.WithAuthorization())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns true if the HTTP response contains a bearer challenge
|
|
||||||
func hasBearerChallenge(header http.Header) bool {
|
|
||||||
authHeader := header.Get(bearerChallengeHeader)
|
|
||||||
if len(authHeader) == 0 || strings.Index(authHeader, bearer) < 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
type bearerChallenge struct {
|
|
||||||
values map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newBearerChallenge(header http.Header) (bc bearerChallenge, err error) {
|
|
||||||
challenge := strings.TrimSpace(header.Get(bearerChallengeHeader))
|
|
||||||
trimmedChallenge := challenge[len(bearer)+1:]
|
|
||||||
|
|
||||||
// challenge is a set of key=value pairs that are comma delimited
|
|
||||||
pairs := strings.Split(trimmedChallenge, ",")
|
|
||||||
if len(pairs) < 1 {
|
|
||||||
err = fmt.Errorf("challenge '%s' contains no pairs", challenge)
|
|
||||||
return bc, err
|
|
||||||
}
|
|
||||||
|
|
||||||
bc.values = make(map[string]string)
|
|
||||||
for i := range pairs {
|
|
||||||
trimmedPair := strings.TrimSpace(pairs[i])
|
|
||||||
pair := strings.Split(trimmedPair, "=")
|
|
||||||
if len(pair) == 2 {
|
|
||||||
// remove the enclosing quotes
|
|
||||||
key := strings.Trim(pair[0], "\"")
|
|
||||||
value := strings.Trim(pair[1], "\"")
|
|
||||||
|
|
||||||
switch key {
|
|
||||||
case "authorization", "authorization_uri":
|
|
||||||
// strip the tenant ID from the authorization URL
|
|
||||||
asURL, err := url.Parse(value)
|
|
||||||
if err != nil {
|
|
||||||
return bc, err
|
|
||||||
}
|
|
||||||
bc.values[tenantID] = asURL.Path[1:]
|
|
||||||
default:
|
|
||||||
bc.values[key] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bc, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// EventGridKeyAuthorizer implements authorization for event grid using key authentication.
|
|
||||||
type EventGridKeyAuthorizer struct {
|
|
||||||
topicKey string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEventGridKeyAuthorizer creates a new EventGridKeyAuthorizer
|
|
||||||
// with the specified topic key.
|
|
||||||
func NewEventGridKeyAuthorizer(topicKey string) EventGridKeyAuthorizer {
|
|
||||||
return EventGridKeyAuthorizer{topicKey: topicKey}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAuthorization returns a PrepareDecorator that adds the aeg-sas-key authentication header.
|
|
||||||
func (egta EventGridKeyAuthorizer) WithAuthorization() PrepareDecorator {
|
|
||||||
headers := map[string]interface{}{
|
|
||||||
"aeg-sas-key": egta.topicKey,
|
|
||||||
}
|
|
||||||
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
|
|
||||||
}
|
|
||||||
|
|
||||||
// BasicAuthorizer implements basic HTTP authorization by adding the Authorization HTTP header
|
|
||||||
// with the value "Basic <TOKEN>" where <TOKEN> is a base64-encoded username:password tuple.
|
|
||||||
type BasicAuthorizer struct {
|
|
||||||
userName string
|
|
||||||
password string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBasicAuthorizer creates a new BasicAuthorizer with the specified username and password.
|
|
||||||
func NewBasicAuthorizer(userName, password string) *BasicAuthorizer {
|
|
||||||
return &BasicAuthorizer{
|
|
||||||
userName: userName,
|
|
||||||
password: password,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
|
||||||
// value is "Basic " followed by the base64-encoded username:password tuple.
|
|
||||||
func (ba *BasicAuthorizer) WithAuthorization() PrepareDecorator {
|
|
||||||
headers := make(map[string]interface{})
|
|
||||||
headers[authorization] = basic + " " + base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", ba.userName, ba.password)))
|
|
||||||
|
|
||||||
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
|
|
||||||
}
|
|
||||||
|
|
||||||
// MultiTenantServicePrincipalTokenAuthorizer provides authentication across tenants.
|
|
||||||
type MultiTenantServicePrincipalTokenAuthorizer interface {
|
|
||||||
WithAuthorization() PrepareDecorator
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMultiTenantServicePrincipalTokenAuthorizer crates a BearerAuthorizer using the given token provider
|
|
||||||
func NewMultiTenantServicePrincipalTokenAuthorizer(tp adal.MultitenantOAuthTokenProvider) MultiTenantServicePrincipalTokenAuthorizer {
|
|
||||||
return NewMultiTenantBearerAuthorizer(tp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MultiTenantBearerAuthorizer implements bearer authorization across multiple tenants.
|
|
||||||
type MultiTenantBearerAuthorizer struct {
|
|
||||||
tp adal.MultitenantOAuthTokenProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMultiTenantBearerAuthorizer creates a MultiTenantBearerAuthorizer using the given token provider.
|
|
||||||
func NewMultiTenantBearerAuthorizer(tp adal.MultitenantOAuthTokenProvider) *MultiTenantBearerAuthorizer {
|
|
||||||
return &MultiTenantBearerAuthorizer{tp: tp}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header using the
|
|
||||||
// primary token along with the auxiliary authorization header using the auxiliary tokens.
|
|
||||||
//
|
|
||||||
// By default, the token will be automatically refreshed through the Refresher interface.
|
|
||||||
func (mt *MultiTenantBearerAuthorizer) WithAuthorization() PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
if refresher, ok := mt.tp.(adal.RefresherWithContext); ok {
|
|
||||||
err = refresher.EnsureFreshWithContext(r.Context())
|
|
||||||
if err != nil {
|
|
||||||
var resp *http.Response
|
|
||||||
if tokError, ok := err.(adal.TokenRefreshError); ok {
|
|
||||||
resp = tokError.Response()
|
|
||||||
}
|
|
||||||
return r, NewErrorWithError(err, "azure.multiTenantSPTAuthorizer", "WithAuthorization", resp,
|
|
||||||
"Failed to refresh one or more Tokens for request to %s", r.URL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r, err = Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", mt.tp.PrimaryOAuthToken())))
|
|
||||||
if err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
auxTokens := mt.tp.AuxiliaryOAuthTokens()
|
|
||||||
for i := range auxTokens {
|
|
||||||
auxTokens[i] = fmt.Sprintf("Bearer %s", auxTokens[i])
|
|
||||||
}
|
|
||||||
return Prepare(r, WithHeader(headerAuxAuthorization, strings.Join(auxTokens, ", ")))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenProvider returns the underlying MultitenantOAuthTokenProvider for this authorizer.
|
|
||||||
func (mt *MultiTenantBearerAuthorizer) TokenProvider() adal.MultitenantOAuthTokenProvider {
|
|
||||||
return mt.tp
|
|
||||||
}
|
|
||||||
66
vendor/github.com/Azure/go-autorest/autorest/authorization_sas.go
generated
vendored
66
vendor/github.com/Azure/go-autorest/autorest/authorization_sas.go
generated
vendored
@@ -1,66 +0,0 @@
|
|||||||
package autorest
|
|
||||||
|
|
||||||
// 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"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SASTokenAuthorizer implements an authorization for SAS Token Authentication
|
|
||||||
// this can be used for interaction with Blob Storage Endpoints
|
|
||||||
type SASTokenAuthorizer struct {
|
|
||||||
sasToken string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSASTokenAuthorizer creates a SASTokenAuthorizer using the given credentials
|
|
||||||
func NewSASTokenAuthorizer(sasToken string) (*SASTokenAuthorizer, error) {
|
|
||||||
if strings.TrimSpace(sasToken) == "" {
|
|
||||||
return nil, fmt.Errorf("sasToken cannot be empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
token := sasToken
|
|
||||||
if strings.HasPrefix(sasToken, "?") {
|
|
||||||
token = strings.TrimPrefix(sasToken, "?")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &SASTokenAuthorizer{
|
|
||||||
sasToken: token,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAuthorization returns a PrepareDecorator that adds a shared access signature token to the
|
|
||||||
// URI's query parameters. This can be used for the Blob, Queue, and File Services.
|
|
||||||
//
|
|
||||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/delegate-access-with-shared-access-signature
|
|
||||||
func (sas *SASTokenAuthorizer) WithAuthorization() PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.URL.RawQuery == "" {
|
|
||||||
r.URL.RawQuery = sas.sasToken
|
|
||||||
} else if !strings.Contains(r.URL.RawQuery, sas.sasToken) {
|
|
||||||
r.URL.RawQuery = fmt.Sprintf("%s&%s", r.URL.RawQuery, sas.sasToken)
|
|
||||||
}
|
|
||||||
|
|
||||||
return Prepare(r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
307
vendor/github.com/Azure/go-autorest/autorest/authorization_storage.go
generated
vendored
307
vendor/github.com/Azure/go-autorest/autorest/authorization_storage.go
generated
vendored
@@ -1,307 +0,0 @@
|
|||||||
package autorest
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"bytes"
|
|
||||||
"crypto/hmac"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SharedKeyType defines the enumeration for the various shared key types.
|
|
||||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key for details on the shared key types.
|
|
||||||
type SharedKeyType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// SharedKey is used to authorize against blobs, files and queues services.
|
|
||||||
SharedKey SharedKeyType = "sharedKey"
|
|
||||||
|
|
||||||
// SharedKeyForTable is used to authorize against the table service.
|
|
||||||
SharedKeyForTable SharedKeyType = "sharedKeyTable"
|
|
||||||
|
|
||||||
// SharedKeyLite is used to authorize against blobs, files and queues services. It's provided for
|
|
||||||
// backwards compatibility with API versions before 2009-09-19. Prefer SharedKey instead.
|
|
||||||
SharedKeyLite SharedKeyType = "sharedKeyLite"
|
|
||||||
|
|
||||||
// SharedKeyLiteForTable is used to authorize against the table service. It's provided for
|
|
||||||
// backwards compatibility with older table API versions. Prefer SharedKeyForTable instead.
|
|
||||||
SharedKeyLiteForTable SharedKeyType = "sharedKeyLiteTable"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
headerAccept = "Accept"
|
|
||||||
headerAcceptCharset = "Accept-Charset"
|
|
||||||
headerContentEncoding = "Content-Encoding"
|
|
||||||
headerContentLength = "Content-Length"
|
|
||||||
headerContentMD5 = "Content-MD5"
|
|
||||||
headerContentLanguage = "Content-Language"
|
|
||||||
headerIfModifiedSince = "If-Modified-Since"
|
|
||||||
headerIfMatch = "If-Match"
|
|
||||||
headerIfNoneMatch = "If-None-Match"
|
|
||||||
headerIfUnmodifiedSince = "If-Unmodified-Since"
|
|
||||||
headerDate = "Date"
|
|
||||||
headerXMSDate = "X-Ms-Date"
|
|
||||||
headerXMSVersion = "x-ms-version"
|
|
||||||
headerRange = "Range"
|
|
||||||
)
|
|
||||||
|
|
||||||
const storageEmulatorAccountName = "devstoreaccount1"
|
|
||||||
|
|
||||||
// SharedKeyAuthorizer implements an authorization for Shared Key
|
|
||||||
// this can be used for interaction with Blob, File and Queue Storage Endpoints
|
|
||||||
type SharedKeyAuthorizer struct {
|
|
||||||
accountName string
|
|
||||||
accountKey []byte
|
|
||||||
keyType SharedKeyType
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSharedKeyAuthorizer creates a SharedKeyAuthorizer using the provided credentials and shared key type.
|
|
||||||
func NewSharedKeyAuthorizer(accountName, accountKey string, keyType SharedKeyType) (*SharedKeyAuthorizer, error) {
|
|
||||||
key, err := base64.StdEncoding.DecodeString(accountKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("malformed storage account key: %v", err)
|
|
||||||
}
|
|
||||||
return &SharedKeyAuthorizer{
|
|
||||||
accountName: accountName,
|
|
||||||
accountKey: key,
|
|
||||||
keyType: keyType,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
|
||||||
// value is "<SharedKeyType> " followed by the computed key.
|
|
||||||
// This can be used for the Blob, Queue, and File Services
|
|
||||||
//
|
|
||||||
// from: https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key
|
|
||||||
// You may use Shared Key authorization to authorize a request made against the
|
|
||||||
// 2009-09-19 version and later of the Blob and Queue services,
|
|
||||||
// and version 2014-02-14 and later of the File services.
|
|
||||||
func (sk *SharedKeyAuthorizer) WithAuthorization() PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sk, err := buildSharedKey(sk.accountName, sk.accountKey, r, sk.keyType)
|
|
||||||
if err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
return Prepare(r, WithHeader(headerAuthorization, sk))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildSharedKey(accName string, accKey []byte, req *http.Request, keyType SharedKeyType) (string, error) {
|
|
||||||
canRes, err := buildCanonicalizedResource(accName, req.URL.String(), keyType)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.Header == nil {
|
|
||||||
req.Header = http.Header{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensure date is set
|
|
||||||
if req.Header.Get(headerDate) == "" && req.Header.Get(headerXMSDate) == "" {
|
|
||||||
date := time.Now().UTC().Format(http.TimeFormat)
|
|
||||||
req.Header.Set(headerXMSDate, date)
|
|
||||||
}
|
|
||||||
canString, err := buildCanonicalizedString(req.Method, req.Header, canRes, keyType)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return createAuthorizationHeader(accName, accKey, canString, keyType), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildCanonicalizedResource(accountName, uri string, keyType SharedKeyType) (string, error) {
|
|
||||||
errMsg := "buildCanonicalizedResource error: %s"
|
|
||||||
u, err := url.Parse(uri)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf(errMsg, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
cr := bytes.NewBufferString("")
|
|
||||||
if accountName != storageEmulatorAccountName {
|
|
||||||
cr.WriteString("/")
|
|
||||||
cr.WriteString(getCanonicalizedAccountName(accountName))
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(u.Path) > 0 {
|
|
||||||
// Any portion of the CanonicalizedResource string that is derived from
|
|
||||||
// the resource's URI should be encoded exactly as it is in the URI.
|
|
||||||
// -- https://msdn.microsoft.com/en-gb/library/azure/dd179428.aspx
|
|
||||||
cr.WriteString(u.EscapedPath())
|
|
||||||
} else {
|
|
||||||
// a slash is required to indicate the root path
|
|
||||||
cr.WriteString("/")
|
|
||||||
}
|
|
||||||
|
|
||||||
params, err := url.ParseQuery(u.RawQuery)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf(errMsg, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// See https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/Core/Util/AuthenticationUtility.cs#L277
|
|
||||||
if keyType == SharedKey {
|
|
||||||
if len(params) > 0 {
|
|
||||||
cr.WriteString("\n")
|
|
||||||
|
|
||||||
keys := []string{}
|
|
||||||
for key := range params {
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
sort.Strings(keys)
|
|
||||||
|
|
||||||
completeParams := []string{}
|
|
||||||
for _, key := range keys {
|
|
||||||
if len(params[key]) > 1 {
|
|
||||||
sort.Strings(params[key])
|
|
||||||
}
|
|
||||||
|
|
||||||
completeParams = append(completeParams, fmt.Sprintf("%s:%s", key, strings.Join(params[key], ",")))
|
|
||||||
}
|
|
||||||
cr.WriteString(strings.Join(completeParams, "\n"))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// search for "comp" parameter, if exists then add it to canonicalizedresource
|
|
||||||
if v, ok := params["comp"]; ok {
|
|
||||||
cr.WriteString("?comp=" + v[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(cr.Bytes()), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCanonicalizedAccountName(accountName string) string {
|
|
||||||
// since we may be trying to access a secondary storage account, we need to
|
|
||||||
// remove the -secondary part of the storage name
|
|
||||||
return strings.TrimSuffix(accountName, "-secondary")
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildCanonicalizedString(verb string, headers http.Header, canonicalizedResource string, keyType SharedKeyType) (string, error) {
|
|
||||||
contentLength := headers.Get(headerContentLength)
|
|
||||||
if contentLength == "0" {
|
|
||||||
contentLength = ""
|
|
||||||
}
|
|
||||||
date := headers.Get(headerDate)
|
|
||||||
if v := headers.Get(headerXMSDate); v != "" {
|
|
||||||
if keyType == SharedKey || keyType == SharedKeyLite {
|
|
||||||
date = ""
|
|
||||||
} else {
|
|
||||||
date = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var canString string
|
|
||||||
switch keyType {
|
|
||||||
case SharedKey:
|
|
||||||
canString = strings.Join([]string{
|
|
||||||
verb,
|
|
||||||
headers.Get(headerContentEncoding),
|
|
||||||
headers.Get(headerContentLanguage),
|
|
||||||
contentLength,
|
|
||||||
headers.Get(headerContentMD5),
|
|
||||||
headers.Get(headerContentType),
|
|
||||||
date,
|
|
||||||
headers.Get(headerIfModifiedSince),
|
|
||||||
headers.Get(headerIfMatch),
|
|
||||||
headers.Get(headerIfNoneMatch),
|
|
||||||
headers.Get(headerIfUnmodifiedSince),
|
|
||||||
headers.Get(headerRange),
|
|
||||||
buildCanonicalizedHeader(headers),
|
|
||||||
canonicalizedResource,
|
|
||||||
}, "\n")
|
|
||||||
case SharedKeyForTable:
|
|
||||||
canString = strings.Join([]string{
|
|
||||||
verb,
|
|
||||||
headers.Get(headerContentMD5),
|
|
||||||
headers.Get(headerContentType),
|
|
||||||
date,
|
|
||||||
canonicalizedResource,
|
|
||||||
}, "\n")
|
|
||||||
case SharedKeyLite:
|
|
||||||
canString = strings.Join([]string{
|
|
||||||
verb,
|
|
||||||
headers.Get(headerContentMD5),
|
|
||||||
headers.Get(headerContentType),
|
|
||||||
date,
|
|
||||||
buildCanonicalizedHeader(headers),
|
|
||||||
canonicalizedResource,
|
|
||||||
}, "\n")
|
|
||||||
case SharedKeyLiteForTable:
|
|
||||||
canString = strings.Join([]string{
|
|
||||||
date,
|
|
||||||
canonicalizedResource,
|
|
||||||
}, "\n")
|
|
||||||
default:
|
|
||||||
return "", fmt.Errorf("key type '%s' is not supported", keyType)
|
|
||||||
}
|
|
||||||
return canString, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildCanonicalizedHeader(headers http.Header) string {
|
|
||||||
cm := make(map[string]string)
|
|
||||||
|
|
||||||
for k := range headers {
|
|
||||||
headerName := strings.TrimSpace(strings.ToLower(k))
|
|
||||||
if strings.HasPrefix(headerName, "x-ms-") {
|
|
||||||
cm[headerName] = headers.Get(k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cm) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
keys := []string{}
|
|
||||||
for key := range cm {
|
|
||||||
keys = append(keys, key)
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Strings(keys)
|
|
||||||
|
|
||||||
ch := bytes.NewBufferString("")
|
|
||||||
|
|
||||||
for _, key := range keys {
|
|
||||||
ch.WriteString(key)
|
|
||||||
ch.WriteRune(':')
|
|
||||||
ch.WriteString(cm[key])
|
|
||||||
ch.WriteRune('\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.TrimSuffix(string(ch.Bytes()), "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func createAuthorizationHeader(accountName string, accountKey []byte, canonicalizedString string, keyType SharedKeyType) string {
|
|
||||||
h := hmac.New(sha256.New, accountKey)
|
|
||||||
h.Write([]byte(canonicalizedString))
|
|
||||||
signature := base64.StdEncoding.EncodeToString(h.Sum(nil))
|
|
||||||
var key string
|
|
||||||
switch keyType {
|
|
||||||
case SharedKey, SharedKeyForTable:
|
|
||||||
key = "SharedKey"
|
|
||||||
case SharedKeyLite, SharedKeyLiteForTable:
|
|
||||||
key = "SharedKeyLite"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s %s:%s", key, getCanonicalizedAccountName(accountName), signature)
|
|
||||||
}
|
|
||||||
150
vendor/github.com/Azure/go-autorest/autorest/autorest.go
generated
vendored
150
vendor/github.com/Azure/go-autorest/autorest/autorest.go
generated
vendored
@@ -1,150 +0,0 @@
|
|||||||
/*
|
|
||||||
Package autorest implements an HTTP request pipeline suitable for use across multiple go-routines
|
|
||||||
and provides the shared routines relied on by AutoRest (see https://github.com/Azure/autorest/)
|
|
||||||
generated Go code.
|
|
||||||
|
|
||||||
The package breaks sending and responding to HTTP requests into three phases: Preparing, Sending,
|
|
||||||
and Responding. A typical pattern is:
|
|
||||||
|
|
||||||
req, err := Prepare(&http.Request{},
|
|
||||||
token.WithAuthorization())
|
|
||||||
|
|
||||||
resp, err := Send(req,
|
|
||||||
WithLogging(logger),
|
|
||||||
DoErrorIfStatusCode(http.StatusInternalServerError),
|
|
||||||
DoCloseIfError(),
|
|
||||||
DoRetryForAttempts(5, time.Second))
|
|
||||||
|
|
||||||
err = Respond(resp,
|
|
||||||
ByDiscardingBody(),
|
|
||||||
ByClosing())
|
|
||||||
|
|
||||||
Each phase relies on decorators to modify and / or manage processing. Decorators may first modify
|
|
||||||
and then pass the data along, pass the data first and then modify the result, or wrap themselves
|
|
||||||
around passing the data (such as a logger might do). Decorators run in the order provided. For
|
|
||||||
example, the following:
|
|
||||||
|
|
||||||
req, err := Prepare(&http.Request{},
|
|
||||||
WithBaseURL("https://microsoft.com/"),
|
|
||||||
WithPath("a"),
|
|
||||||
WithPath("b"),
|
|
||||||
WithPath("c"))
|
|
||||||
|
|
||||||
will set the URL to:
|
|
||||||
|
|
||||||
https://microsoft.com/a/b/c
|
|
||||||
|
|
||||||
Preparers and Responders may be shared and re-used (assuming the underlying decorators support
|
|
||||||
sharing and re-use). Performant use is obtained by creating one or more Preparers and Responders
|
|
||||||
shared among multiple go-routines, and a single Sender shared among multiple sending go-routines,
|
|
||||||
all bound together by means of input / output channels.
|
|
||||||
|
|
||||||
Decorators hold their passed state within a closure (such as the path components in the example
|
|
||||||
above). Be careful to share Preparers and Responders only in a context where such held state
|
|
||||||
applies. For example, it may not make sense to share a Preparer that applies a query string from a
|
|
||||||
fixed set of values. Similarly, sharing a Responder that reads the response body into a passed
|
|
||||||
struct (e.g., ByUnmarshallingJson) is likely incorrect.
|
|
||||||
|
|
||||||
Lastly, the Swagger specification (https://swagger.io) that drives AutoRest
|
|
||||||
(https://github.com/Azure/autorest/) precisely defines two date forms: date and date-time. The
|
|
||||||
github.com/Azure/go-autorest/autorest/date package provides time.Time derivations to ensure
|
|
||||||
correct parsing and formatting.
|
|
||||||
|
|
||||||
Errors raised by autorest objects and methods will conform to the autorest.Error interface.
|
|
||||||
|
|
||||||
See the included examples for more detail. For details on the suggested use of this package by
|
|
||||||
generated clients, see the Client described below.
|
|
||||||
*/
|
|
||||||
package autorest
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// HeaderLocation specifies the HTTP Location header.
|
|
||||||
HeaderLocation = "Location"
|
|
||||||
|
|
||||||
// HeaderRetryAfter specifies the HTTP Retry-After header.
|
|
||||||
HeaderRetryAfter = "Retry-After"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ResponseHasStatusCode returns true if the status code in the HTTP Response is in the passed set
|
|
||||||
// and false otherwise.
|
|
||||||
func ResponseHasStatusCode(resp *http.Response, codes ...int) bool {
|
|
||||||
if resp == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return containsInt(codes, resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLocation retrieves the URL from the Location header of the passed response.
|
|
||||||
func GetLocation(resp *http.Response) string {
|
|
||||||
return resp.Header.Get(HeaderLocation)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRetryAfter extracts the retry delay from the Retry-After header of the passed response. If
|
|
||||||
// the header is absent or is malformed, it will return the supplied default delay time.Duration.
|
|
||||||
func GetRetryAfter(resp *http.Response, defaultDelay time.Duration) time.Duration {
|
|
||||||
retry := resp.Header.Get(HeaderRetryAfter)
|
|
||||||
if retry == "" {
|
|
||||||
return defaultDelay
|
|
||||||
}
|
|
||||||
|
|
||||||
d, err := time.ParseDuration(retry + "s")
|
|
||||||
if err != nil {
|
|
||||||
return defaultDelay
|
|
||||||
}
|
|
||||||
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPollingRequest allocates and returns a new http.Request to poll for the passed response.
|
|
||||||
func NewPollingRequest(resp *http.Response, cancel <-chan struct{}) (*http.Request, error) {
|
|
||||||
location := GetLocation(resp)
|
|
||||||
if location == "" {
|
|
||||||
return nil, NewErrorWithResponse("autorest", "NewPollingRequest", resp, "Location header missing from response that requires polling")
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := Prepare(&http.Request{Cancel: cancel},
|
|
||||||
AsGet(),
|
|
||||||
WithBaseURL(location))
|
|
||||||
if err != nil {
|
|
||||||
return nil, NewErrorWithError(err, "autorest", "NewPollingRequest", nil, "Failure creating poll request to %s", location)
|
|
||||||
}
|
|
||||||
|
|
||||||
return req, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPollingRequestWithContext allocates and returns a new http.Request with the specified context to poll for the passed response.
|
|
||||||
func NewPollingRequestWithContext(ctx context.Context, resp *http.Response) (*http.Request, error) {
|
|
||||||
location := GetLocation(resp)
|
|
||||||
if location == "" {
|
|
||||||
return nil, NewErrorWithResponse("autorest", "NewPollingRequestWithContext", resp, "Location header missing from response that requires polling")
|
|
||||||
}
|
|
||||||
|
|
||||||
req, err := Prepare((&http.Request{}).WithContext(ctx),
|
|
||||||
AsGet(),
|
|
||||||
WithBaseURL(location))
|
|
||||||
if err != nil {
|
|
||||||
return nil, NewErrorWithError(err, "autorest", "NewPollingRequestWithContext", nil, "Failure creating poll request to %s", location)
|
|
||||||
}
|
|
||||||
|
|
||||||
return req, nil
|
|
||||||
}
|
|
||||||
991
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
991
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
@@ -1,991 +0,0 @@
|
|||||||
package azure
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Azure/go-autorest/autorest"
|
|
||||||
"github.com/Azure/go-autorest/tracing"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
headerAsyncOperation = "Azure-AsyncOperation"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
operationInProgress string = "InProgress"
|
|
||||||
operationCanceled string = "Canceled"
|
|
||||||
operationFailed string = "Failed"
|
|
||||||
operationSucceeded string = "Succeeded"
|
|
||||||
)
|
|
||||||
|
|
||||||
var pollingCodes = [...]int{http.StatusNoContent, http.StatusAccepted, http.StatusCreated, http.StatusOK}
|
|
||||||
|
|
||||||
// FutureAPI contains the set of methods on the Future type.
|
|
||||||
type FutureAPI interface {
|
|
||||||
// Response returns the last HTTP response.
|
|
||||||
Response() *http.Response
|
|
||||||
|
|
||||||
// Status returns the last status message of the operation.
|
|
||||||
Status() string
|
|
||||||
|
|
||||||
// PollingMethod returns the method used to monitor the status of the asynchronous operation.
|
|
||||||
PollingMethod() PollingMethodType
|
|
||||||
|
|
||||||
// DoneWithContext queries the service to see if the operation has completed.
|
|
||||||
DoneWithContext(context.Context, autorest.Sender) (bool, error)
|
|
||||||
|
|
||||||
// GetPollingDelay returns a duration the application should wait before checking
|
|
||||||
// the status of the asynchronous request and true; this value is returned from
|
|
||||||
// the service via the Retry-After response header. If the header wasn't returned
|
|
||||||
// then the function returns the zero-value time.Duration and false.
|
|
||||||
GetPollingDelay() (time.Duration, bool)
|
|
||||||
|
|
||||||
// WaitForCompletionRef will return when one of the following conditions is met: the long
|
|
||||||
// running operation has completed, the provided context is cancelled, or the client's
|
|
||||||
// polling duration has been exceeded. It will retry failed polling attempts based on
|
|
||||||
// the retry value defined in the client up to the maximum retry attempts.
|
|
||||||
// If no deadline is specified in the context then the client.PollingDuration will be
|
|
||||||
// used to determine if a default deadline should be used.
|
|
||||||
// If PollingDuration is greater than zero the value will be used as the context's timeout.
|
|
||||||
// If PollingDuration is zero then no default deadline will be used.
|
|
||||||
WaitForCompletionRef(context.Context, autorest.Client) error
|
|
||||||
|
|
||||||
// MarshalJSON implements the json.Marshaler interface.
|
|
||||||
MarshalJSON() ([]byte, error)
|
|
||||||
|
|
||||||
// MarshalJSON implements the json.Unmarshaler interface.
|
|
||||||
UnmarshalJSON([]byte) error
|
|
||||||
|
|
||||||
// PollingURL returns the URL used for retrieving the status of the long-running operation.
|
|
||||||
PollingURL() string
|
|
||||||
|
|
||||||
// GetResult should be called once polling has completed successfully.
|
|
||||||
// It makes the final GET call to retrieve the resultant payload.
|
|
||||||
GetResult(autorest.Sender) (*http.Response, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ FutureAPI = (*Future)(nil)
|
|
||||||
|
|
||||||
// Future provides a mechanism to access the status and results of an asynchronous request.
|
|
||||||
// Since futures are stateful they should be passed by value to avoid race conditions.
|
|
||||||
type Future struct {
|
|
||||||
pt pollingTracker
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFutureFromResponse returns a new Future object initialized
|
|
||||||
// with the initial response from an asynchronous operation.
|
|
||||||
func NewFutureFromResponse(resp *http.Response) (Future, error) {
|
|
||||||
pt, err := createPollingTracker(resp)
|
|
||||||
return Future{pt: pt}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response returns the last HTTP response.
|
|
||||||
func (f Future) Response() *http.Response {
|
|
||||||
if f.pt == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return f.pt.latestResponse()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status returns the last status message of the operation.
|
|
||||||
func (f Future) Status() string {
|
|
||||||
if f.pt == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return f.pt.pollingStatus()
|
|
||||||
}
|
|
||||||
|
|
||||||
// PollingMethod returns the method used to monitor the status of the asynchronous operation.
|
|
||||||
func (f Future) PollingMethod() PollingMethodType {
|
|
||||||
if f.pt == nil {
|
|
||||||
return PollingUnknown
|
|
||||||
}
|
|
||||||
return f.pt.pollingMethod()
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoneWithContext queries the service to see if the operation has completed.
|
|
||||||
func (f *Future) DoneWithContext(ctx context.Context, sender autorest.Sender) (done bool, err error) {
|
|
||||||
ctx = tracing.StartSpan(ctx, "github.com/Azure/go-autorest/autorest/azure/async.DoneWithContext")
|
|
||||||
defer func() {
|
|
||||||
sc := -1
|
|
||||||
resp := f.Response()
|
|
||||||
if resp != nil {
|
|
||||||
sc = resp.StatusCode
|
|
||||||
}
|
|
||||||
tracing.EndSpan(ctx, sc, err)
|
|
||||||
}()
|
|
||||||
|
|
||||||
if f.pt == nil {
|
|
||||||
return false, autorest.NewError("Future", "Done", "future is not initialized")
|
|
||||||
}
|
|
||||||
if f.pt.hasTerminated() {
|
|
||||||
return true, f.pt.pollingError()
|
|
||||||
}
|
|
||||||
if err := f.pt.pollForStatus(ctx, sender); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if err := f.pt.checkForErrors(); err != nil {
|
|
||||||
return f.pt.hasTerminated(), err
|
|
||||||
}
|
|
||||||
if err := f.pt.updatePollingState(f.pt.provisioningStateApplicable()); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if err := f.pt.initPollingMethod(); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if err := f.pt.updatePollingMethod(); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return f.pt.hasTerminated(), f.pt.pollingError()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPollingDelay returns a duration the application should wait before checking
|
|
||||||
// the status of the asynchronous request and true; this value is returned from
|
|
||||||
// the service via the Retry-After response header. If the header wasn't returned
|
|
||||||
// then the function returns the zero-value time.Duration and false.
|
|
||||||
func (f Future) GetPollingDelay() (time.Duration, bool) {
|
|
||||||
if f.pt == nil {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
resp := f.pt.latestResponse()
|
|
||||||
if resp == nil {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
retry := resp.Header.Get(autorest.HeaderRetryAfter)
|
|
||||||
if retry == "" {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
d, err := time.ParseDuration(retry + "s")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return d, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// WaitForCompletionRef will return when one of the following conditions is met: the long
|
|
||||||
// running operation has completed, the provided context is cancelled, or the client's
|
|
||||||
// polling duration has been exceeded. It will retry failed polling attempts based on
|
|
||||||
// the retry value defined in the client up to the maximum retry attempts.
|
|
||||||
// If no deadline is specified in the context then the client.PollingDuration will be
|
|
||||||
// used to determine if a default deadline should be used.
|
|
||||||
// If PollingDuration is greater than zero the value will be used as the context's timeout.
|
|
||||||
// If PollingDuration is zero then no default deadline will be used.
|
|
||||||
func (f *Future) WaitForCompletionRef(ctx context.Context, client autorest.Client) (err error) {
|
|
||||||
ctx = tracing.StartSpan(ctx, "github.com/Azure/go-autorest/autorest/azure/async.WaitForCompletionRef")
|
|
||||||
defer func() {
|
|
||||||
sc := -1
|
|
||||||
resp := f.Response()
|
|
||||||
if resp != nil {
|
|
||||||
sc = resp.StatusCode
|
|
||||||
}
|
|
||||||
tracing.EndSpan(ctx, sc, err)
|
|
||||||
}()
|
|
||||||
cancelCtx := ctx
|
|
||||||
// if the provided context already has a deadline don't override it
|
|
||||||
_, hasDeadline := ctx.Deadline()
|
|
||||||
if d := client.PollingDuration; !hasDeadline && d != 0 {
|
|
||||||
var cancel context.CancelFunc
|
|
||||||
cancelCtx, cancel = context.WithTimeout(ctx, d)
|
|
||||||
defer cancel()
|
|
||||||
}
|
|
||||||
// if the initial response has a Retry-After, sleep for the specified amount of time before starting to poll
|
|
||||||
if delay, ok := f.GetPollingDelay(); ok {
|
|
||||||
if delayElapsed := autorest.DelayForBackoff(delay, 0, cancelCtx.Done()); !delayElapsed {
|
|
||||||
err = cancelCtx.Err()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
done, err := f.DoneWithContext(ctx, client)
|
|
||||||
for attempts := 0; !done; done, err = f.DoneWithContext(ctx, client) {
|
|
||||||
if attempts >= client.RetryAttempts {
|
|
||||||
return autorest.NewErrorWithError(err, "Future", "WaitForCompletion", f.pt.latestResponse(), "the number of retries has been exceeded")
|
|
||||||
}
|
|
||||||
// we want delayAttempt to be zero in the non-error case so
|
|
||||||
// that DelayForBackoff doesn't perform exponential back-off
|
|
||||||
var delayAttempt int
|
|
||||||
var delay time.Duration
|
|
||||||
if err == nil {
|
|
||||||
// check for Retry-After delay, if not present use the client's polling delay
|
|
||||||
var ok bool
|
|
||||||
delay, ok = f.GetPollingDelay()
|
|
||||||
if !ok {
|
|
||||||
delay = client.PollingDelay
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// there was an error polling for status so perform exponential
|
|
||||||
// back-off based on the number of attempts using the client's retry
|
|
||||||
// duration. update attempts after delayAttempt to avoid off-by-one.
|
|
||||||
delayAttempt = attempts
|
|
||||||
delay = client.RetryDuration
|
|
||||||
attempts++
|
|
||||||
}
|
|
||||||
// wait until the delay elapses or the context is cancelled
|
|
||||||
delayElapsed := autorest.DelayForBackoff(delay, delayAttempt, cancelCtx.Done())
|
|
||||||
if !delayElapsed {
|
|
||||||
return autorest.NewErrorWithError(cancelCtx.Err(), "Future", "WaitForCompletion", f.pt.latestResponse(), "context has been cancelled")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON implements the json.Marshaler interface.
|
|
||||||
func (f Future) MarshalJSON() ([]byte, error) {
|
|
||||||
return json.Marshal(f.pt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
|
||||||
func (f *Future) UnmarshalJSON(data []byte) error {
|
|
||||||
// unmarshal into JSON object to determine the tracker type
|
|
||||||
obj := map[string]interface{}{}
|
|
||||||
err := json.Unmarshal(data, &obj)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if obj["method"] == nil {
|
|
||||||
return autorest.NewError("Future", "UnmarshalJSON", "missing 'method' property")
|
|
||||||
}
|
|
||||||
method := obj["method"].(string)
|
|
||||||
switch strings.ToUpper(method) {
|
|
||||||
case http.MethodDelete:
|
|
||||||
f.pt = &pollingTrackerDelete{}
|
|
||||||
case http.MethodPatch:
|
|
||||||
f.pt = &pollingTrackerPatch{}
|
|
||||||
case http.MethodPost:
|
|
||||||
f.pt = &pollingTrackerPost{}
|
|
||||||
case http.MethodPut:
|
|
||||||
f.pt = &pollingTrackerPut{}
|
|
||||||
default:
|
|
||||||
return autorest.NewError("Future", "UnmarshalJSON", "unsupoorted method '%s'", method)
|
|
||||||
}
|
|
||||||
// now unmarshal into the tracker
|
|
||||||
return json.Unmarshal(data, &f.pt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PollingURL returns the URL used for retrieving the status of the long-running operation.
|
|
||||||
func (f Future) PollingURL() string {
|
|
||||||
if f.pt == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return f.pt.pollingURL()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetResult should be called once polling has completed successfully.
|
|
||||||
// It makes the final GET call to retrieve the resultant payload.
|
|
||||||
func (f Future) GetResult(sender autorest.Sender) (*http.Response, error) {
|
|
||||||
if f.pt.finalGetURL() == "" {
|
|
||||||
// we can end up in this situation if the async operation returns a 200
|
|
||||||
// with no polling URLs. in that case return the response which should
|
|
||||||
// contain the JSON payload (only do this for successful terminal cases).
|
|
||||||
if lr := f.pt.latestResponse(); lr != nil && f.pt.hasSucceeded() {
|
|
||||||
return lr, nil
|
|
||||||
}
|
|
||||||
return nil, autorest.NewError("Future", "GetResult", "missing URL for retrieving result")
|
|
||||||
}
|
|
||||||
req, err := http.NewRequest(http.MethodGet, f.pt.finalGetURL(), nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
resp, err := sender.Do(req)
|
|
||||||
if err == nil && resp.Body != nil {
|
|
||||||
// copy the body and close it so callers don't have to
|
|
||||||
defer resp.Body.Close()
|
|
||||||
b, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
resp.Body = ioutil.NopCloser(bytes.NewReader(b))
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
type pollingTracker interface {
|
|
||||||
// these methods can differ per tracker
|
|
||||||
|
|
||||||
// checks the response headers and status code to determine the polling mechanism
|
|
||||||
updatePollingMethod() error
|
|
||||||
|
|
||||||
// checks the response for tracker-specific error conditions
|
|
||||||
checkForErrors() error
|
|
||||||
|
|
||||||
// returns true if provisioning state should be checked
|
|
||||||
provisioningStateApplicable() bool
|
|
||||||
|
|
||||||
// methods common to all trackers
|
|
||||||
|
|
||||||
// initializes a tracker's polling URL and method, called for each iteration.
|
|
||||||
// these values can be overridden by each polling tracker as required.
|
|
||||||
initPollingMethod() error
|
|
||||||
|
|
||||||
// initializes the tracker's internal state, call this when the tracker is created
|
|
||||||
initializeState() error
|
|
||||||
|
|
||||||
// makes an HTTP request to check the status of the LRO
|
|
||||||
pollForStatus(ctx context.Context, sender autorest.Sender) error
|
|
||||||
|
|
||||||
// updates internal tracker state, call this after each call to pollForStatus
|
|
||||||
updatePollingState(provStateApl bool) error
|
|
||||||
|
|
||||||
// returns the error response from the service, can be nil
|
|
||||||
pollingError() error
|
|
||||||
|
|
||||||
// returns the polling method being used
|
|
||||||
pollingMethod() PollingMethodType
|
|
||||||
|
|
||||||
// returns the state of the LRO as returned from the service
|
|
||||||
pollingStatus() string
|
|
||||||
|
|
||||||
// returns the URL used for polling status
|
|
||||||
pollingURL() string
|
|
||||||
|
|
||||||
// returns the URL used for the final GET to retrieve the resource
|
|
||||||
finalGetURL() string
|
|
||||||
|
|
||||||
// returns true if the LRO is in a terminal state
|
|
||||||
hasTerminated() bool
|
|
||||||
|
|
||||||
// returns true if the LRO is in a failed terminal state
|
|
||||||
hasFailed() bool
|
|
||||||
|
|
||||||
// returns true if the LRO is in a successful terminal state
|
|
||||||
hasSucceeded() bool
|
|
||||||
|
|
||||||
// returns the cached HTTP response after a call to pollForStatus(), can be nil
|
|
||||||
latestResponse() *http.Response
|
|
||||||
}
|
|
||||||
|
|
||||||
type pollingTrackerBase struct {
|
|
||||||
// resp is the last response, either from the submission of the LRO or from polling
|
|
||||||
resp *http.Response
|
|
||||||
|
|
||||||
// method is the HTTP verb, this is needed for deserialization
|
|
||||||
Method string `json:"method"`
|
|
||||||
|
|
||||||
// rawBody is the raw JSON response body
|
|
||||||
rawBody map[string]interface{}
|
|
||||||
|
|
||||||
// denotes if polling is using async-operation or location header
|
|
||||||
Pm PollingMethodType `json:"pollingMethod"`
|
|
||||||
|
|
||||||
// the URL to poll for status
|
|
||||||
URI string `json:"pollingURI"`
|
|
||||||
|
|
||||||
// the state of the LRO as returned from the service
|
|
||||||
State string `json:"lroState"`
|
|
||||||
|
|
||||||
// the URL to GET for the final result
|
|
||||||
FinalGetURI string `json:"resultURI"`
|
|
||||||
|
|
||||||
// used to hold an error object returned from the service
|
|
||||||
Err *ServiceError `json:"error,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt *pollingTrackerBase) initializeState() error {
|
|
||||||
// determine the initial polling state based on response body and/or HTTP status
|
|
||||||
// code. this is applicable to the initial LRO response, not polling responses!
|
|
||||||
pt.Method = pt.resp.Request.Method
|
|
||||||
if err := pt.updateRawBody(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
switch pt.resp.StatusCode {
|
|
||||||
case http.StatusOK:
|
|
||||||
if ps := pt.getProvisioningState(); ps != nil {
|
|
||||||
pt.State = *ps
|
|
||||||
if pt.hasFailed() {
|
|
||||||
pt.updateErrorFromResponse()
|
|
||||||
return pt.pollingError()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pt.State = operationSucceeded
|
|
||||||
}
|
|
||||||
case http.StatusCreated:
|
|
||||||
if ps := pt.getProvisioningState(); ps != nil {
|
|
||||||
pt.State = *ps
|
|
||||||
} else {
|
|
||||||
pt.State = operationInProgress
|
|
||||||
}
|
|
||||||
case http.StatusAccepted:
|
|
||||||
pt.State = operationInProgress
|
|
||||||
case http.StatusNoContent:
|
|
||||||
pt.State = operationSucceeded
|
|
||||||
default:
|
|
||||||
pt.State = operationFailed
|
|
||||||
pt.updateErrorFromResponse()
|
|
||||||
return pt.pollingError()
|
|
||||||
}
|
|
||||||
return pt.initPollingMethod()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerBase) getProvisioningState() *string {
|
|
||||||
if pt.rawBody != nil && pt.rawBody["properties"] != nil {
|
|
||||||
p := pt.rawBody["properties"].(map[string]interface{})
|
|
||||||
if ps := p["provisioningState"]; ps != nil {
|
|
||||||
s := ps.(string)
|
|
||||||
return &s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt *pollingTrackerBase) updateRawBody() error {
|
|
||||||
pt.rawBody = map[string]interface{}{}
|
|
||||||
if pt.resp.ContentLength != 0 {
|
|
||||||
defer pt.resp.Body.Close()
|
|
||||||
b, err := ioutil.ReadAll(pt.resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to read response body")
|
|
||||||
}
|
|
||||||
// put the body back so it's available to other callers
|
|
||||||
pt.resp.Body = ioutil.NopCloser(bytes.NewReader(b))
|
|
||||||
// observed in 204 responses over HTTP/2.0; the content length is -1 but body is empty
|
|
||||||
if len(b) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if err = json.Unmarshal(b, &pt.rawBody); err != nil {
|
|
||||||
return autorest.NewErrorWithError(err, "pollingTrackerBase", "updateRawBody", nil, "failed to unmarshal response body")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt *pollingTrackerBase) pollForStatus(ctx context.Context, sender autorest.Sender) error {
|
|
||||||
req, err := http.NewRequest(http.MethodGet, pt.URI, nil)
|
|
||||||
if err != nil {
|
|
||||||
return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed to create HTTP request")
|
|
||||||
}
|
|
||||||
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
preparer := autorest.CreatePreparer(autorest.GetPrepareDecorators(ctx)...)
|
|
||||||
req, err = preparer.Prepare(req)
|
|
||||||
if err != nil {
|
|
||||||
return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed preparing HTTP request")
|
|
||||||
}
|
|
||||||
pt.resp, err = sender.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return autorest.NewErrorWithError(err, "pollingTrackerBase", "pollForStatus", nil, "failed to send HTTP request")
|
|
||||||
}
|
|
||||||
if autorest.ResponseHasStatusCode(pt.resp, pollingCodes[:]...) {
|
|
||||||
// reset the service error on success case
|
|
||||||
pt.Err = nil
|
|
||||||
err = pt.updateRawBody()
|
|
||||||
} else {
|
|
||||||
// check response body for error content
|
|
||||||
pt.updateErrorFromResponse()
|
|
||||||
err = pt.pollingError()
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// attempts to unmarshal a ServiceError type from the response body.
|
|
||||||
// if that fails then make a best attempt at creating something meaningful.
|
|
||||||
// NOTE: this assumes that the async operation has failed.
|
|
||||||
func (pt *pollingTrackerBase) updateErrorFromResponse() {
|
|
||||||
var err error
|
|
||||||
if pt.resp.ContentLength != 0 {
|
|
||||||
type respErr struct {
|
|
||||||
ServiceError *ServiceError `json:"error"`
|
|
||||||
}
|
|
||||||
re := respErr{}
|
|
||||||
defer pt.resp.Body.Close()
|
|
||||||
var b []byte
|
|
||||||
if b, err = ioutil.ReadAll(pt.resp.Body); err != nil {
|
|
||||||
goto Default
|
|
||||||
}
|
|
||||||
// put the body back so it's available to other callers
|
|
||||||
pt.resp.Body = ioutil.NopCloser(bytes.NewReader(b))
|
|
||||||
if len(b) == 0 {
|
|
||||||
goto Default
|
|
||||||
}
|
|
||||||
if err = json.Unmarshal(b, &re); err != nil {
|
|
||||||
goto Default
|
|
||||||
}
|
|
||||||
// unmarshalling the error didn't yield anything, try unwrapped error
|
|
||||||
if re.ServiceError == nil {
|
|
||||||
err = json.Unmarshal(b, &re.ServiceError)
|
|
||||||
if err != nil {
|
|
||||||
goto Default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// the unmarshaller will ensure re.ServiceError is non-nil
|
|
||||||
// even if there was no content unmarshalled so check the code.
|
|
||||||
if re.ServiceError.Code != "" {
|
|
||||||
pt.Err = re.ServiceError
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Default:
|
|
||||||
se := &ServiceError{
|
|
||||||
Code: pt.pollingStatus(),
|
|
||||||
Message: "The async operation failed.",
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
se.InnerError = make(map[string]interface{})
|
|
||||||
se.InnerError["unmarshalError"] = err.Error()
|
|
||||||
}
|
|
||||||
// stick the response body into the error object in hopes
|
|
||||||
// it contains something useful to help diagnose the failure.
|
|
||||||
if len(pt.rawBody) > 0 {
|
|
||||||
se.AdditionalInfo = []map[string]interface{}{
|
|
||||||
pt.rawBody,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pt.Err = se
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt *pollingTrackerBase) updatePollingState(provStateApl bool) error {
|
|
||||||
if pt.Pm == PollingAsyncOperation && pt.rawBody["status"] != nil {
|
|
||||||
pt.State = pt.rawBody["status"].(string)
|
|
||||||
} else {
|
|
||||||
if pt.resp.StatusCode == http.StatusAccepted {
|
|
||||||
pt.State = operationInProgress
|
|
||||||
} else if provStateApl {
|
|
||||||
if ps := pt.getProvisioningState(); ps != nil {
|
|
||||||
pt.State = *ps
|
|
||||||
} else {
|
|
||||||
pt.State = operationSucceeded
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return autorest.NewError("pollingTrackerBase", "updatePollingState", "the response from the async operation has an invalid status code")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if the operation has failed update the error state
|
|
||||||
if pt.hasFailed() {
|
|
||||||
pt.updateErrorFromResponse()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerBase) pollingError() error {
|
|
||||||
if pt.Err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return pt.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerBase) pollingMethod() PollingMethodType {
|
|
||||||
return pt.Pm
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerBase) pollingStatus() string {
|
|
||||||
return pt.State
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerBase) pollingURL() string {
|
|
||||||
return pt.URI
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerBase) finalGetURL() string {
|
|
||||||
return pt.FinalGetURI
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerBase) hasTerminated() bool {
|
|
||||||
return strings.EqualFold(pt.State, operationCanceled) || strings.EqualFold(pt.State, operationFailed) || strings.EqualFold(pt.State, operationSucceeded)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerBase) hasFailed() bool {
|
|
||||||
return strings.EqualFold(pt.State, operationCanceled) || strings.EqualFold(pt.State, operationFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerBase) hasSucceeded() bool {
|
|
||||||
return strings.EqualFold(pt.State, operationSucceeded)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerBase) latestResponse() *http.Response {
|
|
||||||
return pt.resp
|
|
||||||
}
|
|
||||||
|
|
||||||
// error checking common to all trackers
|
|
||||||
func (pt pollingTrackerBase) baseCheckForErrors() error {
|
|
||||||
// for Azure-AsyncOperations the response body cannot be nil or empty
|
|
||||||
if pt.Pm == PollingAsyncOperation {
|
|
||||||
if pt.resp.Body == nil || pt.resp.ContentLength == 0 {
|
|
||||||
return autorest.NewError("pollingTrackerBase", "baseCheckForErrors", "for Azure-AsyncOperation response body cannot be nil")
|
|
||||||
}
|
|
||||||
if pt.rawBody["status"] == nil {
|
|
||||||
return autorest.NewError("pollingTrackerBase", "baseCheckForErrors", "missing status property in Azure-AsyncOperation response body")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// default initialization of polling URL/method. each verb tracker will update this as required.
|
|
||||||
func (pt *pollingTrackerBase) initPollingMethod() error {
|
|
||||||
if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil {
|
|
||||||
return err
|
|
||||||
} else if ao != "" {
|
|
||||||
pt.URI = ao
|
|
||||||
pt.Pm = PollingAsyncOperation
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil {
|
|
||||||
return err
|
|
||||||
} else if lh != "" {
|
|
||||||
pt.URI = lh
|
|
||||||
pt.Pm = PollingLocation
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// it's ok if we didn't find a polling header, this will be handled elsewhere
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DELETE
|
|
||||||
|
|
||||||
type pollingTrackerDelete struct {
|
|
||||||
pollingTrackerBase
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt *pollingTrackerDelete) updatePollingMethod() error {
|
|
||||||
// for 201 the Location header is required
|
|
||||||
if pt.resp.StatusCode == http.StatusCreated {
|
|
||||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil {
|
|
||||||
return err
|
|
||||||
} else if lh == "" {
|
|
||||||
return autorest.NewError("pollingTrackerDelete", "updateHeaders", "missing Location header in 201 response")
|
|
||||||
} else {
|
|
||||||
pt.URI = lh
|
|
||||||
}
|
|
||||||
pt.Pm = PollingLocation
|
|
||||||
pt.FinalGetURI = pt.URI
|
|
||||||
}
|
|
||||||
// for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary
|
|
||||||
if pt.resp.StatusCode == http.StatusAccepted {
|
|
||||||
ao, err := getURLFromAsyncOpHeader(pt.resp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else if ao != "" {
|
|
||||||
pt.URI = ao
|
|
||||||
pt.Pm = PollingAsyncOperation
|
|
||||||
}
|
|
||||||
// if the Location header is invalid and we already have a polling URL
|
|
||||||
// then we don't care if the Location header URL is malformed.
|
|
||||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" {
|
|
||||||
return err
|
|
||||||
} else if lh != "" {
|
|
||||||
if ao == "" {
|
|
||||||
pt.URI = lh
|
|
||||||
pt.Pm = PollingLocation
|
|
||||||
}
|
|
||||||
// when both headers are returned we use the value in the Location header for the final GET
|
|
||||||
pt.FinalGetURI = lh
|
|
||||||
}
|
|
||||||
// make sure a polling URL was found
|
|
||||||
if pt.URI == "" {
|
|
||||||
return autorest.NewError("pollingTrackerPost", "updateHeaders", "didn't get any suitable polling URLs in 202 response")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerDelete) checkForErrors() error {
|
|
||||||
return pt.baseCheckForErrors()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerDelete) provisioningStateApplicable() bool {
|
|
||||||
return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusNoContent
|
|
||||||
}
|
|
||||||
|
|
||||||
// PATCH
|
|
||||||
|
|
||||||
type pollingTrackerPatch struct {
|
|
||||||
pollingTrackerBase
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt *pollingTrackerPatch) updatePollingMethod() error {
|
|
||||||
// by default we can use the original URL for polling and final GET
|
|
||||||
if pt.URI == "" {
|
|
||||||
pt.URI = pt.resp.Request.URL.String()
|
|
||||||
}
|
|
||||||
if pt.FinalGetURI == "" {
|
|
||||||
pt.FinalGetURI = pt.resp.Request.URL.String()
|
|
||||||
}
|
|
||||||
if pt.Pm == PollingUnknown {
|
|
||||||
pt.Pm = PollingRequestURI
|
|
||||||
}
|
|
||||||
// for 201 it's permissible for no headers to be returned
|
|
||||||
if pt.resp.StatusCode == http.StatusCreated {
|
|
||||||
if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil {
|
|
||||||
return err
|
|
||||||
} else if ao != "" {
|
|
||||||
pt.URI = ao
|
|
||||||
pt.Pm = PollingAsyncOperation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary
|
|
||||||
// note the absence of the "final GET" mechanism for PATCH
|
|
||||||
if pt.resp.StatusCode == http.StatusAccepted {
|
|
||||||
ao, err := getURLFromAsyncOpHeader(pt.resp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else if ao != "" {
|
|
||||||
pt.URI = ao
|
|
||||||
pt.Pm = PollingAsyncOperation
|
|
||||||
}
|
|
||||||
if ao == "" {
|
|
||||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil {
|
|
||||||
return err
|
|
||||||
} else if lh == "" {
|
|
||||||
return autorest.NewError("pollingTrackerPatch", "updateHeaders", "didn't get any suitable polling URLs in 202 response")
|
|
||||||
} else {
|
|
||||||
pt.URI = lh
|
|
||||||
pt.Pm = PollingLocation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerPatch) checkForErrors() error {
|
|
||||||
return pt.baseCheckForErrors()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerPatch) provisioningStateApplicable() bool {
|
|
||||||
return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusCreated
|
|
||||||
}
|
|
||||||
|
|
||||||
// POST
|
|
||||||
|
|
||||||
type pollingTrackerPost struct {
|
|
||||||
pollingTrackerBase
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt *pollingTrackerPost) updatePollingMethod() error {
|
|
||||||
// 201 requires Location header
|
|
||||||
if pt.resp.StatusCode == http.StatusCreated {
|
|
||||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil {
|
|
||||||
return err
|
|
||||||
} else if lh == "" {
|
|
||||||
return autorest.NewError("pollingTrackerPost", "updateHeaders", "missing Location header in 201 response")
|
|
||||||
} else {
|
|
||||||
pt.URI = lh
|
|
||||||
pt.FinalGetURI = lh
|
|
||||||
pt.Pm = PollingLocation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary
|
|
||||||
if pt.resp.StatusCode == http.StatusAccepted {
|
|
||||||
ao, err := getURLFromAsyncOpHeader(pt.resp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else if ao != "" {
|
|
||||||
pt.URI = ao
|
|
||||||
pt.Pm = PollingAsyncOperation
|
|
||||||
}
|
|
||||||
// if the Location header is invalid and we already have a polling URL
|
|
||||||
// then we don't care if the Location header URL is malformed.
|
|
||||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" {
|
|
||||||
return err
|
|
||||||
} else if lh != "" {
|
|
||||||
if ao == "" {
|
|
||||||
pt.URI = lh
|
|
||||||
pt.Pm = PollingLocation
|
|
||||||
}
|
|
||||||
// when both headers are returned we use the value in the Location header for the final GET
|
|
||||||
pt.FinalGetURI = lh
|
|
||||||
}
|
|
||||||
// make sure a polling URL was found
|
|
||||||
if pt.URI == "" {
|
|
||||||
return autorest.NewError("pollingTrackerPost", "updateHeaders", "didn't get any suitable polling URLs in 202 response")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerPost) checkForErrors() error {
|
|
||||||
return pt.baseCheckForErrors()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerPost) provisioningStateApplicable() bool {
|
|
||||||
return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusNoContent
|
|
||||||
}
|
|
||||||
|
|
||||||
// PUT
|
|
||||||
|
|
||||||
type pollingTrackerPut struct {
|
|
||||||
pollingTrackerBase
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt *pollingTrackerPut) updatePollingMethod() error {
|
|
||||||
// by default we can use the original URL for polling and final GET
|
|
||||||
if pt.URI == "" {
|
|
||||||
pt.URI = pt.resp.Request.URL.String()
|
|
||||||
}
|
|
||||||
if pt.FinalGetURI == "" {
|
|
||||||
pt.FinalGetURI = pt.resp.Request.URL.String()
|
|
||||||
}
|
|
||||||
if pt.Pm == PollingUnknown {
|
|
||||||
pt.Pm = PollingRequestURI
|
|
||||||
}
|
|
||||||
// for 201 it's permissible for no headers to be returned
|
|
||||||
if pt.resp.StatusCode == http.StatusCreated {
|
|
||||||
if ao, err := getURLFromAsyncOpHeader(pt.resp); err != nil {
|
|
||||||
return err
|
|
||||||
} else if ao != "" {
|
|
||||||
pt.URI = ao
|
|
||||||
pt.Pm = PollingAsyncOperation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// for 202 prefer the Azure-AsyncOperation header but fall back to Location if necessary
|
|
||||||
if pt.resp.StatusCode == http.StatusAccepted {
|
|
||||||
ao, err := getURLFromAsyncOpHeader(pt.resp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else if ao != "" {
|
|
||||||
pt.URI = ao
|
|
||||||
pt.Pm = PollingAsyncOperation
|
|
||||||
}
|
|
||||||
// if the Location header is invalid and we already have a polling URL
|
|
||||||
// then we don't care if the Location header URL is malformed.
|
|
||||||
if lh, err := getURLFromLocationHeader(pt.resp); err != nil && pt.URI == "" {
|
|
||||||
return err
|
|
||||||
} else if lh != "" {
|
|
||||||
if ao == "" {
|
|
||||||
pt.URI = lh
|
|
||||||
pt.Pm = PollingLocation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// make sure a polling URL was found
|
|
||||||
if pt.URI == "" {
|
|
||||||
return autorest.NewError("pollingTrackerPut", "updateHeaders", "didn't get any suitable polling URLs in 202 response")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerPut) checkForErrors() error {
|
|
||||||
err := pt.baseCheckForErrors()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// if there are no LRO headers then the body cannot be empty
|
|
||||||
ao, err := getURLFromAsyncOpHeader(pt.resp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
lh, err := getURLFromLocationHeader(pt.resp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if ao == "" && lh == "" && len(pt.rawBody) == 0 {
|
|
||||||
return autorest.NewError("pollingTrackerPut", "checkForErrors", "the response did not contain a body")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pt pollingTrackerPut) provisioningStateApplicable() bool {
|
|
||||||
return pt.resp.StatusCode == http.StatusOK || pt.resp.StatusCode == http.StatusCreated
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates a polling tracker based on the verb of the original request
|
|
||||||
func createPollingTracker(resp *http.Response) (pollingTracker, error) {
|
|
||||||
var pt pollingTracker
|
|
||||||
switch strings.ToUpper(resp.Request.Method) {
|
|
||||||
case http.MethodDelete:
|
|
||||||
pt = &pollingTrackerDelete{pollingTrackerBase: pollingTrackerBase{resp: resp}}
|
|
||||||
case http.MethodPatch:
|
|
||||||
pt = &pollingTrackerPatch{pollingTrackerBase: pollingTrackerBase{resp: resp}}
|
|
||||||
case http.MethodPost:
|
|
||||||
pt = &pollingTrackerPost{pollingTrackerBase: pollingTrackerBase{resp: resp}}
|
|
||||||
case http.MethodPut:
|
|
||||||
pt = &pollingTrackerPut{pollingTrackerBase: pollingTrackerBase{resp: resp}}
|
|
||||||
default:
|
|
||||||
return nil, autorest.NewError("azure", "createPollingTracker", "unsupported HTTP method %s", resp.Request.Method)
|
|
||||||
}
|
|
||||||
if err := pt.initializeState(); err != nil {
|
|
||||||
return pt, err
|
|
||||||
}
|
|
||||||
// this initializes the polling header values, we do this during creation in case the
|
|
||||||
// initial response send us invalid values; this way the API call will return a non-nil
|
|
||||||
// error (not doing this means the error shows up in Future.Done)
|
|
||||||
return pt, pt.updatePollingMethod()
|
|
||||||
}
|
|
||||||
|
|
||||||
// gets the polling URL from the Azure-AsyncOperation header.
|
|
||||||
// ensures the URL is well-formed and absolute.
|
|
||||||
func getURLFromAsyncOpHeader(resp *http.Response) (string, error) {
|
|
||||||
s := resp.Header.Get(http.CanonicalHeaderKey(headerAsyncOperation))
|
|
||||||
if s == "" {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
if !isValidURL(s) {
|
|
||||||
return "", autorest.NewError("azure", "getURLFromAsyncOpHeader", "invalid polling URL '%s'", s)
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// gets the polling URL from the Location header.
|
|
||||||
// ensures the URL is well-formed and absolute.
|
|
||||||
func getURLFromLocationHeader(resp *http.Response) (string, error) {
|
|
||||||
s := resp.Header.Get(http.CanonicalHeaderKey(autorest.HeaderLocation))
|
|
||||||
if s == "" {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
if !isValidURL(s) {
|
|
||||||
return "", autorest.NewError("azure", "getURLFromLocationHeader", "invalid polling URL '%s'", s)
|
|
||||||
}
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify that the URL is valid and absolute
|
|
||||||
func isValidURL(s string) bool {
|
|
||||||
u, err := url.Parse(s)
|
|
||||||
return err == nil && u.IsAbs()
|
|
||||||
}
|
|
||||||
|
|
||||||
// PollingMethodType defines a type used for enumerating polling mechanisms.
|
|
||||||
type PollingMethodType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// PollingAsyncOperation indicates the polling method uses the Azure-AsyncOperation header.
|
|
||||||
PollingAsyncOperation PollingMethodType = "AsyncOperation"
|
|
||||||
|
|
||||||
// PollingLocation indicates the polling method uses the Location header.
|
|
||||||
PollingLocation PollingMethodType = "Location"
|
|
||||||
|
|
||||||
// PollingRequestURI indicates the polling method uses the original request URI.
|
|
||||||
PollingRequestURI PollingMethodType = "RequestURI"
|
|
||||||
|
|
||||||
// PollingUnknown indicates an unknown polling method and is the default value.
|
|
||||||
PollingUnknown PollingMethodType = ""
|
|
||||||
)
|
|
||||||
|
|
||||||
// AsyncOpIncompleteError is the type that's returned from a future that has not completed.
|
|
||||||
type AsyncOpIncompleteError struct {
|
|
||||||
// FutureType is the name of the type composed of a azure.Future.
|
|
||||||
FutureType string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns an error message including the originating type name of the error.
|
|
||||||
func (e AsyncOpIncompleteError) Error() string {
|
|
||||||
return fmt.Sprintf("%s: asynchronous operation has not completed", e.FutureType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAsyncOpIncompleteError creates a new AsyncOpIncompleteError with the specified parameters.
|
|
||||||
func NewAsyncOpIncompleteError(futureType string) AsyncOpIncompleteError {
|
|
||||||
return AsyncOpIncompleteError{
|
|
||||||
FutureType: futureType,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
388
vendor/github.com/Azure/go-autorest/autorest/azure/azure.go
generated
vendored
388
vendor/github.com/Azure/go-autorest/autorest/azure/azure.go
generated
vendored
@@ -1,388 +0,0 @@
|
|||||||
// Package azure provides Azure-specific implementations used with AutoRest.
|
|
||||||
// See the included examples for more detail.
|
|
||||||
package azure
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/Azure/go-autorest/autorest"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// HeaderClientID is the Azure extension header to set a user-specified request ID.
|
|
||||||
HeaderClientID = "x-ms-client-request-id"
|
|
||||||
|
|
||||||
// HeaderReturnClientID is the Azure extension header to set if the user-specified request ID
|
|
||||||
// should be included in the response.
|
|
||||||
HeaderReturnClientID = "x-ms-return-client-request-id"
|
|
||||||
|
|
||||||
// HeaderContentType is the type of the content in the HTTP response.
|
|
||||||
HeaderContentType = "Content-Type"
|
|
||||||
|
|
||||||
// HeaderRequestID is the Azure extension header of the service generated request ID returned
|
|
||||||
// in the response.
|
|
||||||
HeaderRequestID = "x-ms-request-id"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ServiceError encapsulates the error response from an Azure service.
|
|
||||||
// It adhears to the OData v4 specification for error responses.
|
|
||||||
type ServiceError struct {
|
|
||||||
Code string `json:"code"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
Target *string `json:"target"`
|
|
||||||
Details []map[string]interface{} `json:"details"`
|
|
||||||
InnerError map[string]interface{} `json:"innererror"`
|
|
||||||
AdditionalInfo []map[string]interface{} `json:"additionalInfo"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (se ServiceError) Error() string {
|
|
||||||
result := fmt.Sprintf("Code=%q Message=%q", se.Code, se.Message)
|
|
||||||
|
|
||||||
if se.Target != nil {
|
|
||||||
result += fmt.Sprintf(" Target=%q", *se.Target)
|
|
||||||
}
|
|
||||||
|
|
||||||
if se.Details != nil {
|
|
||||||
d, err := json.Marshal(se.Details)
|
|
||||||
if err != nil {
|
|
||||||
result += fmt.Sprintf(" Details=%v", se.Details)
|
|
||||||
}
|
|
||||||
result += fmt.Sprintf(" Details=%v", string(d))
|
|
||||||
}
|
|
||||||
|
|
||||||
if se.InnerError != nil {
|
|
||||||
d, err := json.Marshal(se.InnerError)
|
|
||||||
if err != nil {
|
|
||||||
result += fmt.Sprintf(" InnerError=%v", se.InnerError)
|
|
||||||
}
|
|
||||||
result += fmt.Sprintf(" InnerError=%v", string(d))
|
|
||||||
}
|
|
||||||
|
|
||||||
if se.AdditionalInfo != nil {
|
|
||||||
d, err := json.Marshal(se.AdditionalInfo)
|
|
||||||
if err != nil {
|
|
||||||
result += fmt.Sprintf(" AdditionalInfo=%v", se.AdditionalInfo)
|
|
||||||
}
|
|
||||||
result += fmt.Sprintf(" AdditionalInfo=%v", string(d))
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON implements the json.Unmarshaler interface for the ServiceError type.
|
|
||||||
func (se *ServiceError) UnmarshalJSON(b []byte) error {
|
|
||||||
// http://docs.oasis-open.org/odata/odata-json-format/v4.0/os/odata-json-format-v4.0-os.html#_Toc372793091
|
|
||||||
|
|
||||||
type serviceErrorInternal struct {
|
|
||||||
Code string `json:"code"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
Target *string `json:"target,omitempty"`
|
|
||||||
AdditionalInfo []map[string]interface{} `json:"additionalInfo,omitempty"`
|
|
||||||
// not all services conform to the OData v4 spec.
|
|
||||||
// the following fields are where we've seen discrepancies
|
|
||||||
|
|
||||||
// spec calls for []map[string]interface{} but have seen map[string]interface{}
|
|
||||||
Details interface{} `json:"details,omitempty"`
|
|
||||||
|
|
||||||
// spec calls for map[string]interface{} but have seen []map[string]interface{} and string
|
|
||||||
InnerError interface{} `json:"innererror,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
sei := serviceErrorInternal{}
|
|
||||||
if err := json.Unmarshal(b, &sei); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy the fields we know to be correct
|
|
||||||
se.AdditionalInfo = sei.AdditionalInfo
|
|
||||||
se.Code = sei.Code
|
|
||||||
se.Message = sei.Message
|
|
||||||
se.Target = sei.Target
|
|
||||||
|
|
||||||
// converts an []interface{} to []map[string]interface{}
|
|
||||||
arrayOfObjs := func(v interface{}) ([]map[string]interface{}, bool) {
|
|
||||||
arrayOf, ok := v.([]interface{})
|
|
||||||
if !ok {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
final := []map[string]interface{}{}
|
|
||||||
for _, item := range arrayOf {
|
|
||||||
as, ok := item.(map[string]interface{})
|
|
||||||
if !ok {
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
final = append(final, as)
|
|
||||||
}
|
|
||||||
return final, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert the remaining fields, falling back to raw JSON if necessary
|
|
||||||
|
|
||||||
if c, ok := arrayOfObjs(sei.Details); ok {
|
|
||||||
se.Details = c
|
|
||||||
} else if c, ok := sei.Details.(map[string]interface{}); ok {
|
|
||||||
se.Details = []map[string]interface{}{c}
|
|
||||||
} else if sei.Details != nil {
|
|
||||||
// stuff into Details
|
|
||||||
se.Details = []map[string]interface{}{
|
|
||||||
{"raw": sei.Details},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if c, ok := sei.InnerError.(map[string]interface{}); ok {
|
|
||||||
se.InnerError = c
|
|
||||||
} else if c, ok := arrayOfObjs(sei.InnerError); ok {
|
|
||||||
// if there's only one error extract it
|
|
||||||
if len(c) == 1 {
|
|
||||||
se.InnerError = c[0]
|
|
||||||
} else {
|
|
||||||
// multiple errors, stuff them into the value
|
|
||||||
se.InnerError = map[string]interface{}{
|
|
||||||
"multi": c,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if c, ok := sei.InnerError.(string); ok {
|
|
||||||
se.InnerError = map[string]interface{}{"error": c}
|
|
||||||
} else if sei.InnerError != nil {
|
|
||||||
// stuff into InnerError
|
|
||||||
se.InnerError = map[string]interface{}{
|
|
||||||
"raw": sei.InnerError,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestError describes an error response returned by Azure service.
|
|
||||||
type RequestError struct {
|
|
||||||
autorest.DetailedError
|
|
||||||
|
|
||||||
// The error returned by the Azure service.
|
|
||||||
ServiceError *ServiceError `json:"error" xml:"Error"`
|
|
||||||
|
|
||||||
// The request id (from the x-ms-request-id-header) of the request.
|
|
||||||
RequestID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns a human-friendly error message from service error.
|
|
||||||
func (e RequestError) Error() string {
|
|
||||||
return fmt.Sprintf("autorest/azure: Service returned an error. Status=%v %v",
|
|
||||||
e.StatusCode, e.ServiceError)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsAzureError returns true if the passed error is an Azure Service error; false otherwise.
|
|
||||||
func IsAzureError(e error) bool {
|
|
||||||
_, ok := e.(*RequestError)
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resource contains details about an Azure resource.
|
|
||||||
type Resource struct {
|
|
||||||
SubscriptionID string
|
|
||||||
ResourceGroup string
|
|
||||||
Provider string
|
|
||||||
ResourceType string
|
|
||||||
ResourceName string
|
|
||||||
}
|
|
||||||
|
|
||||||
// String function returns a string in form of azureResourceID
|
|
||||||
func (r Resource) String() string {
|
|
||||||
return fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/%s/%s/%s", r.SubscriptionID, r.ResourceGroup, r.Provider, r.ResourceType, r.ResourceName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseResourceID parses a resource ID into a ResourceDetails struct.
|
|
||||||
// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-functions-resource#return-value-4.
|
|
||||||
func ParseResourceID(resourceID string) (Resource, error) {
|
|
||||||
|
|
||||||
const resourceIDPatternText = `(?i)subscriptions/(.+)/resourceGroups/(.+)/providers/(.+?)/(.+?)/(.+)`
|
|
||||||
resourceIDPattern := regexp.MustCompile(resourceIDPatternText)
|
|
||||||
match := resourceIDPattern.FindStringSubmatch(resourceID)
|
|
||||||
|
|
||||||
if len(match) == 0 {
|
|
||||||
return Resource{}, fmt.Errorf("parsing failed for %s. Invalid resource Id format", resourceID)
|
|
||||||
}
|
|
||||||
|
|
||||||
v := strings.Split(match[5], "/")
|
|
||||||
resourceName := v[len(v)-1]
|
|
||||||
|
|
||||||
result := Resource{
|
|
||||||
SubscriptionID: match[1],
|
|
||||||
ResourceGroup: match[2],
|
|
||||||
Provider: match[3],
|
|
||||||
ResourceType: match[4],
|
|
||||||
ResourceName: resourceName,
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewErrorWithError creates a new Error conforming object from the
|
|
||||||
// passed packageType, method, statusCode of the given resp (UndefinedStatusCode
|
|
||||||
// if resp is nil), message, and original error. message is treated as a format
|
|
||||||
// string to which the optional args apply.
|
|
||||||
func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) RequestError {
|
|
||||||
if v, ok := original.(*RequestError); ok {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
|
|
||||||
statusCode := autorest.UndefinedStatusCode
|
|
||||||
if resp != nil {
|
|
||||||
statusCode = resp.StatusCode
|
|
||||||
}
|
|
||||||
return RequestError{
|
|
||||||
DetailedError: autorest.DetailedError{
|
|
||||||
Original: original,
|
|
||||||
PackageType: packageType,
|
|
||||||
Method: method,
|
|
||||||
StatusCode: statusCode,
|
|
||||||
Message: fmt.Sprintf(message, args...),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithReturningClientID returns a PrepareDecorator that adds an HTTP extension header of
|
|
||||||
// x-ms-client-request-id whose value is the passed, undecorated UUID (e.g.,
|
|
||||||
// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA"). It also sets the x-ms-return-client-request-id
|
|
||||||
// header to true such that UUID accompanies the http.Response.
|
|
||||||
func WithReturningClientID(uuid string) autorest.PrepareDecorator {
|
|
||||||
preparer := autorest.CreatePreparer(
|
|
||||||
WithClientID(uuid),
|
|
||||||
WithReturnClientID(true))
|
|
||||||
|
|
||||||
return func(p autorest.Preparer) autorest.Preparer {
|
|
||||||
return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
return preparer.Prepare(r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithClientID returns a PrepareDecorator that adds an HTTP extension header of
|
|
||||||
// x-ms-client-request-id whose value is passed, undecorated UUID (e.g.,
|
|
||||||
// "0F39878C-5F76-4DB8-A25D-61D2C193C3CA").
|
|
||||||
func WithClientID(uuid string) autorest.PrepareDecorator {
|
|
||||||
return autorest.WithHeader(HeaderClientID, uuid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithReturnClientID returns a PrepareDecorator that adds an HTTP extension header of
|
|
||||||
// x-ms-return-client-request-id whose boolean value indicates if the value of the
|
|
||||||
// x-ms-client-request-id header should be included in the http.Response.
|
|
||||||
func WithReturnClientID(b bool) autorest.PrepareDecorator {
|
|
||||||
return autorest.WithHeader(HeaderReturnClientID, strconv.FormatBool(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExtractClientID extracts the client identifier from the x-ms-client-request-id header set on the
|
|
||||||
// http.Request sent to the service (and returned in the http.Response)
|
|
||||||
func ExtractClientID(resp *http.Response) string {
|
|
||||||
return autorest.ExtractHeaderValue(HeaderClientID, resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExtractRequestID extracts the Azure server generated request identifier from the
|
|
||||||
// x-ms-request-id header.
|
|
||||||
func ExtractRequestID(resp *http.Response) string {
|
|
||||||
return autorest.ExtractHeaderValue(HeaderRequestID, resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithErrorUnlessStatusCode returns a RespondDecorator that emits an
|
|
||||||
// azure.RequestError by reading the response body unless the response HTTP status code
|
|
||||||
// is among the set passed.
|
|
||||||
//
|
|
||||||
// If there is a chance service may return responses other than the Azure error
|
|
||||||
// format and the response cannot be parsed into an error, a decoding error will
|
|
||||||
// be returned containing the response body. In any case, the Responder will
|
|
||||||
// return an error if the status code is not satisfied.
|
|
||||||
//
|
|
||||||
// If this Responder returns an error, the response body will be replaced with
|
|
||||||
// an in-memory reader, which needs no further closing.
|
|
||||||
func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator {
|
|
||||||
return func(r autorest.Responder) autorest.Responder {
|
|
||||||
return autorest.ResponderFunc(func(resp *http.Response) error {
|
|
||||||
err := r.Respond(resp)
|
|
||||||
if err == nil && !autorest.ResponseHasStatusCode(resp, codes...) {
|
|
||||||
var e RequestError
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
encodedAs := autorest.EncodedAsJSON
|
|
||||||
if strings.Contains(resp.Header.Get("Content-Type"), "xml") {
|
|
||||||
encodedAs = autorest.EncodedAsXML
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy and replace the Body in case it does not contain an error object.
|
|
||||||
// This will leave the Body available to the caller.
|
|
||||||
b, decodeErr := autorest.CopyAndDecode(encodedAs, resp.Body, &e)
|
|
||||||
resp.Body = ioutil.NopCloser(&b)
|
|
||||||
if decodeErr != nil {
|
|
||||||
return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr)
|
|
||||||
}
|
|
||||||
if e.ServiceError == nil {
|
|
||||||
// Check if error is unwrapped ServiceError
|
|
||||||
decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes()))
|
|
||||||
if err := decoder.Decode(&e.ServiceError); err != nil {
|
|
||||||
return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// for example, should the API return the literal value `null` as the response
|
|
||||||
if e.ServiceError == nil {
|
|
||||||
e.ServiceError = &ServiceError{
|
|
||||||
Code: "Unknown",
|
|
||||||
Message: "Unknown service error",
|
|
||||||
Details: []map[string]interface{}{
|
|
||||||
{
|
|
||||||
"HttpResponse.Body": b.String(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if e.ServiceError != nil && e.ServiceError.Message == "" {
|
|
||||||
// if we're here it means the returned error wasn't OData v4 compliant.
|
|
||||||
// try to unmarshal the body in hopes of getting something.
|
|
||||||
rawBody := map[string]interface{}{}
|
|
||||||
decoder := autorest.NewDecoder(encodedAs, bytes.NewReader(b.Bytes()))
|
|
||||||
if err := decoder.Decode(&rawBody); err != nil {
|
|
||||||
return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
e.ServiceError = &ServiceError{
|
|
||||||
Code: "Unknown",
|
|
||||||
Message: "Unknown service error",
|
|
||||||
}
|
|
||||||
if len(rawBody) > 0 {
|
|
||||||
e.ServiceError.Details = []map[string]interface{}{rawBody}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
e.Response = resp
|
|
||||||
e.RequestID = ExtractRequestID(resp)
|
|
||||||
if e.StatusCode == nil {
|
|
||||||
e.StatusCode = resp.StatusCode
|
|
||||||
}
|
|
||||||
err = &e
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
269
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
269
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
@@ -1,269 +0,0 @@
|
|||||||
package azure
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// EnvironmentFilepathName captures the name of the environment variable containing the path to the file
|
|
||||||
// to be used while populating the Azure Environment.
|
|
||||||
EnvironmentFilepathName = "AZURE_ENVIRONMENT_FILEPATH"
|
|
||||||
|
|
||||||
// NotAvailable is used for endpoints and resource IDs that are not available for a given cloud.
|
|
||||||
NotAvailable = "N/A"
|
|
||||||
)
|
|
||||||
|
|
||||||
var environments = map[string]Environment{
|
|
||||||
"AZURECHINACLOUD": ChinaCloud,
|
|
||||||
"AZUREGERMANCLOUD": GermanCloud,
|
|
||||||
"AZUREPUBLICCLOUD": PublicCloud,
|
|
||||||
"AZUREUSGOVERNMENTCLOUD": USGovernmentCloud,
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResourceIdentifier contains a set of Azure resource IDs.
|
|
||||||
type ResourceIdentifier struct {
|
|
||||||
Graph string `json:"graph"`
|
|
||||||
KeyVault string `json:"keyVault"`
|
|
||||||
Datalake string `json:"datalake"`
|
|
||||||
Batch string `json:"batch"`
|
|
||||||
OperationalInsights string `json:"operationalInsights"`
|
|
||||||
Storage string `json:"storage"`
|
|
||||||
Synapse string `json:"synapse"`
|
|
||||||
ServiceBus string `json:"serviceBus"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Environment represents a set of endpoints for each of Azure's Clouds.
|
|
||||||
type Environment struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
ManagementPortalURL string `json:"managementPortalURL"`
|
|
||||||
PublishSettingsURL string `json:"publishSettingsURL"`
|
|
||||||
ServiceManagementEndpoint string `json:"serviceManagementEndpoint"`
|
|
||||||
ResourceManagerEndpoint string `json:"resourceManagerEndpoint"`
|
|
||||||
ActiveDirectoryEndpoint string `json:"activeDirectoryEndpoint"`
|
|
||||||
GalleryEndpoint string `json:"galleryEndpoint"`
|
|
||||||
KeyVaultEndpoint string `json:"keyVaultEndpoint"`
|
|
||||||
GraphEndpoint string `json:"graphEndpoint"`
|
|
||||||
ServiceBusEndpoint string `json:"serviceBusEndpoint"`
|
|
||||||
BatchManagementEndpoint string `json:"batchManagementEndpoint"`
|
|
||||||
StorageEndpointSuffix string `json:"storageEndpointSuffix"`
|
|
||||||
SQLDatabaseDNSSuffix string `json:"sqlDatabaseDNSSuffix"`
|
|
||||||
TrafficManagerDNSSuffix string `json:"trafficManagerDNSSuffix"`
|
|
||||||
KeyVaultDNSSuffix string `json:"keyVaultDNSSuffix"`
|
|
||||||
ServiceBusEndpointSuffix string `json:"serviceBusEndpointSuffix"`
|
|
||||||
ServiceManagementVMDNSSuffix string `json:"serviceManagementVMDNSSuffix"`
|
|
||||||
ResourceManagerVMDNSSuffix string `json:"resourceManagerVMDNSSuffix"`
|
|
||||||
ContainerRegistryDNSSuffix string `json:"containerRegistryDNSSuffix"`
|
|
||||||
CosmosDBDNSSuffix string `json:"cosmosDBDNSSuffix"`
|
|
||||||
TokenAudience string `json:"tokenAudience"`
|
|
||||||
APIManagementHostNameSuffix string `json:"apiManagementHostNameSuffix"`
|
|
||||||
SynapseEndpointSuffix string `json:"synapseEndpointSuffix"`
|
|
||||||
ResourceIdentifiers ResourceIdentifier `json:"resourceIdentifiers"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
// PublicCloud is the default public Azure cloud environment
|
|
||||||
PublicCloud = Environment{
|
|
||||||
Name: "AzurePublicCloud",
|
|
||||||
ManagementPortalURL: "https://manage.windowsazure.com/",
|
|
||||||
PublishSettingsURL: "https://manage.windowsazure.com/publishsettings/index",
|
|
||||||
ServiceManagementEndpoint: "https://management.core.windows.net/",
|
|
||||||
ResourceManagerEndpoint: "https://management.azure.com/",
|
|
||||||
ActiveDirectoryEndpoint: "https://login.microsoftonline.com/",
|
|
||||||
GalleryEndpoint: "https://gallery.azure.com/",
|
|
||||||
KeyVaultEndpoint: "https://vault.azure.net/",
|
|
||||||
GraphEndpoint: "https://graph.windows.net/",
|
|
||||||
ServiceBusEndpoint: "https://servicebus.windows.net/",
|
|
||||||
BatchManagementEndpoint: "https://batch.core.windows.net/",
|
|
||||||
StorageEndpointSuffix: "core.windows.net",
|
|
||||||
SQLDatabaseDNSSuffix: "database.windows.net",
|
|
||||||
TrafficManagerDNSSuffix: "trafficmanager.net",
|
|
||||||
KeyVaultDNSSuffix: "vault.azure.net",
|
|
||||||
ServiceBusEndpointSuffix: "servicebus.windows.net",
|
|
||||||
ServiceManagementVMDNSSuffix: "cloudapp.net",
|
|
||||||
ResourceManagerVMDNSSuffix: "cloudapp.azure.com",
|
|
||||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
|
||||||
CosmosDBDNSSuffix: "documents.azure.com",
|
|
||||||
TokenAudience: "https://management.azure.com/",
|
|
||||||
APIManagementHostNameSuffix: "azure-api.net",
|
|
||||||
SynapseEndpointSuffix: "dev.azuresynapse.net",
|
|
||||||
ResourceIdentifiers: ResourceIdentifier{
|
|
||||||
Graph: "https://graph.windows.net/",
|
|
||||||
KeyVault: "https://vault.azure.net",
|
|
||||||
Datalake: "https://datalake.azure.net/",
|
|
||||||
Batch: "https://batch.core.windows.net/",
|
|
||||||
OperationalInsights: "https://api.loganalytics.io",
|
|
||||||
Storage: "https://storage.azure.com/",
|
|
||||||
Synapse: "https://dev.azuresynapse.net",
|
|
||||||
ServiceBus: "https://servicebus.azure.net/",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// USGovernmentCloud is the cloud environment for the US Government
|
|
||||||
USGovernmentCloud = Environment{
|
|
||||||
Name: "AzureUSGovernmentCloud",
|
|
||||||
ManagementPortalURL: "https://manage.windowsazure.us/",
|
|
||||||
PublishSettingsURL: "https://manage.windowsazure.us/publishsettings/index",
|
|
||||||
ServiceManagementEndpoint: "https://management.core.usgovcloudapi.net/",
|
|
||||||
ResourceManagerEndpoint: "https://management.usgovcloudapi.net/",
|
|
||||||
ActiveDirectoryEndpoint: "https://login.microsoftonline.us/",
|
|
||||||
GalleryEndpoint: "https://gallery.usgovcloudapi.net/",
|
|
||||||
KeyVaultEndpoint: "https://vault.usgovcloudapi.net/",
|
|
||||||
GraphEndpoint: "https://graph.windows.net/",
|
|
||||||
ServiceBusEndpoint: "https://servicebus.usgovcloudapi.net/",
|
|
||||||
BatchManagementEndpoint: "https://batch.core.usgovcloudapi.net/",
|
|
||||||
StorageEndpointSuffix: "core.usgovcloudapi.net",
|
|
||||||
SQLDatabaseDNSSuffix: "database.usgovcloudapi.net",
|
|
||||||
TrafficManagerDNSSuffix: "usgovtrafficmanager.net",
|
|
||||||
KeyVaultDNSSuffix: "vault.usgovcloudapi.net",
|
|
||||||
ServiceBusEndpointSuffix: "servicebus.usgovcloudapi.net",
|
|
||||||
ServiceManagementVMDNSSuffix: "usgovcloudapp.net",
|
|
||||||
ResourceManagerVMDNSSuffix: "cloudapp.usgovcloudapi.net",
|
|
||||||
ContainerRegistryDNSSuffix: "azurecr.us",
|
|
||||||
CosmosDBDNSSuffix: "documents.azure.us",
|
|
||||||
TokenAudience: "https://management.usgovcloudapi.net/",
|
|
||||||
APIManagementHostNameSuffix: "azure-api.us",
|
|
||||||
SynapseEndpointSuffix: NotAvailable,
|
|
||||||
ResourceIdentifiers: ResourceIdentifier{
|
|
||||||
Graph: "https://graph.windows.net/",
|
|
||||||
KeyVault: "https://vault.usgovcloudapi.net",
|
|
||||||
Datalake: NotAvailable,
|
|
||||||
Batch: "https://batch.core.usgovcloudapi.net/",
|
|
||||||
OperationalInsights: "https://api.loganalytics.us",
|
|
||||||
Storage: "https://storage.azure.com/",
|
|
||||||
Synapse: NotAvailable,
|
|
||||||
ServiceBus: "https://servicebus.azure.net/",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChinaCloud is the cloud environment operated in China
|
|
||||||
ChinaCloud = Environment{
|
|
||||||
Name: "AzureChinaCloud",
|
|
||||||
ManagementPortalURL: "https://manage.chinacloudapi.com/",
|
|
||||||
PublishSettingsURL: "https://manage.chinacloudapi.com/publishsettings/index",
|
|
||||||
ServiceManagementEndpoint: "https://management.core.chinacloudapi.cn/",
|
|
||||||
ResourceManagerEndpoint: "https://management.chinacloudapi.cn/",
|
|
||||||
ActiveDirectoryEndpoint: "https://login.chinacloudapi.cn/",
|
|
||||||
GalleryEndpoint: "https://gallery.chinacloudapi.cn/",
|
|
||||||
KeyVaultEndpoint: "https://vault.azure.cn/",
|
|
||||||
GraphEndpoint: "https://graph.chinacloudapi.cn/",
|
|
||||||
ServiceBusEndpoint: "https://servicebus.chinacloudapi.cn/",
|
|
||||||
BatchManagementEndpoint: "https://batch.chinacloudapi.cn/",
|
|
||||||
StorageEndpointSuffix: "core.chinacloudapi.cn",
|
|
||||||
SQLDatabaseDNSSuffix: "database.chinacloudapi.cn",
|
|
||||||
TrafficManagerDNSSuffix: "trafficmanager.cn",
|
|
||||||
KeyVaultDNSSuffix: "vault.azure.cn",
|
|
||||||
ServiceBusEndpointSuffix: "servicebus.chinacloudapi.cn",
|
|
||||||
ServiceManagementVMDNSSuffix: "chinacloudapp.cn",
|
|
||||||
ResourceManagerVMDNSSuffix: "cloudapp.chinacloudapi.cn",
|
|
||||||
ContainerRegistryDNSSuffix: "azurecr.cn",
|
|
||||||
CosmosDBDNSSuffix: "documents.azure.cn",
|
|
||||||
TokenAudience: "https://management.chinacloudapi.cn/",
|
|
||||||
APIManagementHostNameSuffix: "azure-api.cn",
|
|
||||||
SynapseEndpointSuffix: "dev.azuresynapse.azure.cn",
|
|
||||||
ResourceIdentifiers: ResourceIdentifier{
|
|
||||||
Graph: "https://graph.chinacloudapi.cn/",
|
|
||||||
KeyVault: "https://vault.azure.cn",
|
|
||||||
Datalake: NotAvailable,
|
|
||||||
Batch: "https://batch.chinacloudapi.cn/",
|
|
||||||
OperationalInsights: NotAvailable,
|
|
||||||
Storage: "https://storage.azure.com/",
|
|
||||||
Synapse: "https://dev.azuresynapse.net",
|
|
||||||
ServiceBus: "https://servicebus.azure.net/",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// GermanCloud is the cloud environment operated in Germany
|
|
||||||
GermanCloud = Environment{
|
|
||||||
Name: "AzureGermanCloud",
|
|
||||||
ManagementPortalURL: "http://portal.microsoftazure.de/",
|
|
||||||
PublishSettingsURL: "https://manage.microsoftazure.de/publishsettings/index",
|
|
||||||
ServiceManagementEndpoint: "https://management.core.cloudapi.de/",
|
|
||||||
ResourceManagerEndpoint: "https://management.microsoftazure.de/",
|
|
||||||
ActiveDirectoryEndpoint: "https://login.microsoftonline.de/",
|
|
||||||
GalleryEndpoint: "https://gallery.cloudapi.de/",
|
|
||||||
KeyVaultEndpoint: "https://vault.microsoftazure.de/",
|
|
||||||
GraphEndpoint: "https://graph.cloudapi.de/",
|
|
||||||
ServiceBusEndpoint: "https://servicebus.cloudapi.de/",
|
|
||||||
BatchManagementEndpoint: "https://batch.cloudapi.de/",
|
|
||||||
StorageEndpointSuffix: "core.cloudapi.de",
|
|
||||||
SQLDatabaseDNSSuffix: "database.cloudapi.de",
|
|
||||||
TrafficManagerDNSSuffix: "azuretrafficmanager.de",
|
|
||||||
KeyVaultDNSSuffix: "vault.microsoftazure.de",
|
|
||||||
ServiceBusEndpointSuffix: "servicebus.cloudapi.de",
|
|
||||||
ServiceManagementVMDNSSuffix: "azurecloudapp.de",
|
|
||||||
ResourceManagerVMDNSSuffix: "cloudapp.microsoftazure.de",
|
|
||||||
ContainerRegistryDNSSuffix: NotAvailable,
|
|
||||||
CosmosDBDNSSuffix: "documents.microsoftazure.de",
|
|
||||||
TokenAudience: "https://management.microsoftazure.de/",
|
|
||||||
APIManagementHostNameSuffix: NotAvailable,
|
|
||||||
SynapseEndpointSuffix: NotAvailable,
|
|
||||||
ResourceIdentifiers: ResourceIdentifier{
|
|
||||||
Graph: "https://graph.cloudapi.de/",
|
|
||||||
KeyVault: "https://vault.microsoftazure.de",
|
|
||||||
Datalake: NotAvailable,
|
|
||||||
Batch: "https://batch.cloudapi.de/",
|
|
||||||
OperationalInsights: NotAvailable,
|
|
||||||
Storage: "https://storage.azure.com/",
|
|
||||||
Synapse: NotAvailable,
|
|
||||||
ServiceBus: "https://servicebus.azure.net/",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// EnvironmentFromName returns an Environment based on the common name specified.
|
|
||||||
func EnvironmentFromName(name string) (Environment, error) {
|
|
||||||
// IMPORTANT
|
|
||||||
// As per @radhikagupta5:
|
|
||||||
// This is technical debt, fundamentally here because Kubernetes is not currently accepting
|
|
||||||
// contributions to the providers. Once that is an option, the provider should be updated to
|
|
||||||
// directly call `EnvironmentFromFile`. Until then, we rely on dispatching Azure Stack environment creation
|
|
||||||
// from this method based on the name that is provided to us.
|
|
||||||
if strings.EqualFold(name, "AZURESTACKCLOUD") {
|
|
||||||
return EnvironmentFromFile(os.Getenv(EnvironmentFilepathName))
|
|
||||||
}
|
|
||||||
|
|
||||||
name = strings.ToUpper(name)
|
|
||||||
env, ok := environments[name]
|
|
||||||
if !ok {
|
|
||||||
return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
return env, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnvironmentFromFile loads an Environment from a configuration file available on disk.
|
|
||||||
// This function is particularly useful in the Hybrid Cloud model, where one must define their own
|
|
||||||
// endpoints.
|
|
||||||
func EnvironmentFromFile(location string) (unmarshaled Environment, err error) {
|
|
||||||
fileContents, err := ioutil.ReadFile(location)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal(fileContents, &unmarshaled)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetEnvironment updates the environment map with the specified values.
|
|
||||||
func SetEnvironment(name string, env Environment) {
|
|
||||||
environments[strings.ToUpper(name)] = env
|
|
||||||
}
|
|
||||||
245
vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go
generated
vendored
245
vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go
generated
vendored
@@ -1,245 +0,0 @@
|
|||||||
package azure
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/Azure/go-autorest/autorest"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
type audience []string
|
|
||||||
|
|
||||||
type authentication struct {
|
|
||||||
LoginEndpoint string `json:"loginEndpoint"`
|
|
||||||
Audiences audience `json:"audiences"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type environmentMetadataInfo struct {
|
|
||||||
GalleryEndpoint string `json:"galleryEndpoint"`
|
|
||||||
GraphEndpoint string `json:"graphEndpoint"`
|
|
||||||
PortalEndpoint string `json:"portalEndpoint"`
|
|
||||||
Authentication authentication `json:"authentication"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnvironmentProperty represent property names that clients can override
|
|
||||||
type EnvironmentProperty string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// EnvironmentName ...
|
|
||||||
EnvironmentName EnvironmentProperty = "name"
|
|
||||||
// EnvironmentManagementPortalURL ..
|
|
||||||
EnvironmentManagementPortalURL EnvironmentProperty = "managementPortalURL"
|
|
||||||
// EnvironmentPublishSettingsURL ...
|
|
||||||
EnvironmentPublishSettingsURL EnvironmentProperty = "publishSettingsURL"
|
|
||||||
// EnvironmentServiceManagementEndpoint ...
|
|
||||||
EnvironmentServiceManagementEndpoint EnvironmentProperty = "serviceManagementEndpoint"
|
|
||||||
// EnvironmentResourceManagerEndpoint ...
|
|
||||||
EnvironmentResourceManagerEndpoint EnvironmentProperty = "resourceManagerEndpoint"
|
|
||||||
// EnvironmentActiveDirectoryEndpoint ...
|
|
||||||
EnvironmentActiveDirectoryEndpoint EnvironmentProperty = "activeDirectoryEndpoint"
|
|
||||||
// EnvironmentGalleryEndpoint ...
|
|
||||||
EnvironmentGalleryEndpoint EnvironmentProperty = "galleryEndpoint"
|
|
||||||
// EnvironmentKeyVaultEndpoint ...
|
|
||||||
EnvironmentKeyVaultEndpoint EnvironmentProperty = "keyVaultEndpoint"
|
|
||||||
// EnvironmentGraphEndpoint ...
|
|
||||||
EnvironmentGraphEndpoint EnvironmentProperty = "graphEndpoint"
|
|
||||||
// EnvironmentServiceBusEndpoint ...
|
|
||||||
EnvironmentServiceBusEndpoint EnvironmentProperty = "serviceBusEndpoint"
|
|
||||||
// EnvironmentBatchManagementEndpoint ...
|
|
||||||
EnvironmentBatchManagementEndpoint EnvironmentProperty = "batchManagementEndpoint"
|
|
||||||
// EnvironmentStorageEndpointSuffix ...
|
|
||||||
EnvironmentStorageEndpointSuffix EnvironmentProperty = "storageEndpointSuffix"
|
|
||||||
// EnvironmentSQLDatabaseDNSSuffix ...
|
|
||||||
EnvironmentSQLDatabaseDNSSuffix EnvironmentProperty = "sqlDatabaseDNSSuffix"
|
|
||||||
// EnvironmentTrafficManagerDNSSuffix ...
|
|
||||||
EnvironmentTrafficManagerDNSSuffix EnvironmentProperty = "trafficManagerDNSSuffix"
|
|
||||||
// EnvironmentKeyVaultDNSSuffix ...
|
|
||||||
EnvironmentKeyVaultDNSSuffix EnvironmentProperty = "keyVaultDNSSuffix"
|
|
||||||
// EnvironmentServiceBusEndpointSuffix ...
|
|
||||||
EnvironmentServiceBusEndpointSuffix EnvironmentProperty = "serviceBusEndpointSuffix"
|
|
||||||
// EnvironmentServiceManagementVMDNSSuffix ...
|
|
||||||
EnvironmentServiceManagementVMDNSSuffix EnvironmentProperty = "serviceManagementVMDNSSuffix"
|
|
||||||
// EnvironmentResourceManagerVMDNSSuffix ...
|
|
||||||
EnvironmentResourceManagerVMDNSSuffix EnvironmentProperty = "resourceManagerVMDNSSuffix"
|
|
||||||
// EnvironmentContainerRegistryDNSSuffix ...
|
|
||||||
EnvironmentContainerRegistryDNSSuffix EnvironmentProperty = "containerRegistryDNSSuffix"
|
|
||||||
// EnvironmentTokenAudience ...
|
|
||||||
EnvironmentTokenAudience EnvironmentProperty = "tokenAudience"
|
|
||||||
)
|
|
||||||
|
|
||||||
// OverrideProperty represents property name and value that clients can override
|
|
||||||
type OverrideProperty struct {
|
|
||||||
Key EnvironmentProperty
|
|
||||||
Value string
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnvironmentFromURL loads an Environment from a URL
|
|
||||||
// This function is particularly useful in the Hybrid Cloud model, where one may define their own
|
|
||||||
// endpoints.
|
|
||||||
func EnvironmentFromURL(resourceManagerEndpoint string, properties ...OverrideProperty) (environment Environment, err error) {
|
|
||||||
var metadataEnvProperties environmentMetadataInfo
|
|
||||||
|
|
||||||
if resourceManagerEndpoint == "" {
|
|
||||||
return environment, fmt.Errorf("Metadata resource manager endpoint is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
if metadataEnvProperties, err = retrieveMetadataEnvironment(resourceManagerEndpoint); err != nil {
|
|
||||||
return environment, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Give priority to user's override values
|
|
||||||
overrideProperties(&environment, properties)
|
|
||||||
|
|
||||||
if environment.Name == "" {
|
|
||||||
environment.Name = "HybridEnvironment"
|
|
||||||
}
|
|
||||||
stampDNSSuffix := environment.StorageEndpointSuffix
|
|
||||||
if stampDNSSuffix == "" {
|
|
||||||
stampDNSSuffix = strings.TrimSuffix(strings.TrimPrefix(strings.Replace(resourceManagerEndpoint, strings.Split(resourceManagerEndpoint, ".")[0], "", 1), "."), "/")
|
|
||||||
environment.StorageEndpointSuffix = stampDNSSuffix
|
|
||||||
}
|
|
||||||
if environment.KeyVaultDNSSuffix == "" {
|
|
||||||
environment.KeyVaultDNSSuffix = fmt.Sprintf("%s.%s", "vault", stampDNSSuffix)
|
|
||||||
}
|
|
||||||
if environment.KeyVaultEndpoint == "" {
|
|
||||||
environment.KeyVaultEndpoint = fmt.Sprintf("%s%s", "https://", environment.KeyVaultDNSSuffix)
|
|
||||||
}
|
|
||||||
if environment.TokenAudience == "" {
|
|
||||||
environment.TokenAudience = metadataEnvProperties.Authentication.Audiences[0]
|
|
||||||
}
|
|
||||||
if environment.ActiveDirectoryEndpoint == "" {
|
|
||||||
environment.ActiveDirectoryEndpoint = metadataEnvProperties.Authentication.LoginEndpoint
|
|
||||||
}
|
|
||||||
if environment.ResourceManagerEndpoint == "" {
|
|
||||||
environment.ResourceManagerEndpoint = resourceManagerEndpoint
|
|
||||||
}
|
|
||||||
if environment.GalleryEndpoint == "" {
|
|
||||||
environment.GalleryEndpoint = metadataEnvProperties.GalleryEndpoint
|
|
||||||
}
|
|
||||||
if environment.GraphEndpoint == "" {
|
|
||||||
environment.GraphEndpoint = metadataEnvProperties.GraphEndpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
return environment, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func overrideProperties(environment *Environment, properties []OverrideProperty) {
|
|
||||||
for _, property := range properties {
|
|
||||||
switch property.Key {
|
|
||||||
case EnvironmentName:
|
|
||||||
{
|
|
||||||
environment.Name = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentManagementPortalURL:
|
|
||||||
{
|
|
||||||
environment.ManagementPortalURL = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentPublishSettingsURL:
|
|
||||||
{
|
|
||||||
environment.PublishSettingsURL = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentServiceManagementEndpoint:
|
|
||||||
{
|
|
||||||
environment.ServiceManagementEndpoint = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentResourceManagerEndpoint:
|
|
||||||
{
|
|
||||||
environment.ResourceManagerEndpoint = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentActiveDirectoryEndpoint:
|
|
||||||
{
|
|
||||||
environment.ActiveDirectoryEndpoint = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentGalleryEndpoint:
|
|
||||||
{
|
|
||||||
environment.GalleryEndpoint = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentKeyVaultEndpoint:
|
|
||||||
{
|
|
||||||
environment.KeyVaultEndpoint = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentGraphEndpoint:
|
|
||||||
{
|
|
||||||
environment.GraphEndpoint = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentServiceBusEndpoint:
|
|
||||||
{
|
|
||||||
environment.ServiceBusEndpoint = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentBatchManagementEndpoint:
|
|
||||||
{
|
|
||||||
environment.BatchManagementEndpoint = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentStorageEndpointSuffix:
|
|
||||||
{
|
|
||||||
environment.StorageEndpointSuffix = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentSQLDatabaseDNSSuffix:
|
|
||||||
{
|
|
||||||
environment.SQLDatabaseDNSSuffix = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentTrafficManagerDNSSuffix:
|
|
||||||
{
|
|
||||||
environment.TrafficManagerDNSSuffix = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentKeyVaultDNSSuffix:
|
|
||||||
{
|
|
||||||
environment.KeyVaultDNSSuffix = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentServiceBusEndpointSuffix:
|
|
||||||
{
|
|
||||||
environment.ServiceBusEndpointSuffix = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentServiceManagementVMDNSSuffix:
|
|
||||||
{
|
|
||||||
environment.ServiceManagementVMDNSSuffix = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentResourceManagerVMDNSSuffix:
|
|
||||||
{
|
|
||||||
environment.ResourceManagerVMDNSSuffix = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentContainerRegistryDNSSuffix:
|
|
||||||
{
|
|
||||||
environment.ContainerRegistryDNSSuffix = property.Value
|
|
||||||
}
|
|
||||||
case EnvironmentTokenAudience:
|
|
||||||
{
|
|
||||||
environment.TokenAudience = property.Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func retrieveMetadataEnvironment(endpoint string) (environment environmentMetadataInfo, err error) {
|
|
||||||
client := autorest.NewClientWithUserAgent("")
|
|
||||||
managementEndpoint := fmt.Sprintf("%s%s", strings.TrimSuffix(endpoint, "/"), "/metadata/endpoints?api-version=1.0")
|
|
||||||
req, _ := http.NewRequest("GET", managementEndpoint, nil)
|
|
||||||
response, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return environment, err
|
|
||||||
}
|
|
||||||
defer response.Body.Close()
|
|
||||||
jsonResponse, err := ioutil.ReadAll(response.Body)
|
|
||||||
if err != nil {
|
|
||||||
return environment, err
|
|
||||||
}
|
|
||||||
err = json.Unmarshal(jsonResponse, &environment)
|
|
||||||
return environment, err
|
|
||||||
}
|
|
||||||
204
vendor/github.com/Azure/go-autorest/autorest/azure/rp.go
generated
vendored
204
vendor/github.com/Azure/go-autorest/autorest/azure/rp.go
generated
vendored
@@ -1,204 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
package azure
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Azure/go-autorest/autorest"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DoRetryWithRegistration tries to register the resource provider in case it is unregistered.
|
|
||||||
// It also handles request retries
|
|
||||||
func DoRetryWithRegistration(client autorest.Client) autorest.SendDecorator {
|
|
||||||
return func(s autorest.Sender) autorest.Sender {
|
|
||||||
return autorest.SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
|
||||||
rr := autorest.NewRetriableRequest(r)
|
|
||||||
for currentAttempt := 0; currentAttempt < client.RetryAttempts; currentAttempt++ {
|
|
||||||
err = rr.Prepare()
|
|
||||||
if err != nil {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err = autorest.SendWithSender(s, rr.Request(),
|
|
||||||
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusConflict || client.SkipResourceProviderRegistration {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var re RequestError
|
|
||||||
if strings.Contains(r.Header.Get("Content-Type"), "xml") {
|
|
||||||
// XML errors (e.g. Storage Data Plane) only return the inner object
|
|
||||||
err = autorest.Respond(resp, autorest.ByUnmarshallingXML(&re.ServiceError))
|
|
||||||
} else {
|
|
||||||
err = autorest.Respond(resp, autorest.ByUnmarshallingJSON(&re))
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
err = re
|
|
||||||
|
|
||||||
if re.ServiceError != nil && re.ServiceError.Code == "MissingSubscriptionRegistration" {
|
|
||||||
regErr := register(client, r, re)
|
|
||||||
if regErr != nil {
|
|
||||||
return resp, fmt.Errorf("failed auto registering Resource Provider: %s. Original error: %s", regErr, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getProvider(re RequestError) (string, error) {
|
|
||||||
if re.ServiceError != nil && len(re.ServiceError.Details) > 0 {
|
|
||||||
return re.ServiceError.Details[0]["target"].(string), nil
|
|
||||||
}
|
|
||||||
return "", errors.New("provider was not found in the response")
|
|
||||||
}
|
|
||||||
|
|
||||||
func register(client autorest.Client, originalReq *http.Request, re RequestError) error {
|
|
||||||
subID := getSubscription(originalReq.URL.Path)
|
|
||||||
if subID == "" {
|
|
||||||
return errors.New("missing parameter subscriptionID to register resource provider")
|
|
||||||
}
|
|
||||||
providerName, err := getProvider(re)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("missing parameter provider to register resource provider: %s", err)
|
|
||||||
}
|
|
||||||
newURL := url.URL{
|
|
||||||
Scheme: originalReq.URL.Scheme,
|
|
||||||
Host: originalReq.URL.Host,
|
|
||||||
}
|
|
||||||
|
|
||||||
// taken from the resources SDK
|
|
||||||
// with almost identical code, this sections are easier to mantain
|
|
||||||
// It is also not a good idea to import the SDK here
|
|
||||||
// https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L252
|
|
||||||
pathParameters := map[string]interface{}{
|
|
||||||
"resourceProviderNamespace": autorest.Encode("path", providerName),
|
|
||||||
"subscriptionId": autorest.Encode("path", subID),
|
|
||||||
}
|
|
||||||
|
|
||||||
const APIVersion = "2016-09-01"
|
|
||||||
queryParameters := map[string]interface{}{
|
|
||||||
"api-version": APIVersion,
|
|
||||||
}
|
|
||||||
|
|
||||||
preparer := autorest.CreatePreparer(
|
|
||||||
autorest.AsPost(),
|
|
||||||
autorest.WithBaseURL(newURL.String()),
|
|
||||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register", pathParameters),
|
|
||||||
autorest.WithQueryParameters(queryParameters),
|
|
||||||
)
|
|
||||||
|
|
||||||
req, err := preparer.Prepare(&http.Request{})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
req = req.WithContext(originalReq.Context())
|
|
||||||
|
|
||||||
resp, err := autorest.SendWithSender(client, req,
|
|
||||||
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type Provider struct {
|
|
||||||
RegistrationState *string `json:"registrationState,omitempty"`
|
|
||||||
}
|
|
||||||
var provider Provider
|
|
||||||
|
|
||||||
err = autorest.Respond(
|
|
||||||
resp,
|
|
||||||
WithErrorUnlessStatusCode(http.StatusOK),
|
|
||||||
autorest.ByUnmarshallingJSON(&provider),
|
|
||||||
autorest.ByClosing(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// poll for registered provisioning state
|
|
||||||
registrationStartTime := time.Now()
|
|
||||||
for err == nil && (client.PollingDuration == 0 || (client.PollingDuration != 0 && time.Since(registrationStartTime) < client.PollingDuration)) {
|
|
||||||
// taken from the resources SDK
|
|
||||||
// https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L45
|
|
||||||
preparer := autorest.CreatePreparer(
|
|
||||||
autorest.AsGet(),
|
|
||||||
autorest.WithBaseURL(newURL.String()),
|
|
||||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}", pathParameters),
|
|
||||||
autorest.WithQueryParameters(queryParameters),
|
|
||||||
)
|
|
||||||
req, err = preparer.Prepare(&http.Request{})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
req = req.WithContext(originalReq.Context())
|
|
||||||
|
|
||||||
resp, err := autorest.SendWithSender(client, req,
|
|
||||||
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = autorest.Respond(
|
|
||||||
resp,
|
|
||||||
WithErrorUnlessStatusCode(http.StatusOK),
|
|
||||||
autorest.ByUnmarshallingJSON(&provider),
|
|
||||||
autorest.ByClosing(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if provider.RegistrationState != nil &&
|
|
||||||
*provider.RegistrationState == "Registered" {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
delayed := autorest.DelayWithRetryAfter(resp, originalReq.Context().Done())
|
|
||||||
if !delayed && !autorest.DelayForBackoff(client.PollingDelay, 0, originalReq.Context().Done()) {
|
|
||||||
return originalReq.Context().Err()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if client.PollingDuration != 0 && !(time.Since(registrationStartTime) < client.PollingDuration) {
|
|
||||||
return errors.New("polling for resource provider registration has exceeded the polling duration")
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSubscription(path string) string {
|
|
||||||
parts := strings.Split(path, "/")
|
|
||||||
for i, v := range parts {
|
|
||||||
if v == "subscriptions" && (i+1) < len(parts) {
|
|
||||||
return parts[i+1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
328
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
328
vendor/github.com/Azure/go-autorest/autorest/client.go
generated
vendored
@@ -1,328 +0,0 @@
|
|||||||
package autorest
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"bytes"
|
|
||||||
"crypto/tls"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Azure/go-autorest/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DefaultPollingDelay is a reasonable delay between polling requests.
|
|
||||||
DefaultPollingDelay = 60 * time.Second
|
|
||||||
|
|
||||||
// DefaultPollingDuration is a reasonable total polling duration.
|
|
||||||
DefaultPollingDuration = 15 * time.Minute
|
|
||||||
|
|
||||||
// DefaultRetryAttempts is number of attempts for retry status codes (5xx).
|
|
||||||
DefaultRetryAttempts = 3
|
|
||||||
|
|
||||||
// DefaultRetryDuration is the duration to wait between retries.
|
|
||||||
DefaultRetryDuration = 30 * time.Second
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// StatusCodesForRetry are a defined group of status code for which the client will retry
|
|
||||||
StatusCodesForRetry = []int{
|
|
||||||
http.StatusRequestTimeout, // 408
|
|
||||||
http.StatusTooManyRequests, // 429
|
|
||||||
http.StatusInternalServerError, // 500
|
|
||||||
http.StatusBadGateway, // 502
|
|
||||||
http.StatusServiceUnavailable, // 503
|
|
||||||
http.StatusGatewayTimeout, // 504
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
requestFormat = `HTTP Request Begin ===================================================
|
|
||||||
%s
|
|
||||||
===================================================== HTTP Request End
|
|
||||||
`
|
|
||||||
responseFormat = `HTTP Response Begin ===================================================
|
|
||||||
%s
|
|
||||||
===================================================== HTTP Response End
|
|
||||||
`
|
|
||||||
)
|
|
||||||
|
|
||||||
// Response serves as the base for all responses from generated clients. It provides access to the
|
|
||||||
// last http.Response.
|
|
||||||
type Response struct {
|
|
||||||
*http.Response `json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsHTTPStatus returns true if the returned HTTP status code matches the provided status code.
|
|
||||||
// If there was no response (i.e. the underlying http.Response is nil) the return value is false.
|
|
||||||
func (r Response) IsHTTPStatus(statusCode int) bool {
|
|
||||||
if r.Response == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return r.Response.StatusCode == statusCode
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasHTTPStatus returns true if the returned HTTP status code matches one of the provided status codes.
|
|
||||||
// If there was no response (i.e. the underlying http.Response is nil) or not status codes are provided
|
|
||||||
// the return value is false.
|
|
||||||
func (r Response) HasHTTPStatus(statusCodes ...int) bool {
|
|
||||||
return ResponseHasStatusCode(r.Response, statusCodes...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoggingInspector implements request and response inspectors that log the full request and
|
|
||||||
// response to a supplied log.
|
|
||||||
type LoggingInspector struct {
|
|
||||||
Logger *log.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithInspection returns a PrepareDecorator that emits the http.Request to the supplied logger. The
|
|
||||||
// body is restored after being emitted.
|
|
||||||
//
|
|
||||||
// Note: Since it reads the entire Body, this decorator should not be used where body streaming is
|
|
||||||
// important. It is best used to trace JSON or similar body values.
|
|
||||||
func (li LoggingInspector) WithInspection() PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
var body, b bytes.Buffer
|
|
||||||
|
|
||||||
defer r.Body.Close()
|
|
||||||
|
|
||||||
r.Body = ioutil.NopCloser(io.TeeReader(r.Body, &body))
|
|
||||||
if err := r.Write(&b); err != nil {
|
|
||||||
return nil, fmt.Errorf("Failed to write response: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
li.Logger.Printf(requestFormat, b.String())
|
|
||||||
|
|
||||||
r.Body = ioutil.NopCloser(&body)
|
|
||||||
return p.Prepare(r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByInspecting returns a RespondDecorator that emits the http.Response to the supplied logger. The
|
|
||||||
// body is restored after being emitted.
|
|
||||||
//
|
|
||||||
// Note: Since it reads the entire Body, this decorator should not be used where body streaming is
|
|
||||||
// important. It is best used to trace JSON or similar body values.
|
|
||||||
func (li LoggingInspector) ByInspecting() RespondDecorator {
|
|
||||||
return func(r Responder) Responder {
|
|
||||||
return ResponderFunc(func(resp *http.Response) error {
|
|
||||||
var body, b bytes.Buffer
|
|
||||||
defer resp.Body.Close()
|
|
||||||
resp.Body = ioutil.NopCloser(io.TeeReader(resp.Body, &body))
|
|
||||||
if err := resp.Write(&b); err != nil {
|
|
||||||
return fmt.Errorf("Failed to write response: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
li.Logger.Printf(responseFormat, b.String())
|
|
||||||
|
|
||||||
resp.Body = ioutil.NopCloser(&body)
|
|
||||||
return r.Respond(resp)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client is the base for autorest generated clients. It provides default, "do nothing"
|
|
||||||
// implementations of an Authorizer, RequestInspector, and ResponseInspector. It also returns the
|
|
||||||
// standard, undecorated http.Client as a default Sender.
|
|
||||||
//
|
|
||||||
// Generated clients should also use Error (see NewError and NewErrorWithError) for errors and
|
|
||||||
// return responses that compose with Response.
|
|
||||||
//
|
|
||||||
// Most customization of generated clients is best achieved by supplying a custom Authorizer, custom
|
|
||||||
// RequestInspector, and / or custom ResponseInspector. Users may log requests, implement circuit
|
|
||||||
// breakers (see https://msdn.microsoft.com/en-us/library/dn589784.aspx) or otherwise influence
|
|
||||||
// sending the request by providing a decorated Sender.
|
|
||||||
type Client struct {
|
|
||||||
Authorizer Authorizer
|
|
||||||
Sender Sender
|
|
||||||
RequestInspector PrepareDecorator
|
|
||||||
ResponseInspector RespondDecorator
|
|
||||||
|
|
||||||
// PollingDelay sets the polling frequency used in absence of a Retry-After HTTP header
|
|
||||||
PollingDelay time.Duration
|
|
||||||
|
|
||||||
// PollingDuration sets the maximum polling time after which an error is returned.
|
|
||||||
// Setting this to zero will use the provided context to control the duration.
|
|
||||||
PollingDuration time.Duration
|
|
||||||
|
|
||||||
// RetryAttempts sets the total number of times the client will attempt to make an HTTP request.
|
|
||||||
// Set the value to 1 to disable retries. DO NOT set the value to less than 1.
|
|
||||||
RetryAttempts int
|
|
||||||
|
|
||||||
// RetryDuration sets the delay duration for retries.
|
|
||||||
RetryDuration time.Duration
|
|
||||||
|
|
||||||
// UserAgent, if not empty, will be set as the HTTP User-Agent header on all requests sent
|
|
||||||
// through the Do method.
|
|
||||||
UserAgent string
|
|
||||||
|
|
||||||
Jar http.CookieJar
|
|
||||||
|
|
||||||
// Set to true to skip attempted registration of resource providers (false by default).
|
|
||||||
SkipResourceProviderRegistration bool
|
|
||||||
|
|
||||||
// SendDecorators can be used to override the default chain of SendDecorators.
|
|
||||||
// This can be used to specify things like a custom retry SendDecorator.
|
|
||||||
// Set this to an empty slice to use no SendDecorators.
|
|
||||||
SendDecorators []SendDecorator
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClientWithUserAgent returns an instance of a Client with the UserAgent set to the passed
|
|
||||||
// string.
|
|
||||||
func NewClientWithUserAgent(ua string) Client {
|
|
||||||
return newClient(ua, tls.RenegotiateNever)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientOptions contains various Client configuration options.
|
|
||||||
type ClientOptions struct {
|
|
||||||
// UserAgent is an optional user-agent string to append to the default user agent.
|
|
||||||
UserAgent string
|
|
||||||
|
|
||||||
// Renegotiation is an optional setting to control client-side TLS renegotiation.
|
|
||||||
Renegotiation tls.RenegotiationSupport
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClientWithOptions returns an instance of a Client with the specified values.
|
|
||||||
func NewClientWithOptions(options ClientOptions) Client {
|
|
||||||
return newClient(options.UserAgent, options.Renegotiation)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newClient(ua string, renegotiation tls.RenegotiationSupport) Client {
|
|
||||||
c := Client{
|
|
||||||
PollingDelay: DefaultPollingDelay,
|
|
||||||
PollingDuration: DefaultPollingDuration,
|
|
||||||
RetryAttempts: DefaultRetryAttempts,
|
|
||||||
RetryDuration: DefaultRetryDuration,
|
|
||||||
UserAgent: UserAgent(),
|
|
||||||
}
|
|
||||||
c.Sender = c.sender(renegotiation)
|
|
||||||
c.AddToUserAgent(ua)
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddToUserAgent adds an extension to the current user agent
|
|
||||||
func (c *Client) AddToUserAgent(extension string) error {
|
|
||||||
if extension != "" {
|
|
||||||
c.UserAgent = fmt.Sprintf("%s %s", c.UserAgent, extension)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("Extension was empty, User Agent stayed as %s", c.UserAgent)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do implements the Sender interface by invoking the active Sender after applying authorization.
|
|
||||||
// If Sender is not set, it uses a new instance of http.Client. In both cases it will, if UserAgent
|
|
||||||
// is set, apply set the User-Agent header.
|
|
||||||
func (c Client) Do(r *http.Request) (*http.Response, error) {
|
|
||||||
if r.UserAgent() == "" {
|
|
||||||
r, _ = Prepare(r,
|
|
||||||
WithUserAgent(c.UserAgent))
|
|
||||||
}
|
|
||||||
// NOTE: c.WithInspection() must be last in the list so that it can inspect all preceding operations
|
|
||||||
r, err := Prepare(r,
|
|
||||||
c.WithAuthorization(),
|
|
||||||
c.WithInspection())
|
|
||||||
if err != nil {
|
|
||||||
var resp *http.Response
|
|
||||||
if detErr, ok := err.(DetailedError); ok {
|
|
||||||
// if the authorization failed (e.g. invalid credentials) there will
|
|
||||||
// be a response associated with the error, be sure to return it.
|
|
||||||
resp = detErr.Response
|
|
||||||
}
|
|
||||||
return resp, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed")
|
|
||||||
}
|
|
||||||
logger.Instance.WriteRequest(r, logger.Filter{
|
|
||||||
Header: func(k string, v []string) (bool, []string) {
|
|
||||||
// remove the auth token from the log
|
|
||||||
if strings.EqualFold(k, "Authorization") || strings.EqualFold(k, "Ocp-Apim-Subscription-Key") {
|
|
||||||
v = []string{"**REDACTED**"}
|
|
||||||
}
|
|
||||||
return true, v
|
|
||||||
},
|
|
||||||
})
|
|
||||||
resp, err := SendWithSender(c.sender(tls.RenegotiateNever), r)
|
|
||||||
if resp == nil && err == nil {
|
|
||||||
err = errors.New("autorest: received nil response and error")
|
|
||||||
}
|
|
||||||
logger.Instance.WriteResponse(resp, logger.Filter{})
|
|
||||||
Respond(resp, c.ByInspecting())
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// sender returns the Sender to which to send requests.
|
|
||||||
func (c Client) sender(renengotiation tls.RenegotiationSupport) Sender {
|
|
||||||
if c.Sender == nil {
|
|
||||||
return sender(renengotiation)
|
|
||||||
}
|
|
||||||
return c.Sender
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAuthorization is a convenience method that returns the WithAuthorization PrepareDecorator
|
|
||||||
// from the current Authorizer. If not Authorizer is set, it uses the NullAuthorizer.
|
|
||||||
func (c Client) WithAuthorization() PrepareDecorator {
|
|
||||||
return c.authorizer().WithAuthorization()
|
|
||||||
}
|
|
||||||
|
|
||||||
// authorizer returns the Authorizer to use.
|
|
||||||
func (c Client) authorizer() Authorizer {
|
|
||||||
if c.Authorizer == nil {
|
|
||||||
return NullAuthorizer{}
|
|
||||||
}
|
|
||||||
return c.Authorizer
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithInspection is a convenience method that passes the request to the supplied RequestInspector,
|
|
||||||
// if present, or returns the WithNothing PrepareDecorator otherwise.
|
|
||||||
func (c Client) WithInspection() PrepareDecorator {
|
|
||||||
if c.RequestInspector == nil {
|
|
||||||
return WithNothing()
|
|
||||||
}
|
|
||||||
return c.RequestInspector
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByInspecting is a convenience method that passes the response to the supplied ResponseInspector,
|
|
||||||
// if present, or returns the ByIgnoring RespondDecorator otherwise.
|
|
||||||
func (c Client) ByInspecting() RespondDecorator {
|
|
||||||
if c.ResponseInspector == nil {
|
|
||||||
return ByIgnoring()
|
|
||||||
}
|
|
||||||
return c.ResponseInspector
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send sends the provided http.Request using the client's Sender or the default sender.
|
|
||||||
// It returns the http.Response and possible error. It also accepts a, possibly empty,
|
|
||||||
// default set of SendDecorators used when sending the request.
|
|
||||||
// SendDecorators have the following precedence:
|
|
||||||
// 1. In a request's context via WithSendDecorators()
|
|
||||||
// 2. Specified on the client in SendDecorators
|
|
||||||
// 3. The default values specified in this method
|
|
||||||
func (c Client) Send(req *http.Request, decorators ...SendDecorator) (*http.Response, error) {
|
|
||||||
if c.SendDecorators != nil {
|
|
||||||
decorators = c.SendDecorators
|
|
||||||
}
|
|
||||||
inCtx := req.Context().Value(ctxSendDecorators{})
|
|
||||||
if sd, ok := inCtx.([]SendDecorator); ok {
|
|
||||||
decorators = sd
|
|
||||||
}
|
|
||||||
return SendWithSender(c, req, decorators...)
|
|
||||||
}
|
|
||||||
191
vendor/github.com/Azure/go-autorest/autorest/date/LICENSE
generated
vendored
191
vendor/github.com/Azure/go-autorest/autorest/date/LICENSE
generated
vendored
@@ -1,191 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
Copyright 2015 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.
|
|
||||||
96
vendor/github.com/Azure/go-autorest/autorest/date/date.go
generated
vendored
96
vendor/github.com/Azure/go-autorest/autorest/date/date.go
generated
vendored
@@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
Package date provides time.Time derivatives that conform to the Swagger.io (https://swagger.io/)
|
|
||||||
defined date formats: Date and DateTime. Both types may, in most cases, be used in lieu of
|
|
||||||
time.Time types. And both convert to time.Time through a ToTime method.
|
|
||||||
*/
|
|
||||||
package date
|
|
||||||
|
|
||||||
// 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"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
fullDate = "2006-01-02"
|
|
||||||
fullDateJSON = `"2006-01-02"`
|
|
||||||
dateFormat = "%04d-%02d-%02d"
|
|
||||||
jsonFormat = `"%04d-%02d-%02d"`
|
|
||||||
)
|
|
||||||
|
|
||||||
// Date defines a type similar to time.Time but assumes a layout of RFC3339 full-date (i.e.,
|
|
||||||
// 2006-01-02).
|
|
||||||
type Date struct {
|
|
||||||
time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseDate create a new Date from the passed string.
|
|
||||||
func ParseDate(date string) (d Date, err error) {
|
|
||||||
return parseDate(date, fullDate)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseDate(date string, format string) (Date, error) {
|
|
||||||
d, err := time.Parse(format, date)
|
|
||||||
return Date{Time: d}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalBinary preserves the Date as a byte array conforming to RFC3339 full-date (i.e.,
|
|
||||||
// 2006-01-02).
|
|
||||||
func (d Date) MarshalBinary() ([]byte, error) {
|
|
||||||
return d.MarshalText()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalBinary reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e.,
|
|
||||||
// 2006-01-02).
|
|
||||||
func (d *Date) UnmarshalBinary(data []byte) error {
|
|
||||||
return d.UnmarshalText(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON preserves the Date as a JSON string conforming to RFC3339 full-date (i.e.,
|
|
||||||
// 2006-01-02).
|
|
||||||
func (d Date) MarshalJSON() (json []byte, err error) {
|
|
||||||
return []byte(fmt.Sprintf(jsonFormat, d.Year(), d.Month(), d.Day())), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON reconstitutes the Date from a JSON string conforming to RFC3339 full-date (i.e.,
|
|
||||||
// 2006-01-02).
|
|
||||||
func (d *Date) UnmarshalJSON(data []byte) (err error) {
|
|
||||||
d.Time, err = time.Parse(fullDateJSON, string(data))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalText preserves the Date as a byte array conforming to RFC3339 full-date (i.e.,
|
|
||||||
// 2006-01-02).
|
|
||||||
func (d Date) MarshalText() (text []byte, err error) {
|
|
||||||
return []byte(fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day())), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalText reconstitutes a Date saved as a byte array conforming to RFC3339 full-date (i.e.,
|
|
||||||
// 2006-01-02).
|
|
||||||
func (d *Date) UnmarshalText(data []byte) (err error) {
|
|
||||||
d.Time, err = time.Parse(fullDate, string(data))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the Date formatted as an RFC3339 full-date string (i.e., 2006-01-02).
|
|
||||||
func (d Date) String() string {
|
|
||||||
return fmt.Sprintf(dateFormat, d.Year(), d.Month(), d.Day())
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToTime returns a Date as a time.Time
|
|
||||||
func (d Date) ToTime() time.Time {
|
|
||||||
return d.Time
|
|
||||||
}
|
|
||||||
24
vendor/github.com/Azure/go-autorest/autorest/date/go_mod_tidy_hack.go
generated
vendored
24
vendor/github.com/Azure/go-autorest/autorest/date/go_mod_tidy_hack.go
generated
vendored
@@ -1,24 +0,0 @@
|
|||||||
// +build modhack
|
|
||||||
|
|
||||||
package date
|
|
||||||
|
|
||||||
// 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 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"
|
|
||||||
103
vendor/github.com/Azure/go-autorest/autorest/date/time.go
generated
vendored
103
vendor/github.com/Azure/go-autorest/autorest/date/time.go
generated
vendored
@@ -1,103 +0,0 @@
|
|||||||
package date
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"regexp"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Azure reports time in UTC but it doesn't include the 'Z' time zone suffix in some cases.
|
|
||||||
const (
|
|
||||||
azureUtcFormatJSON = `"2006-01-02T15:04:05.999999999"`
|
|
||||||
azureUtcFormat = "2006-01-02T15:04:05.999999999"
|
|
||||||
rfc3339JSON = `"` + time.RFC3339Nano + `"`
|
|
||||||
rfc3339 = time.RFC3339Nano
|
|
||||||
tzOffsetRegex = `(Z|z|\+|-)(\d+:\d+)*"*$`
|
|
||||||
)
|
|
||||||
|
|
||||||
// Time defines a type similar to time.Time but assumes a layout of RFC3339 date-time (i.e.,
|
|
||||||
// 2006-01-02T15:04:05Z).
|
|
||||||
type Time struct {
|
|
||||||
time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalBinary preserves the Time as a byte array conforming to RFC3339 date-time (i.e.,
|
|
||||||
// 2006-01-02T15:04:05Z).
|
|
||||||
func (t Time) MarshalBinary() ([]byte, error) {
|
|
||||||
return t.Time.MarshalText()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC3339 date-time
|
|
||||||
// (i.e., 2006-01-02T15:04:05Z).
|
|
||||||
func (t *Time) UnmarshalBinary(data []byte) error {
|
|
||||||
return t.UnmarshalText(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON preserves the Time as a JSON string conforming to RFC3339 date-time (i.e.,
|
|
||||||
// 2006-01-02T15:04:05Z).
|
|
||||||
func (t Time) MarshalJSON() (json []byte, err error) {
|
|
||||||
return t.Time.MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC3339 date-time
|
|
||||||
// (i.e., 2006-01-02T15:04:05Z).
|
|
||||||
func (t *Time) UnmarshalJSON(data []byte) (err error) {
|
|
||||||
timeFormat := azureUtcFormatJSON
|
|
||||||
match, err := regexp.Match(tzOffsetRegex, data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else if match {
|
|
||||||
timeFormat = rfc3339JSON
|
|
||||||
}
|
|
||||||
t.Time, err = ParseTime(timeFormat, string(data))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalText preserves the Time as a byte array conforming to RFC3339 date-time (i.e.,
|
|
||||||
// 2006-01-02T15:04:05Z).
|
|
||||||
func (t Time) MarshalText() (text []byte, err error) {
|
|
||||||
return t.Time.MarshalText()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC3339 date-time
|
|
||||||
// (i.e., 2006-01-02T15:04:05Z).
|
|
||||||
func (t *Time) UnmarshalText(data []byte) (err error) {
|
|
||||||
timeFormat := azureUtcFormat
|
|
||||||
match, err := regexp.Match(tzOffsetRegex, data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else if match {
|
|
||||||
timeFormat = rfc3339
|
|
||||||
}
|
|
||||||
t.Time, err = ParseTime(timeFormat, string(data))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the Time formatted as an RFC3339 date-time string (i.e.,
|
|
||||||
// 2006-01-02T15:04:05Z).
|
|
||||||
func (t Time) String() string {
|
|
||||||
// Note: time.Time.String does not return an RFC3339 compliant string, time.Time.MarshalText does.
|
|
||||||
b, err := t.MarshalText()
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToTime returns a Time as a time.Time
|
|
||||||
func (t Time) ToTime() time.Time {
|
|
||||||
return t.Time
|
|
||||||
}
|
|
||||||
100
vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go
generated
vendored
100
vendor/github.com/Azure/go-autorest/autorest/date/timerfc1123.go
generated
vendored
@@ -1,100 +0,0 @@
|
|||||||
package date
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"errors"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
rfc1123JSON = `"` + time.RFC1123 + `"`
|
|
||||||
rfc1123 = time.RFC1123
|
|
||||||
)
|
|
||||||
|
|
||||||
// TimeRFC1123 defines a type similar to time.Time but assumes a layout of RFC1123 date-time (i.e.,
|
|
||||||
// Mon, 02 Jan 2006 15:04:05 MST).
|
|
||||||
type TimeRFC1123 struct {
|
|
||||||
time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON reconstitutes the Time from a JSON string conforming to RFC1123 date-time
|
|
||||||
// (i.e., Mon, 02 Jan 2006 15:04:05 MST).
|
|
||||||
func (t *TimeRFC1123) UnmarshalJSON(data []byte) (err error) {
|
|
||||||
t.Time, err = ParseTime(rfc1123JSON, string(data))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON preserves the Time as a JSON string conforming to RFC1123 date-time (i.e.,
|
|
||||||
// Mon, 02 Jan 2006 15:04:05 MST).
|
|
||||||
func (t TimeRFC1123) MarshalJSON() ([]byte, error) {
|
|
||||||
if y := t.Year(); y < 0 || y >= 10000 {
|
|
||||||
return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
|
|
||||||
}
|
|
||||||
b := []byte(t.Format(rfc1123JSON))
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalText preserves the Time as a byte array conforming to RFC1123 date-time (i.e.,
|
|
||||||
// Mon, 02 Jan 2006 15:04:05 MST).
|
|
||||||
func (t TimeRFC1123) MarshalText() ([]byte, error) {
|
|
||||||
if y := t.Year(); y < 0 || y >= 10000 {
|
|
||||||
return nil, errors.New("Time.MarshalText: year outside of range [0,9999]")
|
|
||||||
}
|
|
||||||
|
|
||||||
b := []byte(t.Format(rfc1123))
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalText reconstitutes a Time saved as a byte array conforming to RFC1123 date-time
|
|
||||||
// (i.e., Mon, 02 Jan 2006 15:04:05 MST).
|
|
||||||
func (t *TimeRFC1123) UnmarshalText(data []byte) (err error) {
|
|
||||||
t.Time, err = ParseTime(rfc1123, string(data))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalBinary preserves the Time as a byte array conforming to RFC1123 date-time (i.e.,
|
|
||||||
// Mon, 02 Jan 2006 15:04:05 MST).
|
|
||||||
func (t TimeRFC1123) MarshalBinary() ([]byte, error) {
|
|
||||||
return t.MarshalText()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalBinary reconstitutes a Time saved as a byte array conforming to RFC1123 date-time
|
|
||||||
// (i.e., Mon, 02 Jan 2006 15:04:05 MST).
|
|
||||||
func (t *TimeRFC1123) UnmarshalBinary(data []byte) error {
|
|
||||||
return t.UnmarshalText(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToTime returns a Time as a time.Time
|
|
||||||
func (t TimeRFC1123) ToTime() time.Time {
|
|
||||||
return t.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the Time formatted as an RFC1123 date-time string (i.e.,
|
|
||||||
// Mon, 02 Jan 2006 15:04:05 MST).
|
|
||||||
func (t TimeRFC1123) String() string {
|
|
||||||
// Note: time.Time.String does not return an RFC1123 compliant string, time.Time.MarshalText does.
|
|
||||||
b, err := t.MarshalText()
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
123
vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go
generated
vendored
123
vendor/github.com/Azure/go-autorest/autorest/date/unixtime.go
generated
vendored
@@ -1,123 +0,0 @@
|
|||||||
package date
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
|
||||||
"encoding/json"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// unixEpoch is the moment in time that should be treated as timestamp 0.
|
|
||||||
var unixEpoch = time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC)
|
|
||||||
|
|
||||||
// UnixTime marshals and unmarshals a time that is represented as the number
|
|
||||||
// of seconds (ignoring skip-seconds) since the Unix Epoch.
|
|
||||||
type UnixTime time.Time
|
|
||||||
|
|
||||||
// Duration returns the time as a Duration since the UnixEpoch.
|
|
||||||
func (t UnixTime) Duration() time.Duration {
|
|
||||||
return time.Time(t).Sub(unixEpoch)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUnixTimeFromSeconds creates a UnixTime as a number of seconds from the UnixEpoch.
|
|
||||||
func NewUnixTimeFromSeconds(seconds float64) UnixTime {
|
|
||||||
return NewUnixTimeFromDuration(time.Duration(seconds * float64(time.Second)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUnixTimeFromNanoseconds creates a UnixTime as a number of nanoseconds from the UnixEpoch.
|
|
||||||
func NewUnixTimeFromNanoseconds(nanoseconds int64) UnixTime {
|
|
||||||
return NewUnixTimeFromDuration(time.Duration(nanoseconds))
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUnixTimeFromDuration creates a UnixTime as a duration of time since the UnixEpoch.
|
|
||||||
func NewUnixTimeFromDuration(dur time.Duration) UnixTime {
|
|
||||||
return UnixTime(unixEpoch.Add(dur))
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnixEpoch retreives the moment considered the Unix Epoch. I.e. The time represented by '0'
|
|
||||||
func UnixEpoch() time.Time {
|
|
||||||
return unixEpoch
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON preserves the UnixTime as a JSON number conforming to Unix Timestamp requirements.
|
|
||||||
// (i.e. the number of seconds since midnight January 1st, 1970 not considering leap seconds.)
|
|
||||||
func (t UnixTime) MarshalJSON() ([]byte, error) {
|
|
||||||
buffer := &bytes.Buffer{}
|
|
||||||
enc := json.NewEncoder(buffer)
|
|
||||||
err := enc.Encode(float64(time.Time(t).UnixNano()) / 1e9)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return buffer.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON reconstitures a UnixTime saved as a JSON number of the number of seconds since
|
|
||||||
// midnight January 1st, 1970.
|
|
||||||
func (t *UnixTime) UnmarshalJSON(text []byte) error {
|
|
||||||
dec := json.NewDecoder(bytes.NewReader(text))
|
|
||||||
|
|
||||||
var secondsSinceEpoch float64
|
|
||||||
if err := dec.Decode(&secondsSinceEpoch); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*t = NewUnixTimeFromSeconds(secondsSinceEpoch)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalText stores the number of seconds since the Unix Epoch as a textual floating point number.
|
|
||||||
func (t UnixTime) MarshalText() ([]byte, error) {
|
|
||||||
cast := time.Time(t)
|
|
||||||
return cast.MarshalText()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalText populates a UnixTime with a value stored textually as a floating point number of seconds since the Unix Epoch.
|
|
||||||
func (t *UnixTime) UnmarshalText(raw []byte) error {
|
|
||||||
var unmarshaled time.Time
|
|
||||||
|
|
||||||
if err := unmarshaled.UnmarshalText(raw); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*t = UnixTime(unmarshaled)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalBinary converts a UnixTime into a binary.LittleEndian float64 of nanoseconds since the epoch.
|
|
||||||
func (t UnixTime) MarshalBinary() ([]byte, error) {
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
|
|
||||||
payload := int64(t.Duration())
|
|
||||||
|
|
||||||
if err := binary.Write(buf, binary.LittleEndian, &payload); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalBinary converts a from a binary.LittleEndian float64 of nanoseconds since the epoch into a UnixTime.
|
|
||||||
func (t *UnixTime) UnmarshalBinary(raw []byte) error {
|
|
||||||
var nanosecondsSinceEpoch int64
|
|
||||||
|
|
||||||
if err := binary.Read(bytes.NewReader(raw), binary.LittleEndian, &nanosecondsSinceEpoch); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*t = NewUnixTimeFromNanoseconds(nanosecondsSinceEpoch)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
25
vendor/github.com/Azure/go-autorest/autorest/date/utility.go
generated
vendored
25
vendor/github.com/Azure/go-autorest/autorest/date/utility.go
generated
vendored
@@ -1,25 +0,0 @@
|
|||||||
package date
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ParseTime to parse Time string to specified format.
|
|
||||||
func ParseTime(format string, t string) (d time.Time, err error) {
|
|
||||||
return time.Parse(format, strings.ToUpper(t))
|
|
||||||
}
|
|
||||||
103
vendor/github.com/Azure/go-autorest/autorest/error.go
generated
vendored
103
vendor/github.com/Azure/go-autorest/autorest/error.go
generated
vendored
@@ -1,103 +0,0 @@
|
|||||||
package autorest
|
|
||||||
|
|
||||||
// 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"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// UndefinedStatusCode is used when HTTP status code is not available for an error.
|
|
||||||
UndefinedStatusCode = 0
|
|
||||||
)
|
|
||||||
|
|
||||||
// DetailedError encloses a error with details of the package, method, and associated HTTP
|
|
||||||
// status code (if any).
|
|
||||||
type DetailedError struct {
|
|
||||||
Original error
|
|
||||||
|
|
||||||
// PackageType is the package type of the object emitting the error. For types, the value
|
|
||||||
// matches that produced the the '%T' format specifier of the fmt package. For other elements,
|
|
||||||
// such as functions, it is just the package name (e.g., "autorest").
|
|
||||||
PackageType string
|
|
||||||
|
|
||||||
// Method is the name of the method raising the error.
|
|
||||||
Method string
|
|
||||||
|
|
||||||
// StatusCode is the HTTP Response StatusCode (if non-zero) that led to the error.
|
|
||||||
StatusCode interface{}
|
|
||||||
|
|
||||||
// Message is the error message.
|
|
||||||
Message string
|
|
||||||
|
|
||||||
// Service Error is the response body of failed API in bytes
|
|
||||||
ServiceError []byte
|
|
||||||
|
|
||||||
// Response is the response object that was returned during failure if applicable.
|
|
||||||
Response *http.Response
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewError creates a new Error conforming object from the passed packageType, method, and
|
|
||||||
// message. message is treated as a format string to which the optional args apply.
|
|
||||||
func NewError(packageType string, method string, message string, args ...interface{}) DetailedError {
|
|
||||||
return NewErrorWithError(nil, packageType, method, nil, message, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewErrorWithResponse creates a new Error conforming object from the passed
|
|
||||||
// packageType, method, statusCode of the given resp (UndefinedStatusCode if
|
|
||||||
// resp is nil), and message. message is treated as a format string to which the
|
|
||||||
// optional args apply.
|
|
||||||
func NewErrorWithResponse(packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError {
|
|
||||||
return NewErrorWithError(nil, packageType, method, resp, message, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewErrorWithError creates a new Error conforming object from the
|
|
||||||
// passed packageType, method, statusCode of the given resp (UndefinedStatusCode
|
|
||||||
// if resp is nil), message, and original error. message is treated as a format
|
|
||||||
// string to which the optional args apply.
|
|
||||||
func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError {
|
|
||||||
if v, ok := original.(DetailedError); ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
statusCode := UndefinedStatusCode
|
|
||||||
if resp != nil {
|
|
||||||
statusCode = resp.StatusCode
|
|
||||||
}
|
|
||||||
|
|
||||||
return DetailedError{
|
|
||||||
Original: original,
|
|
||||||
PackageType: packageType,
|
|
||||||
Method: method,
|
|
||||||
StatusCode: statusCode,
|
|
||||||
Message: fmt.Sprintf(message, args...),
|
|
||||||
Response: resp,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns a formatted containing all available details (i.e., PackageType, Method,
|
|
||||||
// StatusCode, Message, and original error (if any)).
|
|
||||||
func (e DetailedError) Error() string {
|
|
||||||
if e.Original == nil {
|
|
||||||
return fmt.Sprintf("%s#%s: %s: StatusCode=%d", e.PackageType, e.Method, e.Message, e.StatusCode)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s#%s: %s: StatusCode=%d -- Original Error: %v", e.PackageType, e.Method, e.Message, e.StatusCode, e.Original)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unwrap returns the original error.
|
|
||||||
func (e DetailedError) Unwrap() error {
|
|
||||||
return e.Original
|
|
||||||
}
|
|
||||||
24
vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go
generated
vendored
24
vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go
generated
vendored
@@ -1,24 +0,0 @@
|
|||||||
// +build modhack
|
|
||||||
|
|
||||||
package autorest
|
|
||||||
|
|
||||||
// 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 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"
|
|
||||||
547
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
547
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
@@ -1,547 +0,0 @@
|
|||||||
package autorest
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"mime/multipart"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
mimeTypeJSON = "application/json"
|
|
||||||
mimeTypeOctetStream = "application/octet-stream"
|
|
||||||
mimeTypeFormPost = "application/x-www-form-urlencoded"
|
|
||||||
|
|
||||||
headerAuthorization = "Authorization"
|
|
||||||
headerAuxAuthorization = "x-ms-authorization-auxiliary"
|
|
||||||
headerContentType = "Content-Type"
|
|
||||||
headerUserAgent = "User-Agent"
|
|
||||||
)
|
|
||||||
|
|
||||||
// used as a key type in context.WithValue()
|
|
||||||
type ctxPrepareDecorators struct{}
|
|
||||||
|
|
||||||
// WithPrepareDecorators adds the specified PrepareDecorators to the provided context.
|
|
||||||
// If no PrepareDecorators are provided the context is unchanged.
|
|
||||||
func WithPrepareDecorators(ctx context.Context, prepareDecorator []PrepareDecorator) context.Context {
|
|
||||||
if len(prepareDecorator) == 0 {
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
return context.WithValue(ctx, ctxPrepareDecorators{}, prepareDecorator)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPrepareDecorators returns the PrepareDecorators in the provided context or the provided default PrepareDecorators.
|
|
||||||
func GetPrepareDecorators(ctx context.Context, defaultPrepareDecorators ...PrepareDecorator) []PrepareDecorator {
|
|
||||||
inCtx := ctx.Value(ctxPrepareDecorators{})
|
|
||||||
if pd, ok := inCtx.([]PrepareDecorator); ok {
|
|
||||||
return pd
|
|
||||||
}
|
|
||||||
return defaultPrepareDecorators
|
|
||||||
}
|
|
||||||
|
|
||||||
// Preparer is the interface that wraps the Prepare method.
|
|
||||||
//
|
|
||||||
// Prepare accepts and possibly modifies an http.Request (e.g., adding Headers). Implementations
|
|
||||||
// must ensure to not share or hold per-invocation state since Preparers may be shared and re-used.
|
|
||||||
type Preparer interface {
|
|
||||||
Prepare(*http.Request) (*http.Request, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PreparerFunc is a method that implements the Preparer interface.
|
|
||||||
type PreparerFunc func(*http.Request) (*http.Request, error)
|
|
||||||
|
|
||||||
// Prepare implements the Preparer interface on PreparerFunc.
|
|
||||||
func (pf PreparerFunc) Prepare(r *http.Request) (*http.Request, error) {
|
|
||||||
return pf(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrepareDecorator takes and possibly decorates, by wrapping, a Preparer. Decorators may affect the
|
|
||||||
// http.Request and pass it along or, first, pass the http.Request along then affect the result.
|
|
||||||
type PrepareDecorator func(Preparer) Preparer
|
|
||||||
|
|
||||||
// CreatePreparer creates, decorates, and returns a Preparer.
|
|
||||||
// Without decorators, the returned Preparer returns the passed http.Request unmodified.
|
|
||||||
// Preparers are safe to share and re-use.
|
|
||||||
func CreatePreparer(decorators ...PrepareDecorator) Preparer {
|
|
||||||
return DecoratePreparer(
|
|
||||||
Preparer(PreparerFunc(func(r *http.Request) (*http.Request, error) { return r, nil })),
|
|
||||||
decorators...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecoratePreparer accepts a Preparer and a, possibly empty, set of PrepareDecorators, which it
|
|
||||||
// applies to the Preparer. Decorators are applied in the order received, but their affect upon the
|
|
||||||
// request depends on whether they are a pre-decorator (change the http.Request and then pass it
|
|
||||||
// along) or a post-decorator (pass the http.Request along and alter it on return).
|
|
||||||
func DecoratePreparer(p Preparer, decorators ...PrepareDecorator) Preparer {
|
|
||||||
for _, decorate := range decorators {
|
|
||||||
p = decorate(p)
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare accepts an http.Request and a, possibly empty, set of PrepareDecorators.
|
|
||||||
// It creates a Preparer from the decorators which it then applies to the passed http.Request.
|
|
||||||
func Prepare(r *http.Request, decorators ...PrepareDecorator) (*http.Request, error) {
|
|
||||||
if r == nil {
|
|
||||||
return nil, NewError("autorest", "Prepare", "Invoked without an http.Request")
|
|
||||||
}
|
|
||||||
return CreatePreparer(decorators...).Prepare(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithNothing returns a "do nothing" PrepareDecorator that makes no changes to the passed
|
|
||||||
// http.Request.
|
|
||||||
func WithNothing() PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
return p.Prepare(r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithHeader returns a PrepareDecorator that sets the specified HTTP header of the http.Request to
|
|
||||||
// the passed value. It canonicalizes the passed header name (via http.CanonicalHeaderKey) before
|
|
||||||
// adding the header.
|
|
||||||
func WithHeader(header string, value string) PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
setHeader(r, http.CanonicalHeaderKey(header), value)
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithHeaders returns a PrepareDecorator that sets the specified HTTP headers of the http.Request to
|
|
||||||
// the passed value. It canonicalizes the passed headers name (via http.CanonicalHeaderKey) before
|
|
||||||
// adding them.
|
|
||||||
func WithHeaders(headers map[string]interface{}) PrepareDecorator {
|
|
||||||
h := ensureValueStrings(headers)
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
if r.Header == nil {
|
|
||||||
r.Header = make(http.Header)
|
|
||||||
}
|
|
||||||
|
|
||||||
for name, value := range h {
|
|
||||||
r.Header.Set(http.CanonicalHeaderKey(name), value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithBearerAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
|
||||||
// value is "Bearer " followed by the supplied token.
|
|
||||||
func WithBearerAuthorization(token string) PrepareDecorator {
|
|
||||||
return WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", token))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsContentType returns a PrepareDecorator that adds an HTTP Content-Type header whose value
|
|
||||||
// is the passed contentType.
|
|
||||||
func AsContentType(contentType string) PrepareDecorator {
|
|
||||||
return WithHeader(headerContentType, contentType)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithUserAgent returns a PrepareDecorator that adds an HTTP User-Agent header whose value is the
|
|
||||||
// passed string.
|
|
||||||
func WithUserAgent(ua string) PrepareDecorator {
|
|
||||||
return WithHeader(headerUserAgent, ua)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsFormURLEncoded returns a PrepareDecorator that adds an HTTP Content-Type header whose value is
|
|
||||||
// "application/x-www-form-urlencoded".
|
|
||||||
func AsFormURLEncoded() PrepareDecorator {
|
|
||||||
return AsContentType(mimeTypeFormPost)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsJSON returns a PrepareDecorator that adds an HTTP Content-Type header whose value is
|
|
||||||
// "application/json".
|
|
||||||
func AsJSON() PrepareDecorator {
|
|
||||||
return AsContentType(mimeTypeJSON)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsOctetStream returns a PrepareDecorator that adds the "application/octet-stream" Content-Type header.
|
|
||||||
func AsOctetStream() PrepareDecorator {
|
|
||||||
return AsContentType(mimeTypeOctetStream)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithMethod returns a PrepareDecorator that sets the HTTP method of the passed request. The
|
|
||||||
// decorator does not validate that the passed method string is a known HTTP method.
|
|
||||||
func WithMethod(method string) PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r.Method = method
|
|
||||||
return p.Prepare(r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsDelete returns a PrepareDecorator that sets the HTTP method to DELETE.
|
|
||||||
func AsDelete() PrepareDecorator { return WithMethod("DELETE") }
|
|
||||||
|
|
||||||
// AsGet returns a PrepareDecorator that sets the HTTP method to GET.
|
|
||||||
func AsGet() PrepareDecorator { return WithMethod("GET") }
|
|
||||||
|
|
||||||
// AsHead returns a PrepareDecorator that sets the HTTP method to HEAD.
|
|
||||||
func AsHead() PrepareDecorator { return WithMethod("HEAD") }
|
|
||||||
|
|
||||||
// AsMerge returns a PrepareDecorator that sets the HTTP method to MERGE.
|
|
||||||
func AsMerge() PrepareDecorator { return WithMethod("MERGE") }
|
|
||||||
|
|
||||||
// AsOptions returns a PrepareDecorator that sets the HTTP method to OPTIONS.
|
|
||||||
func AsOptions() PrepareDecorator { return WithMethod("OPTIONS") }
|
|
||||||
|
|
||||||
// AsPatch returns a PrepareDecorator that sets the HTTP method to PATCH.
|
|
||||||
func AsPatch() PrepareDecorator { return WithMethod("PATCH") }
|
|
||||||
|
|
||||||
// AsPost returns a PrepareDecorator that sets the HTTP method to POST.
|
|
||||||
func AsPost() PrepareDecorator { return WithMethod("POST") }
|
|
||||||
|
|
||||||
// AsPut returns a PrepareDecorator that sets the HTTP method to PUT.
|
|
||||||
func AsPut() PrepareDecorator { return WithMethod("PUT") }
|
|
||||||
|
|
||||||
// WithBaseURL returns a PrepareDecorator that populates the http.Request with a url.URL constructed
|
|
||||||
// from the supplied baseUrl. Query parameters will be encoded as required.
|
|
||||||
func WithBaseURL(baseURL string) PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
var u *url.URL
|
|
||||||
if u, err = url.Parse(baseURL); err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
if u.Scheme == "" {
|
|
||||||
return r, fmt.Errorf("autorest: No scheme detected in URL %s", baseURL)
|
|
||||||
}
|
|
||||||
if u.RawQuery != "" {
|
|
||||||
q, err := url.ParseQuery(u.RawQuery)
|
|
||||||
if err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
u.RawQuery = q.Encode()
|
|
||||||
}
|
|
||||||
r.URL = u
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithBytes returns a PrepareDecorator that takes a list of bytes
|
|
||||||
// which passes the bytes directly to the body
|
|
||||||
func WithBytes(input *[]byte) PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
if input == nil {
|
|
||||||
return r, fmt.Errorf("Input Bytes was nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
r.ContentLength = int64(len(*input))
|
|
||||||
r.Body = ioutil.NopCloser(bytes.NewReader(*input))
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithCustomBaseURL returns a PrepareDecorator that replaces brace-enclosed keys within the
|
|
||||||
// request base URL (i.e., http.Request.URL) with the corresponding values from the passed map.
|
|
||||||
func WithCustomBaseURL(baseURL string, urlParameters map[string]interface{}) PrepareDecorator {
|
|
||||||
parameters := ensureValueStrings(urlParameters)
|
|
||||||
for key, value := range parameters {
|
|
||||||
baseURL = strings.Replace(baseURL, "{"+key+"}", value, -1)
|
|
||||||
}
|
|
||||||
return WithBaseURL(baseURL)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) into the
|
|
||||||
// http.Request body.
|
|
||||||
func WithFormData(v url.Values) PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
s := v.Encode()
|
|
||||||
|
|
||||||
setHeader(r, http.CanonicalHeaderKey(headerContentType), mimeTypeFormPost)
|
|
||||||
r.ContentLength = int64(len(s))
|
|
||||||
r.Body = ioutil.NopCloser(strings.NewReader(s))
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithMultiPartFormData returns a PrepareDecoratore that "URL encodes" (e.g., bar=baz&foo=quux) form parameters
|
|
||||||
// into the http.Request body.
|
|
||||||
func WithMultiPartFormData(formDataParameters map[string]interface{}) PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
var body bytes.Buffer
|
|
||||||
writer := multipart.NewWriter(&body)
|
|
||||||
for key, value := range formDataParameters {
|
|
||||||
if rc, ok := value.(io.ReadCloser); ok {
|
|
||||||
var fd io.Writer
|
|
||||||
if fd, err = writer.CreateFormFile(key, key); err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
if _, err = io.Copy(fd, rc); err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err = writer.WriteField(key, ensureValueString(value)); err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err = writer.Close(); err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
setHeader(r, http.CanonicalHeaderKey(headerContentType), writer.FormDataContentType())
|
|
||||||
r.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))
|
|
||||||
r.ContentLength = int64(body.Len())
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithFile returns a PrepareDecorator that sends file in request body.
|
|
||||||
func WithFile(f io.ReadCloser) PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
b, err := ioutil.ReadAll(f)
|
|
||||||
if err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
r.Body = ioutil.NopCloser(bytes.NewReader(b))
|
|
||||||
r.ContentLength = int64(len(b))
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithBool returns a PrepareDecorator that encodes the passed bool into the body of the request
|
|
||||||
// and sets the Content-Length header.
|
|
||||||
func WithBool(v bool) PrepareDecorator {
|
|
||||||
return WithString(fmt.Sprintf("%v", v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithFloat32 returns a PrepareDecorator that encodes the passed float32 into the body of the
|
|
||||||
// request and sets the Content-Length header.
|
|
||||||
func WithFloat32(v float32) PrepareDecorator {
|
|
||||||
return WithString(fmt.Sprintf("%v", v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithFloat64 returns a PrepareDecorator that encodes the passed float64 into the body of the
|
|
||||||
// request and sets the Content-Length header.
|
|
||||||
func WithFloat64(v float64) PrepareDecorator {
|
|
||||||
return WithString(fmt.Sprintf("%v", v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithInt32 returns a PrepareDecorator that encodes the passed int32 into the body of the request
|
|
||||||
// and sets the Content-Length header.
|
|
||||||
func WithInt32(v int32) PrepareDecorator {
|
|
||||||
return WithString(fmt.Sprintf("%v", v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithInt64 returns a PrepareDecorator that encodes the passed int64 into the body of the request
|
|
||||||
// and sets the Content-Length header.
|
|
||||||
func WithInt64(v int64) PrepareDecorator {
|
|
||||||
return WithString(fmt.Sprintf("%v", v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithString returns a PrepareDecorator that encodes the passed string into the body of the request
|
|
||||||
// and sets the Content-Length header.
|
|
||||||
func WithString(v string) PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
r.ContentLength = int64(len(v))
|
|
||||||
r.Body = ioutil.NopCloser(strings.NewReader(v))
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithJSON returns a PrepareDecorator that encodes the data passed as JSON into the body of the
|
|
||||||
// request and sets the Content-Length header.
|
|
||||||
func WithJSON(v interface{}) PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
b, err := json.Marshal(v)
|
|
||||||
if err == nil {
|
|
||||||
r.ContentLength = int64(len(b))
|
|
||||||
r.Body = ioutil.NopCloser(bytes.NewReader(b))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithXML returns a PrepareDecorator that encodes the data passed as XML into the body of the
|
|
||||||
// request and sets the Content-Length header.
|
|
||||||
func WithXML(v interface{}) PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
b, err := xml.Marshal(v)
|
|
||||||
if err == nil {
|
|
||||||
// we have to tack on an XML header
|
|
||||||
withHeader := xml.Header + string(b)
|
|
||||||
bytesWithHeader := []byte(withHeader)
|
|
||||||
|
|
||||||
r.ContentLength = int64(len(bytesWithHeader))
|
|
||||||
setHeader(r, headerContentLength, fmt.Sprintf("%d", len(bytesWithHeader)))
|
|
||||||
r.Body = ioutil.NopCloser(bytes.NewReader(bytesWithHeader))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPath returns a PrepareDecorator that adds the supplied path to the request URL. If the path
|
|
||||||
// is absolute (that is, it begins with a "/"), it replaces the existing path.
|
|
||||||
func WithPath(path string) PrepareDecorator {
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
if r.URL == nil {
|
|
||||||
return r, NewError("autorest", "WithPath", "Invoked with a nil URL")
|
|
||||||
}
|
|
||||||
if r.URL, err = parseURL(r.URL, path); err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithEscapedPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the
|
|
||||||
// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map. The
|
|
||||||
// values will be escaped (aka URL encoded) before insertion into the path.
|
|
||||||
func WithEscapedPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator {
|
|
||||||
parameters := escapeValueStrings(ensureValueStrings(pathParameters))
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
if r.URL == nil {
|
|
||||||
return r, NewError("autorest", "WithEscapedPathParameters", "Invoked with a nil URL")
|
|
||||||
}
|
|
||||||
for key, value := range parameters {
|
|
||||||
path = strings.Replace(path, "{"+key+"}", value, -1)
|
|
||||||
}
|
|
||||||
if r.URL, err = parseURL(r.URL, path); err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPathParameters returns a PrepareDecorator that replaces brace-enclosed keys within the
|
|
||||||
// request path (i.e., http.Request.URL.Path) with the corresponding values from the passed map.
|
|
||||||
func WithPathParameters(path string, pathParameters map[string]interface{}) PrepareDecorator {
|
|
||||||
parameters := ensureValueStrings(pathParameters)
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
if r.URL == nil {
|
|
||||||
return r, NewError("autorest", "WithPathParameters", "Invoked with a nil URL")
|
|
||||||
}
|
|
||||||
for key, value := range parameters {
|
|
||||||
path = strings.Replace(path, "{"+key+"}", value, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.URL, err = parseURL(r.URL, path); err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseURL(u *url.URL, path string) (*url.URL, error) {
|
|
||||||
p := strings.TrimRight(u.String(), "/")
|
|
||||||
if !strings.HasPrefix(path, "/") {
|
|
||||||
path = "/" + path
|
|
||||||
}
|
|
||||||
return url.Parse(p + path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithQueryParameters returns a PrepareDecorators that encodes and applies the query parameters
|
|
||||||
// given in the supplied map (i.e., key=value).
|
|
||||||
func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorator {
|
|
||||||
parameters := MapToValues(queryParameters)
|
|
||||||
return func(p Preparer) Preparer {
|
|
||||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
|
||||||
r, err := p.Prepare(r)
|
|
||||||
if err == nil {
|
|
||||||
if r.URL == nil {
|
|
||||||
return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL")
|
|
||||||
}
|
|
||||||
v := r.URL.Query()
|
|
||||||
for key, value := range parameters {
|
|
||||||
for i := range value {
|
|
||||||
d, err := url.QueryUnescape(value[i])
|
|
||||||
if err != nil {
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
value[i] = d
|
|
||||||
}
|
|
||||||
v[key] = value
|
|
||||||
}
|
|
||||||
r.URL.RawQuery = v.Encode()
|
|
||||||
}
|
|
||||||
return r, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
269
vendor/github.com/Azure/go-autorest/autorest/responder.go
generated
vendored
269
vendor/github.com/Azure/go-autorest/autorest/responder.go
generated
vendored
@@ -1,269 +0,0 @@
|
|||||||
package autorest
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Responder is the interface that wraps the Respond method.
|
|
||||||
//
|
|
||||||
// Respond accepts and reacts to an http.Response. Implementations must ensure to not share or hold
|
|
||||||
// state since Responders may be shared and re-used.
|
|
||||||
type Responder interface {
|
|
||||||
Respond(*http.Response) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResponderFunc is a method that implements the Responder interface.
|
|
||||||
type ResponderFunc func(*http.Response) error
|
|
||||||
|
|
||||||
// Respond implements the Responder interface on ResponderFunc.
|
|
||||||
func (rf ResponderFunc) Respond(r *http.Response) error {
|
|
||||||
return rf(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RespondDecorator takes and possibly decorates, by wrapping, a Responder. Decorators may react to
|
|
||||||
// the http.Response and pass it along or, first, pass the http.Response along then react.
|
|
||||||
type RespondDecorator func(Responder) Responder
|
|
||||||
|
|
||||||
// CreateResponder creates, decorates, and returns a Responder. Without decorators, the returned
|
|
||||||
// Responder returns the passed http.Response unmodified. Responders may or may not be safe to share
|
|
||||||
// and re-used: It depends on the applied decorators. For example, a standard decorator that closes
|
|
||||||
// the response body is fine to share whereas a decorator that reads the body into a passed struct
|
|
||||||
// is not.
|
|
||||||
//
|
|
||||||
// To prevent memory leaks, ensure that at least one Responder closes the response body.
|
|
||||||
func CreateResponder(decorators ...RespondDecorator) Responder {
|
|
||||||
return DecorateResponder(
|
|
||||||
Responder(ResponderFunc(func(r *http.Response) error { return nil })),
|
|
||||||
decorators...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecorateResponder accepts a Responder and a, possibly empty, set of RespondDecorators, which it
|
|
||||||
// applies to the Responder. Decorators are applied in the order received, but their affect upon the
|
|
||||||
// request depends on whether they are a pre-decorator (react to the http.Response and then pass it
|
|
||||||
// along) or a post-decorator (pass the http.Response along and then react).
|
|
||||||
func DecorateResponder(r Responder, decorators ...RespondDecorator) Responder {
|
|
||||||
for _, decorate := range decorators {
|
|
||||||
r = decorate(r)
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// Respond accepts an http.Response and a, possibly empty, set of RespondDecorators.
|
|
||||||
// It creates a Responder from the decorators it then applies to the passed http.Response.
|
|
||||||
func Respond(r *http.Response, decorators ...RespondDecorator) error {
|
|
||||||
if r == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return CreateResponder(decorators...).Respond(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByIgnoring returns a RespondDecorator that ignores the passed http.Response passing it unexamined
|
|
||||||
// to the next RespondDecorator.
|
|
||||||
func ByIgnoring() RespondDecorator {
|
|
||||||
return func(r Responder) Responder {
|
|
||||||
return ResponderFunc(func(resp *http.Response) error {
|
|
||||||
return r.Respond(resp)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByCopying copies the contents of the http.Response Body into the passed bytes.Buffer as
|
|
||||||
// the Body is read.
|
|
||||||
func ByCopying(b *bytes.Buffer) RespondDecorator {
|
|
||||||
return func(r Responder) Responder {
|
|
||||||
return ResponderFunc(func(resp *http.Response) error {
|
|
||||||
err := r.Respond(resp)
|
|
||||||
if err == nil && resp != nil && resp.Body != nil {
|
|
||||||
resp.Body = TeeReadCloser(resp.Body, b)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByDiscardingBody returns a RespondDecorator that first invokes the passed Responder after which
|
|
||||||
// it copies the remaining bytes (if any) in the response body to ioutil.Discard. Since the passed
|
|
||||||
// Responder is invoked prior to discarding the response body, the decorator may occur anywhere
|
|
||||||
// within the set.
|
|
||||||
func ByDiscardingBody() RespondDecorator {
|
|
||||||
return func(r Responder) Responder {
|
|
||||||
return ResponderFunc(func(resp *http.Response) error {
|
|
||||||
err := r.Respond(resp)
|
|
||||||
if err == nil && resp != nil && resp.Body != nil {
|
|
||||||
if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
|
|
||||||
return fmt.Errorf("Error discarding the response body: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByClosing returns a RespondDecorator that first invokes the passed Responder after which it
|
|
||||||
// closes the response body. Since the passed Responder is invoked prior to closing the response
|
|
||||||
// body, the decorator may occur anywhere within the set.
|
|
||||||
func ByClosing() RespondDecorator {
|
|
||||||
return func(r Responder) Responder {
|
|
||||||
return ResponderFunc(func(resp *http.Response) error {
|
|
||||||
err := r.Respond(resp)
|
|
||||||
if resp != nil && resp.Body != nil {
|
|
||||||
if err := resp.Body.Close(); err != nil {
|
|
||||||
return fmt.Errorf("Error closing the response body: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByClosingIfError returns a RespondDecorator that first invokes the passed Responder after which
|
|
||||||
// it closes the response if the passed Responder returns an error and the response body exists.
|
|
||||||
func ByClosingIfError() RespondDecorator {
|
|
||||||
return func(r Responder) Responder {
|
|
||||||
return ResponderFunc(func(resp *http.Response) error {
|
|
||||||
err := r.Respond(resp)
|
|
||||||
if err != nil && resp != nil && resp.Body != nil {
|
|
||||||
if err := resp.Body.Close(); err != nil {
|
|
||||||
return fmt.Errorf("Error closing the response body: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByUnmarshallingBytes returns a RespondDecorator that copies the Bytes returned in the
|
|
||||||
// response Body into the value pointed to by v.
|
|
||||||
func ByUnmarshallingBytes(v *[]byte) RespondDecorator {
|
|
||||||
return func(r Responder) Responder {
|
|
||||||
return ResponderFunc(func(resp *http.Response) error {
|
|
||||||
err := r.Respond(resp)
|
|
||||||
if err == nil {
|
|
||||||
bytes, errInner := ioutil.ReadAll(resp.Body)
|
|
||||||
if errInner != nil {
|
|
||||||
err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner)
|
|
||||||
} else {
|
|
||||||
*v = bytes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByUnmarshallingJSON returns a RespondDecorator that decodes a JSON document returned in the
|
|
||||||
// response Body into the value pointed to by v.
|
|
||||||
func ByUnmarshallingJSON(v interface{}) RespondDecorator {
|
|
||||||
return func(r Responder) Responder {
|
|
||||||
return ResponderFunc(func(resp *http.Response) error {
|
|
||||||
err := r.Respond(resp)
|
|
||||||
if err == nil {
|
|
||||||
b, errInner := ioutil.ReadAll(resp.Body)
|
|
||||||
// Some responses might include a BOM, remove for successful unmarshalling
|
|
||||||
b = bytes.TrimPrefix(b, []byte("\xef\xbb\xbf"))
|
|
||||||
if errInner != nil {
|
|
||||||
err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner)
|
|
||||||
} else if len(strings.Trim(string(b), " ")) > 0 {
|
|
||||||
errInner = json.Unmarshal(b, v)
|
|
||||||
if errInner != nil {
|
|
||||||
err = fmt.Errorf("Error occurred unmarshalling JSON - Error = '%v' JSON = '%s'", errInner, string(b))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ByUnmarshallingXML returns a RespondDecorator that decodes a XML document returned in the
|
|
||||||
// response Body into the value pointed to by v.
|
|
||||||
func ByUnmarshallingXML(v interface{}) RespondDecorator {
|
|
||||||
return func(r Responder) Responder {
|
|
||||||
return ResponderFunc(func(resp *http.Response) error {
|
|
||||||
err := r.Respond(resp)
|
|
||||||
if err == nil {
|
|
||||||
b, errInner := ioutil.ReadAll(resp.Body)
|
|
||||||
if errInner != nil {
|
|
||||||
err = fmt.Errorf("Error occurred reading http.Response#Body - Error = '%v'", errInner)
|
|
||||||
} else {
|
|
||||||
errInner = xml.Unmarshal(b, v)
|
|
||||||
if errInner != nil {
|
|
||||||
err = fmt.Errorf("Error occurred unmarshalling Xml - Error = '%v' Xml = '%s'", errInner, string(b))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithErrorUnlessStatusCode returns a RespondDecorator that emits an error unless the response
|
|
||||||
// StatusCode is among the set passed. On error, response body is fully read into a buffer and
|
|
||||||
// presented in the returned error, as well as in the response body.
|
|
||||||
func WithErrorUnlessStatusCode(codes ...int) RespondDecorator {
|
|
||||||
return func(r Responder) Responder {
|
|
||||||
return ResponderFunc(func(resp *http.Response) error {
|
|
||||||
err := r.Respond(resp)
|
|
||||||
if err == nil && !ResponseHasStatusCode(resp, codes...) {
|
|
||||||
derr := NewErrorWithResponse("autorest", "WithErrorUnlessStatusCode", resp, "%v %v failed with %s",
|
|
||||||
resp.Request.Method,
|
|
||||||
resp.Request.URL,
|
|
||||||
resp.Status)
|
|
||||||
if resp.Body != nil {
|
|
||||||
defer resp.Body.Close()
|
|
||||||
b, _ := ioutil.ReadAll(resp.Body)
|
|
||||||
derr.ServiceError = b
|
|
||||||
resp.Body = ioutil.NopCloser(bytes.NewReader(b))
|
|
||||||
}
|
|
||||||
err = derr
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithErrorUnlessOK returns a RespondDecorator that emits an error if the response StatusCode is
|
|
||||||
// anything other than HTTP 200.
|
|
||||||
func WithErrorUnlessOK() RespondDecorator {
|
|
||||||
return WithErrorUnlessStatusCode(http.StatusOK)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExtractHeader extracts all values of the specified header from the http.Response. It returns an
|
|
||||||
// empty string slice if the passed http.Response is nil or the header does not exist.
|
|
||||||
func ExtractHeader(header string, resp *http.Response) []string {
|
|
||||||
if resp != nil && resp.Header != nil {
|
|
||||||
return resp.Header[http.CanonicalHeaderKey(header)]
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExtractHeaderValue extracts the first value of the specified header from the http.Response. It
|
|
||||||
// returns an empty string if the passed http.Response is nil or the header does not exist.
|
|
||||||
func ExtractHeaderValue(header string, resp *http.Response) string {
|
|
||||||
h := ExtractHeader(header, resp)
|
|
||||||
if len(h) > 0 {
|
|
||||||
return h[0]
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
52
vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go
generated
vendored
52
vendor/github.com/Azure/go-autorest/autorest/retriablerequest.go
generated
vendored
@@ -1,52 +0,0 @@
|
|||||||
package autorest
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewRetriableRequest returns a wrapper around an HTTP request that support retry logic.
|
|
||||||
func NewRetriableRequest(req *http.Request) *RetriableRequest {
|
|
||||||
return &RetriableRequest{req: req}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Request returns the wrapped HTTP request.
|
|
||||||
func (rr *RetriableRequest) Request() *http.Request {
|
|
||||||
return rr.req
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rr *RetriableRequest) prepareFromByteReader() (err error) {
|
|
||||||
// fall back to making a copy (only do this once)
|
|
||||||
b := []byte{}
|
|
||||||
if rr.req.ContentLength > 0 {
|
|
||||||
b = make([]byte, rr.req.ContentLength)
|
|
||||||
_, err = io.ReadFull(rr.req.Body, b)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
b, err = ioutil.ReadAll(rr.req.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rr.br = bytes.NewReader(b)
|
|
||||||
rr.req.Body = ioutil.NopCloser(rr.br)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
54
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
54
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
@@ -1,54 +0,0 @@
|
|||||||
// +build !go1.8
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
package autorest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RetriableRequest provides facilities for retrying an HTTP request.
|
|
||||||
type RetriableRequest struct {
|
|
||||||
req *http.Request
|
|
||||||
br *bytes.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare signals that the request is about to be sent.
|
|
||||||
func (rr *RetriableRequest) Prepare() (err error) {
|
|
||||||
// preserve the request body; this is to support retry logic as
|
|
||||||
// the underlying transport will always close the reqeust body
|
|
||||||
if rr.req.Body != nil {
|
|
||||||
if rr.br != nil {
|
|
||||||
_, err = rr.br.Seek(0, 0 /*io.SeekStart*/)
|
|
||||||
rr.req.Body = ioutil.NopCloser(rr.br)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if rr.br == nil {
|
|
||||||
// fall back to making a copy (only do this once)
|
|
||||||
err = rr.prepareFromByteReader()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeRequestBody(req *http.Request) {
|
|
||||||
req.Body = nil
|
|
||||||
req.ContentLength = 0
|
|
||||||
}
|
|
||||||
66
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
66
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
@@ -1,66 +0,0 @@
|
|||||||
// +build go1.8
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
package autorest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RetriableRequest provides facilities for retrying an HTTP request.
|
|
||||||
type RetriableRequest struct {
|
|
||||||
req *http.Request
|
|
||||||
rc io.ReadCloser
|
|
||||||
br *bytes.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare signals that the request is about to be sent.
|
|
||||||
func (rr *RetriableRequest) Prepare() (err error) {
|
|
||||||
// preserve the request body; this is to support retry logic as
|
|
||||||
// the underlying transport will always close the reqeust body
|
|
||||||
if rr.req.Body != nil {
|
|
||||||
if rr.rc != nil {
|
|
||||||
rr.req.Body = rr.rc
|
|
||||||
} else if rr.br != nil {
|
|
||||||
_, err = rr.br.Seek(0, io.SeekStart)
|
|
||||||
rr.req.Body = ioutil.NopCloser(rr.br)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if rr.req.GetBody != nil {
|
|
||||||
// this will allow us to preserve the body without having to
|
|
||||||
// make a copy. note we need to do this on each iteration
|
|
||||||
rr.rc, err = rr.req.GetBody()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else if rr.br == nil {
|
|
||||||
// fall back to making a copy (only do this once)
|
|
||||||
err = rr.prepareFromByteReader()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeRequestBody(req *http.Request) {
|
|
||||||
req.Body = nil
|
|
||||||
req.GetBody = nil
|
|
||||||
req.ContentLength = 0
|
|
||||||
}
|
|
||||||
447
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
447
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
@@ -1,447 +0,0 @@
|
|||||||
package autorest
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"context"
|
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"math"
|
|
||||||
"net/http"
|
|
||||||
"net/http/cookiejar"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Azure/go-autorest/tracing"
|
|
||||||
)
|
|
||||||
|
|
||||||
// there is one sender per TLS renegotiation type, i.e. count of tls.RenegotiationSupport enums
|
|
||||||
const defaultSendersCount = 3
|
|
||||||
|
|
||||||
type defaultSender struct {
|
|
||||||
sender Sender
|
|
||||||
init *sync.Once
|
|
||||||
}
|
|
||||||
|
|
||||||
// each type of sender will be created on demand in sender()
|
|
||||||
var defaultSenders [defaultSendersCount]defaultSender
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
for i := 0; i < defaultSendersCount; i++ {
|
|
||||||
defaultSenders[i].init = &sync.Once{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// used as a key type in context.WithValue()
|
|
||||||
type ctxSendDecorators struct{}
|
|
||||||
|
|
||||||
// WithSendDecorators adds the specified SendDecorators to the provided context.
|
|
||||||
// If no SendDecorators are provided the context is unchanged.
|
|
||||||
func WithSendDecorators(ctx context.Context, sendDecorator []SendDecorator) context.Context {
|
|
||||||
if len(sendDecorator) == 0 {
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
return context.WithValue(ctx, ctxSendDecorators{}, sendDecorator)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSendDecorators returns the SendDecorators in the provided context or the provided default SendDecorators.
|
|
||||||
func GetSendDecorators(ctx context.Context, defaultSendDecorators ...SendDecorator) []SendDecorator {
|
|
||||||
inCtx := ctx.Value(ctxSendDecorators{})
|
|
||||||
if sd, ok := inCtx.([]SendDecorator); ok {
|
|
||||||
return sd
|
|
||||||
}
|
|
||||||
return defaultSendDecorators
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sender is the interface that wraps the Do method to send HTTP requests.
|
|
||||||
//
|
|
||||||
// The standard http.Client conforms to this interface.
|
|
||||||
type Sender interface {
|
|
||||||
Do(*http.Request) (*http.Response, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SenderFunc is a method that implements the Sender interface.
|
|
||||||
type SenderFunc func(*http.Request) (*http.Response, error)
|
|
||||||
|
|
||||||
// Do implements the Sender interface on SenderFunc.
|
|
||||||
func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) {
|
|
||||||
return sf(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendDecorator takes and possibly decorates, by wrapping, a Sender. Decorators may affect the
|
|
||||||
// http.Request and pass it along or, first, pass the http.Request along then react to the
|
|
||||||
// http.Response result.
|
|
||||||
type SendDecorator func(Sender) Sender
|
|
||||||
|
|
||||||
// CreateSender creates, decorates, and returns, as a Sender, the default http.Client.
|
|
||||||
func CreateSender(decorators ...SendDecorator) Sender {
|
|
||||||
return DecorateSender(sender(tls.RenegotiateNever), decorators...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to
|
|
||||||
// the Sender. Decorators are applied in the order received, but their affect upon the request
|
|
||||||
// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a
|
|
||||||
// post-decorator (pass the http.Request along and react to the results in http.Response).
|
|
||||||
func DecorateSender(s Sender, decorators ...SendDecorator) Sender {
|
|
||||||
for _, decorate := range decorators {
|
|
||||||
s = decorate(s)
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send sends, by means of the default http.Client, the passed http.Request, returning the
|
|
||||||
// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which
|
|
||||||
// it will apply the http.Client before invoking the Do method.
|
|
||||||
//
|
|
||||||
// Send is a convenience method and not recommended for production. Advanced users should use
|
|
||||||
// SendWithSender, passing and sharing their own Sender (e.g., instance of http.Client).
|
|
||||||
//
|
|
||||||
// Send will not poll or retry requests.
|
|
||||||
func Send(r *http.Request, decorators ...SendDecorator) (*http.Response, error) {
|
|
||||||
return SendWithSender(sender(tls.RenegotiateNever), r, decorators...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendWithSender sends the passed http.Request, through the provided Sender, returning the
|
|
||||||
// http.Response and possible error. It also accepts a, possibly empty, set of SendDecorators which
|
|
||||||
// it will apply the http.Client before invoking the Do method.
|
|
||||||
//
|
|
||||||
// SendWithSender will not poll or retry requests.
|
|
||||||
func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*http.Response, error) {
|
|
||||||
return DecorateSender(s, decorators...).Do(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sender(renengotiation tls.RenegotiationSupport) Sender {
|
|
||||||
// note that we can't init defaultSenders in init() since it will
|
|
||||||
// execute before calling code has had a chance to enable tracing
|
|
||||||
defaultSenders[renengotiation].init.Do(func() {
|
|
||||||
// Use behaviour compatible with DefaultTransport, but require TLS minimum version.
|
|
||||||
defaultTransport := http.DefaultTransport.(*http.Transport)
|
|
||||||
transport := &http.Transport{
|
|
||||||
Proxy: defaultTransport.Proxy,
|
|
||||||
DialContext: defaultTransport.DialContext,
|
|
||||||
MaxIdleConns: defaultTransport.MaxIdleConns,
|
|
||||||
IdleConnTimeout: defaultTransport.IdleConnTimeout,
|
|
||||||
TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout,
|
|
||||||
ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout,
|
|
||||||
TLSClientConfig: &tls.Config{
|
|
||||||
MinVersion: tls.VersionTLS12,
|
|
||||||
Renegotiation: renengotiation,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
var roundTripper http.RoundTripper = transport
|
|
||||||
if tracing.IsEnabled() {
|
|
||||||
roundTripper = tracing.NewTransport(transport)
|
|
||||||
}
|
|
||||||
j, _ := cookiejar.New(nil)
|
|
||||||
defaultSenders[renengotiation].sender = &http.Client{Jar: j, Transport: roundTripper}
|
|
||||||
})
|
|
||||||
return defaultSenders[renengotiation].sender
|
|
||||||
}
|
|
||||||
|
|
||||||
// AfterDelay returns a SendDecorator that delays for the passed time.Duration before
|
|
||||||
// invoking the Sender. The delay may be terminated by closing the optional channel on the
|
|
||||||
// http.Request. If canceled, no further Senders are invoked.
|
|
||||||
func AfterDelay(d time.Duration) SendDecorator {
|
|
||||||
return func(s Sender) Sender {
|
|
||||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
|
||||||
if !DelayForBackoff(d, 0, r.Context().Done()) {
|
|
||||||
return nil, fmt.Errorf("autorest: AfterDelay canceled before full delay")
|
|
||||||
}
|
|
||||||
return s.Do(r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsIs returns a SendDecorator that invokes the passed Sender without modifying the http.Request.
|
|
||||||
func AsIs() SendDecorator {
|
|
||||||
return func(s Sender) Sender {
|
|
||||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
|
||||||
return s.Do(r)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoCloseIfError returns a SendDecorator that first invokes the passed Sender after which
|
|
||||||
// it closes the response if the passed Sender returns an error and the response body exists.
|
|
||||||
func DoCloseIfError() SendDecorator {
|
|
||||||
return func(s Sender) Sender {
|
|
||||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
|
||||||
resp, err := s.Do(r)
|
|
||||||
if err != nil {
|
|
||||||
Respond(resp, ByDiscardingBody(), ByClosing())
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoErrorIfStatusCode returns a SendDecorator that emits an error if the response StatusCode is
|
|
||||||
// among the set passed. Since these are artificial errors, the response body may still require
|
|
||||||
// closing.
|
|
||||||
func DoErrorIfStatusCode(codes ...int) SendDecorator {
|
|
||||||
return func(s Sender) Sender {
|
|
||||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
|
||||||
resp, err := s.Do(r)
|
|
||||||
if err == nil && ResponseHasStatusCode(resp, codes...) {
|
|
||||||
err = NewErrorWithResponse("autorest", "DoErrorIfStatusCode", resp, "%v %v failed with %s",
|
|
||||||
resp.Request.Method,
|
|
||||||
resp.Request.URL,
|
|
||||||
resp.Status)
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoErrorUnlessStatusCode returns a SendDecorator that emits an error unless the response
|
|
||||||
// StatusCode is among the set passed. Since these are artificial errors, the response body
|
|
||||||
// may still require closing.
|
|
||||||
func DoErrorUnlessStatusCode(codes ...int) SendDecorator {
|
|
||||||
return func(s Sender) Sender {
|
|
||||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
|
||||||
resp, err := s.Do(r)
|
|
||||||
if err == nil && !ResponseHasStatusCode(resp, codes...) {
|
|
||||||
err = NewErrorWithResponse("autorest", "DoErrorUnlessStatusCode", resp, "%v %v failed with %s",
|
|
||||||
resp.Request.Method,
|
|
||||||
resp.Request.URL,
|
|
||||||
resp.Status)
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoPollForStatusCodes returns a SendDecorator that polls if the http.Response contains one of the
|
|
||||||
// passed status codes. It expects the http.Response to contain a Location header providing the
|
|
||||||
// URL at which to poll (using GET) and will poll until the time passed is equal to or greater than
|
|
||||||
// the supplied duration. It will delay between requests for the duration specified in the
|
|
||||||
// RetryAfter header or, if the header is absent, the passed delay. Polling may be canceled by
|
|
||||||
// closing the optional channel on the http.Request.
|
|
||||||
func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ...int) SendDecorator {
|
|
||||||
return func(s Sender) Sender {
|
|
||||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
|
||||||
resp, err = s.Do(r)
|
|
||||||
|
|
||||||
if err == nil && ResponseHasStatusCode(resp, codes...) {
|
|
||||||
r, err = NewPollingRequestWithContext(r.Context(), resp)
|
|
||||||
|
|
||||||
for err == nil && ResponseHasStatusCode(resp, codes...) {
|
|
||||||
Respond(resp,
|
|
||||||
ByDiscardingBody(),
|
|
||||||
ByClosing())
|
|
||||||
resp, err = SendWithSender(s, r,
|
|
||||||
AfterDelay(GetRetryAfter(resp, delay)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoRetryForAttempts returns a SendDecorator that retries a failed request for up to the specified
|
|
||||||
// number of attempts, exponentially backing off between requests using the supplied backoff
|
|
||||||
// time.Duration (which may be zero). Retrying may be canceled by closing the optional channel on
|
|
||||||
// the http.Request.
|
|
||||||
func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator {
|
|
||||||
return func(s Sender) Sender {
|
|
||||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
|
||||||
rr := NewRetriableRequest(r)
|
|
||||||
for attempt := 0; attempt < attempts; attempt++ {
|
|
||||||
err = rr.Prepare()
|
|
||||||
if err != nil {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
DrainResponseBody(resp)
|
|
||||||
resp, err = s.Do(rr.Request())
|
|
||||||
if err == nil {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
if !DelayForBackoff(backoff, attempt, r.Context().Done()) {
|
|
||||||
return nil, r.Context().Err()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count429AsRetry indicates that a 429 response should be included as a retry attempt.
|
|
||||||
var Count429AsRetry = true
|
|
||||||
|
|
||||||
// Max429Delay is the maximum duration to wait between retries on a 429 if no Retry-After header was received.
|
|
||||||
var Max429Delay time.Duration
|
|
||||||
|
|
||||||
// DoRetryForStatusCodes returns a SendDecorator that retries for specified statusCodes for up to the specified
|
|
||||||
// number of attempts, exponentially backing off between requests using the supplied backoff
|
|
||||||
// time.Duration (which may be zero). Retrying may be canceled by cancelling the context on the http.Request.
|
|
||||||
// NOTE: Code http.StatusTooManyRequests (429) will *not* be counted against the number of attempts.
|
|
||||||
func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) SendDecorator {
|
|
||||||
return func(s Sender) Sender {
|
|
||||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
|
||||||
return doRetryForStatusCodesImpl(s, r, Count429AsRetry, attempts, backoff, 0, codes...)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoRetryForStatusCodesWithCap returns a SendDecorator that retries for specified statusCodes for up to the
|
|
||||||
// specified number of attempts, exponentially backing off between requests using the supplied backoff
|
|
||||||
// time.Duration (which may be zero). To cap the maximum possible delay between iterations specify a value greater
|
|
||||||
// than zero for cap. Retrying may be canceled by cancelling the context on the http.Request.
|
|
||||||
func DoRetryForStatusCodesWithCap(attempts int, backoff, cap time.Duration, codes ...int) SendDecorator {
|
|
||||||
return func(s Sender) Sender {
|
|
||||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
|
||||||
return doRetryForStatusCodesImpl(s, r, Count429AsRetry, attempts, backoff, cap, codes...)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func doRetryForStatusCodesImpl(s Sender, r *http.Request, count429 bool, attempts int, backoff, cap time.Duration, codes ...int) (resp *http.Response, err error) {
|
|
||||||
rr := NewRetriableRequest(r)
|
|
||||||
// Increment to add the first call (attempts denotes number of retries)
|
|
||||||
for attempt, delayCount := 0, 0; attempt < attempts+1; {
|
|
||||||
err = rr.Prepare()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
DrainResponseBody(resp)
|
|
||||||
resp, err = s.Do(rr.Request())
|
|
||||||
// we want to retry if err is not nil (e.g. transient network failure). note that for failed authentication
|
|
||||||
// resp and err will both have a value, so in this case we don't want to retry as it will never succeed.
|
|
||||||
if err == nil && !ResponseHasStatusCode(resp, codes...) || IsTokenRefreshError(err) {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
delayed := DelayWithRetryAfter(resp, r.Context().Done())
|
|
||||||
// if this was a 429 set the delay cap as specified.
|
|
||||||
// applicable only in the absence of a retry-after header.
|
|
||||||
if resp != nil && resp.StatusCode == http.StatusTooManyRequests {
|
|
||||||
cap = Max429Delay
|
|
||||||
}
|
|
||||||
if !delayed && !DelayForBackoffWithCap(backoff, cap, delayCount, r.Context().Done()) {
|
|
||||||
return resp, r.Context().Err()
|
|
||||||
}
|
|
||||||
// when count429 == false don't count a 429 against the number
|
|
||||||
// of attempts so that we continue to retry until it succeeds
|
|
||||||
if count429 || (resp == nil || resp.StatusCode != http.StatusTooManyRequests) {
|
|
||||||
attempt++
|
|
||||||
}
|
|
||||||
// delay count is tracked separately from attempts to
|
|
||||||
// ensure that 429 participates in exponential back-off
|
|
||||||
delayCount++
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// DelayWithRetryAfter invokes time.After for the duration specified in the "Retry-After" header.
|
|
||||||
// The value of Retry-After can be either the number of seconds or a date in RFC1123 format.
|
|
||||||
// The function returns true after successfully waiting for the specified duration. If there is
|
|
||||||
// no Retry-After header or the wait is cancelled the return value is false.
|
|
||||||
func DelayWithRetryAfter(resp *http.Response, cancel <-chan struct{}) bool {
|
|
||||||
if resp == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
var dur time.Duration
|
|
||||||
ra := resp.Header.Get("Retry-After")
|
|
||||||
if retryAfter, _ := strconv.Atoi(ra); retryAfter > 0 {
|
|
||||||
dur = time.Duration(retryAfter) * time.Second
|
|
||||||
} else if t, err := time.Parse(time.RFC1123, ra); err == nil {
|
|
||||||
dur = t.Sub(time.Now())
|
|
||||||
}
|
|
||||||
if dur > 0 {
|
|
||||||
select {
|
|
||||||
case <-time.After(dur):
|
|
||||||
return true
|
|
||||||
case <-cancel:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// DoRetryForDuration returns a SendDecorator that retries the request until the total time is equal
|
|
||||||
// to or greater than the specified duration, exponentially backing off between requests using the
|
|
||||||
// supplied backoff time.Duration (which may be zero). Retrying may be canceled by closing the
|
|
||||||
// optional channel on the http.Request.
|
|
||||||
func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator {
|
|
||||||
return func(s Sender) Sender {
|
|
||||||
return SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
|
||||||
rr := NewRetriableRequest(r)
|
|
||||||
end := time.Now().Add(d)
|
|
||||||
for attempt := 0; time.Now().Before(end); attempt++ {
|
|
||||||
err = rr.Prepare()
|
|
||||||
if err != nil {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
DrainResponseBody(resp)
|
|
||||||
resp, err = s.Do(rr.Request())
|
|
||||||
if err == nil {
|
|
||||||
return resp, err
|
|
||||||
}
|
|
||||||
if !DelayForBackoff(backoff, attempt, r.Context().Done()) {
|
|
||||||
return nil, r.Context().Err()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithLogging returns a SendDecorator that implements simple before and after logging of the
|
|
||||||
// request.
|
|
||||||
func WithLogging(logger *log.Logger) SendDecorator {
|
|
||||||
return func(s Sender) Sender {
|
|
||||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
|
||||||
logger.Printf("Sending %s %s", r.Method, r.URL)
|
|
||||||
resp, err := s.Do(r)
|
|
||||||
if err != nil {
|
|
||||||
logger.Printf("%s %s received error '%v'", r.Method, r.URL, err)
|
|
||||||
} else {
|
|
||||||
logger.Printf("%s %s received %s", r.Method, r.URL, resp.Status)
|
|
||||||
}
|
|
||||||
return resp, err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DelayForBackoff invokes time.After for the supplied backoff duration raised to the power of
|
|
||||||
// passed attempt (i.e., an exponential backoff delay). Backoff duration is in seconds and can set
|
|
||||||
// to zero for no delay. The delay may be canceled by closing the passed channel. If terminated early,
|
|
||||||
// returns false.
|
|
||||||
// Note: Passing attempt 1 will result in doubling "backoff" duration. Treat this as a zero-based attempt
|
|
||||||
// count.
|
|
||||||
func DelayForBackoff(backoff time.Duration, attempt int, cancel <-chan struct{}) bool {
|
|
||||||
return DelayForBackoffWithCap(backoff, 0, attempt, cancel)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DelayForBackoffWithCap invokes time.After for the supplied backoff duration raised to the power of
|
|
||||||
// passed attempt (i.e., an exponential backoff delay). Backoff duration is in seconds and can set
|
|
||||||
// to zero for no delay. To cap the maximum possible delay specify a value greater than zero for cap.
|
|
||||||
// The delay may be canceled by closing the passed channel. If terminated early, returns false.
|
|
||||||
// Note: Passing attempt 1 will result in doubling "backoff" duration. Treat this as a zero-based attempt
|
|
||||||
// count.
|
|
||||||
func DelayForBackoffWithCap(backoff, cap time.Duration, attempt int, cancel <-chan struct{}) bool {
|
|
||||||
d := time.Duration(backoff.Seconds()*math.Pow(2, float64(attempt))) * time.Second
|
|
||||||
if cap > 0 && d > cap {
|
|
||||||
d = cap
|
|
||||||
}
|
|
||||||
select {
|
|
||||||
case <-time.After(d):
|
|
||||||
return true
|
|
||||||
case <-cancel:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
232
vendor/github.com/Azure/go-autorest/autorest/utility.go
generated
vendored
232
vendor/github.com/Azure/go-autorest/autorest/utility.go
generated
vendored
@@ -1,232 +0,0 @@
|
|||||||
package autorest
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"encoding/xml"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// EncodedAs is a series of constants specifying various data encodings
|
|
||||||
type EncodedAs string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// EncodedAsJSON states that data is encoded as JSON
|
|
||||||
EncodedAsJSON EncodedAs = "JSON"
|
|
||||||
|
|
||||||
// EncodedAsXML states that data is encoded as Xml
|
|
||||||
EncodedAsXML EncodedAs = "XML"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Decoder defines the decoding method json.Decoder and xml.Decoder share
|
|
||||||
type Decoder interface {
|
|
||||||
Decode(v interface{}) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDecoder creates a new decoder appropriate to the passed encoding.
|
|
||||||
// encodedAs specifies the type of encoding and r supplies the io.Reader containing the
|
|
||||||
// encoded data.
|
|
||||||
func NewDecoder(encodedAs EncodedAs, r io.Reader) Decoder {
|
|
||||||
if encodedAs == EncodedAsJSON {
|
|
||||||
return json.NewDecoder(r)
|
|
||||||
} else if encodedAs == EncodedAsXML {
|
|
||||||
return xml.NewDecoder(r)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyAndDecode decodes the data from the passed io.Reader while making a copy. Having a copy
|
|
||||||
// is especially useful if there is a chance the data will fail to decode.
|
|
||||||
// encodedAs specifies the expected encoding, r provides the io.Reader to the data, and v
|
|
||||||
// is the decoding destination.
|
|
||||||
func CopyAndDecode(encodedAs EncodedAs, r io.Reader, v interface{}) (bytes.Buffer, error) {
|
|
||||||
b := bytes.Buffer{}
|
|
||||||
return b, NewDecoder(encodedAs, io.TeeReader(r, &b)).Decode(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TeeReadCloser returns a ReadCloser that writes to w what it reads from rc.
|
|
||||||
// It utilizes io.TeeReader to copy the data read and has the same behavior when reading.
|
|
||||||
// Further, when it is closed, it ensures that rc is closed as well.
|
|
||||||
func TeeReadCloser(rc io.ReadCloser, w io.Writer) io.ReadCloser {
|
|
||||||
return &teeReadCloser{rc, io.TeeReader(rc, w)}
|
|
||||||
}
|
|
||||||
|
|
||||||
type teeReadCloser struct {
|
|
||||||
rc io.ReadCloser
|
|
||||||
r io.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *teeReadCloser) Read(p []byte) (int, error) {
|
|
||||||
return t.r.Read(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *teeReadCloser) Close() error {
|
|
||||||
return t.rc.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
func containsInt(ints []int, n int) bool {
|
|
||||||
for _, i := range ints {
|
|
||||||
if i == n {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func escapeValueStrings(m map[string]string) map[string]string {
|
|
||||||
for key, value := range m {
|
|
||||||
m[key] = url.QueryEscape(value)
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func ensureValueStrings(mapOfInterface map[string]interface{}) map[string]string {
|
|
||||||
mapOfStrings := make(map[string]string)
|
|
||||||
for key, value := range mapOfInterface {
|
|
||||||
mapOfStrings[key] = ensureValueString(value)
|
|
||||||
}
|
|
||||||
return mapOfStrings
|
|
||||||
}
|
|
||||||
|
|
||||||
func ensureValueString(value interface{}) string {
|
|
||||||
if value == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
switch v := value.(type) {
|
|
||||||
case string:
|
|
||||||
return v
|
|
||||||
case []byte:
|
|
||||||
return string(v)
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("%v", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MapToValues method converts map[string]interface{} to url.Values.
|
|
||||||
func MapToValues(m map[string]interface{}) url.Values {
|
|
||||||
v := url.Values{}
|
|
||||||
for key, value := range m {
|
|
||||||
x := reflect.ValueOf(value)
|
|
||||||
if x.Kind() == reflect.Array || x.Kind() == reflect.Slice {
|
|
||||||
for i := 0; i < x.Len(); i++ {
|
|
||||||
v.Add(key, ensureValueString(x.Index(i)))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v.Add(key, ensureValueString(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsStringSlice method converts interface{} to []string.
|
|
||||||
// s must be of type slice or array or an error is returned.
|
|
||||||
// Each element of s will be converted to its string representation.
|
|
||||||
func AsStringSlice(s interface{}) ([]string, error) {
|
|
||||||
v := reflect.ValueOf(s)
|
|
||||||
if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
|
|
||||||
return nil, NewError("autorest", "AsStringSlice", "the value's type is not a slice or array.")
|
|
||||||
}
|
|
||||||
stringSlice := make([]string, 0, v.Len())
|
|
||||||
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
|
||||||
stringSlice = append(stringSlice, fmt.Sprintf("%v", v.Index(i)))
|
|
||||||
}
|
|
||||||
return stringSlice, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// String method converts interface v to string. If interface is a list, it
|
|
||||||
// joins list elements using the separator. Note that only sep[0] will be used for
|
|
||||||
// joining if any separator is specified.
|
|
||||||
func String(v interface{}, sep ...string) string {
|
|
||||||
if len(sep) == 0 {
|
|
||||||
return ensureValueString(v)
|
|
||||||
}
|
|
||||||
stringSlice, ok := v.([]string)
|
|
||||||
if ok == false {
|
|
||||||
var err error
|
|
||||||
stringSlice, err = AsStringSlice(v)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("autorest: Couldn't convert value to a string %s.", err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ensureValueString(strings.Join(stringSlice, sep[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode method encodes url path and query parameters.
|
|
||||||
func Encode(location string, v interface{}, sep ...string) string {
|
|
||||||
s := String(v, sep...)
|
|
||||||
switch strings.ToLower(location) {
|
|
||||||
case "path":
|
|
||||||
return pathEscape(s)
|
|
||||||
case "query":
|
|
||||||
return queryEscape(s)
|
|
||||||
default:
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func pathEscape(s string) string {
|
|
||||||
return strings.Replace(url.QueryEscape(s), "+", "%20", -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func queryEscape(s string) string {
|
|
||||||
return url.QueryEscape(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChangeToGet turns the specified http.Request into a GET (it assumes it wasn't).
|
|
||||||
// This is mainly useful for long-running operations that use the Azure-AsyncOperation
|
|
||||||
// header, so we change the initial PUT into a GET to retrieve the final result.
|
|
||||||
func ChangeToGet(req *http.Request) *http.Request {
|
|
||||||
req.Method = "GET"
|
|
||||||
req.Body = nil
|
|
||||||
req.ContentLength = 0
|
|
||||||
req.Header.Del("Content-Length")
|
|
||||||
return req
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTemporaryNetworkError returns true if the specified error is a temporary network error or false
|
|
||||||
// if it's not. If the error doesn't implement the net.Error interface the return value is true.
|
|
||||||
func IsTemporaryNetworkError(err error) bool {
|
|
||||||
if netErr, ok := err.(net.Error); !ok || (ok && netErr.Temporary()) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// DrainResponseBody reads the response body then closes it.
|
|
||||||
func DrainResponseBody(resp *http.Response) error {
|
|
||||||
if resp != nil && resp.Body != nil {
|
|
||||||
_, err := io.Copy(ioutil.Discard, resp.Body)
|
|
||||||
resp.Body.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setHeader(r *http.Request, key, value string) {
|
|
||||||
if r.Header == nil {
|
|
||||||
r.Header = make(http.Header)
|
|
||||||
}
|
|
||||||
r.Header.Set(key, value)
|
|
||||||
}
|
|
||||||
29
vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go
generated
vendored
29
vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go
generated
vendored
@@ -1,29 +0,0 @@
|
|||||||
// +build go1.13
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
package autorest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/Azure/go-autorest/autorest/adal"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError interface.
|
|
||||||
func IsTokenRefreshError(err error) bool {
|
|
||||||
var tre adal.TokenRefreshError
|
|
||||||
return errors.As(err, &tre)
|
|
||||||
}
|
|
||||||
31
vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go
generated
vendored
31
vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go
generated
vendored
@@ -1,31 +0,0 @@
|
|||||||
// +build !go1.13
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
package autorest
|
|
||||||
|
|
||||||
import "github.com/Azure/go-autorest/autorest/adal"
|
|
||||||
|
|
||||||
// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError
|
|
||||||
// interface. If err is a DetailedError it will walk the chain of Original errors.
|
|
||||||
func IsTokenRefreshError(err error) bool {
|
|
||||||
if _, ok := err.(adal.TokenRefreshError); ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if de, ok := err.(DetailedError); ok {
|
|
||||||
return IsTokenRefreshError(de.Original)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
41
vendor/github.com/Azure/go-autorest/autorest/version.go
generated
vendored
41
vendor/github.com/Azure/go-autorest/autorest/version.go
generated
vendored
@@ -1,41 +0,0 @@
|
|||||||
package autorest
|
|
||||||
|
|
||||||
// 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"
|
|
||||||
"runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
const number = "v14.2.1"
|
|
||||||
|
|
||||||
var (
|
|
||||||
userAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s",
|
|
||||||
runtime.Version(),
|
|
||||||
runtime.GOARCH,
|
|
||||||
runtime.GOOS,
|
|
||||||
number,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
// UserAgent returns a string containing the Go version, system architecture and OS, and the go-autorest version.
|
|
||||||
func UserAgent() string {
|
|
||||||
return userAgent
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version returns the semantic version (see http://semver.org).
|
|
||||||
func Version() string {
|
|
||||||
return number
|
|
||||||
}
|
|
||||||
105
vendor/github.com/Azure/go-autorest/azure-pipelines.yml
generated
vendored
105
vendor/github.com/Azure/go-autorest/azure-pipelines.yml
generated
vendored
@@ -1,105 +0,0 @@
|
|||||||
variables:
|
|
||||||
GOPATH: '$(system.defaultWorkingDirectory)/work'
|
|
||||||
sdkPath: '$(GOPATH)/src/github.com/$(build.repository.name)'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
- job: 'goautorest'
|
|
||||||
displayName: 'Run go-autorest CI Checks'
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
Linux_Go113:
|
|
||||||
vm.image: 'ubuntu-18.04'
|
|
||||||
go.version: '1.13'
|
|
||||||
Linux_Go114:
|
|
||||||
vm.image: 'ubuntu-18.04'
|
|
||||||
go.version: '1.14'
|
|
||||||
|
|
||||||
pool:
|
|
||||||
vmImage: '$(vm.image)'
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- task: GoTool@0
|
|
||||||
inputs:
|
|
||||||
version: '$(go.version)'
|
|
||||||
displayName: "Select Go Version"
|
|
||||||
|
|
||||||
- script: |
|
|
||||||
set -e
|
|
||||||
mkdir -p '$(GOPATH)/bin'
|
|
||||||
mkdir -p '$(sdkPath)'
|
|
||||||
shopt -s extglob
|
|
||||||
mv !(work) '$(sdkPath)'
|
|
||||||
echo '##vso[task.prependpath]$(GOPATH)/bin'
|
|
||||||
displayName: 'Create Go Workspace'
|
|
||||||
|
|
||||||
- script: |
|
|
||||||
set -e
|
|
||||||
curl -sSL https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
|
||||||
dep ensure -v
|
|
||||||
go install ./vendor/golang.org/x/lint/golint
|
|
||||||
go get github.com/jstemmer/go-junit-report
|
|
||||||
go get github.com/axw/gocov/gocov
|
|
||||||
go get github.com/AlekSi/gocov-xml
|
|
||||||
go get -u github.com/matm/gocov-html
|
|
||||||
workingDirectory: '$(sdkPath)'
|
|
||||||
displayName: 'Install Dependencies'
|
|
||||||
|
|
||||||
- script: |
|
|
||||||
go vet ./autorest/...
|
|
||||||
go vet ./logger/...
|
|
||||||
go vet ./tracing/...
|
|
||||||
workingDirectory: '$(sdkPath)'
|
|
||||||
displayName: 'Vet'
|
|
||||||
|
|
||||||
- script: |
|
|
||||||
go build -v ./autorest/...
|
|
||||||
go build -v ./logger/...
|
|
||||||
go build -v ./tracing/...
|
|
||||||
workingDirectory: '$(sdkPath)'
|
|
||||||
displayName: 'Build'
|
|
||||||
|
|
||||||
- script: |
|
|
||||||
set -e
|
|
||||||
go test -race -v -coverprofile=coverage.txt -covermode atomic ./autorest/... ./logger/... ./tracing/... 2>&1 | go-junit-report > report.xml
|
|
||||||
gocov convert coverage.txt > coverage.json
|
|
||||||
gocov-xml < coverage.json > coverage.xml
|
|
||||||
gocov-html < coverage.json > coverage.html
|
|
||||||
workingDirectory: '$(sdkPath)'
|
|
||||||
displayName: 'Run Tests'
|
|
||||||
|
|
||||||
- script: grep -L -r --include *.go --exclude-dir vendor -P "Copyright (\d{4}|\(c\)) Microsoft" ./ | tee >&2
|
|
||||||
workingDirectory: '$(sdkPath)'
|
|
||||||
displayName: 'Copyright Header Check'
|
|
||||||
failOnStderr: true
|
|
||||||
condition: succeededOrFailed()
|
|
||||||
|
|
||||||
- script: |
|
|
||||||
gofmt -s -l -w ./autorest/. >&2
|
|
||||||
gofmt -s -l -w ./logger/. >&2
|
|
||||||
gofmt -s -l -w ./tracing/. >&2
|
|
||||||
workingDirectory: '$(sdkPath)'
|
|
||||||
displayName: 'Format Check'
|
|
||||||
failOnStderr: true
|
|
||||||
condition: succeededOrFailed()
|
|
||||||
|
|
||||||
- script: |
|
|
||||||
golint ./autorest/... >&2
|
|
||||||
golint ./logger/... >&2
|
|
||||||
golint ./tracing/... >&2
|
|
||||||
workingDirectory: '$(sdkPath)'
|
|
||||||
displayName: 'Linter Check'
|
|
||||||
failOnStderr: true
|
|
||||||
condition: succeededOrFailed()
|
|
||||||
|
|
||||||
- task: PublishTestResults@2
|
|
||||||
inputs:
|
|
||||||
testRunner: JUnit
|
|
||||||
testResultsFiles: $(sdkPath)/report.xml
|
|
||||||
failTaskOnFailedTests: true
|
|
||||||
|
|
||||||
- task: PublishCodeCoverageResults@1
|
|
||||||
inputs:
|
|
||||||
codeCoverageTool: Cobertura
|
|
||||||
summaryFileLocation: $(sdkPath)/coverage.xml
|
|
||||||
additionalCodeCoverageFiles: $(sdkPath)/coverage.html
|
|
||||||
18
vendor/github.com/Azure/go-autorest/doc.go
generated
vendored
18
vendor/github.com/Azure/go-autorest/doc.go
generated
vendored
@@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
Package go-autorest provides an HTTP request client for use with Autorest-generated API client packages.
|
|
||||||
*/
|
|
||||||
package go_autorest
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
191
vendor/github.com/Azure/go-autorest/logger/LICENSE
generated
vendored
191
vendor/github.com/Azure/go-autorest/logger/LICENSE
generated
vendored
@@ -1,191 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
Copyright 2015 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.
|
|
||||||
24
vendor/github.com/Azure/go-autorest/logger/go_mod_tidy_hack.go
generated
vendored
24
vendor/github.com/Azure/go-autorest/logger/go_mod_tidy_hack.go
generated
vendored
@@ -1,24 +0,0 @@
|
|||||||
// +build modhack
|
|
||||||
|
|
||||||
package logger
|
|
||||||
|
|
||||||
// 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 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"
|
|
||||||
337
vendor/github.com/Azure/go-autorest/logger/logger.go
generated
vendored
337
vendor/github.com/Azure/go-autorest/logger/logger.go
generated
vendored
@@ -1,337 +0,0 @@
|
|||||||
package logger
|
|
||||||
|
|
||||||
// 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 (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LevelType tells a logger the minimum level to log. When code reports a log entry,
|
|
||||||
// the LogLevel indicates the level of the log entry. The logger only records entries
|
|
||||||
// whose level is at least the level it was told to log. See the Log* constants.
|
|
||||||
// For example, if a logger is configured with LogError, then LogError, LogPanic,
|
|
||||||
// and LogFatal entries will be logged; lower level entries are ignored.
|
|
||||||
type LevelType uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// LogNone tells a logger not to log any entries passed to it.
|
|
||||||
LogNone LevelType = iota
|
|
||||||
|
|
||||||
// LogFatal tells a logger to log all LogFatal entries passed to it.
|
|
||||||
LogFatal
|
|
||||||
|
|
||||||
// LogPanic tells a logger to log all LogPanic and LogFatal entries passed to it.
|
|
||||||
LogPanic
|
|
||||||
|
|
||||||
// LogError tells a logger to log all LogError, LogPanic and LogFatal entries passed to it.
|
|
||||||
LogError
|
|
||||||
|
|
||||||
// LogWarning tells a logger to log all LogWarning, LogError, LogPanic and LogFatal entries passed to it.
|
|
||||||
LogWarning
|
|
||||||
|
|
||||||
// LogInfo tells a logger to log all LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it.
|
|
||||||
LogInfo
|
|
||||||
|
|
||||||
// LogDebug tells a logger to log all LogDebug, LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it.
|
|
||||||
LogDebug
|
|
||||||
|
|
||||||
// LogAuth is a special case of LogDebug, it tells a logger to also log the body of an authentication request and response.
|
|
||||||
// NOTE: this can disclose sensitive information, use with care.
|
|
||||||
LogAuth
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
logNone = "NONE"
|
|
||||||
logFatal = "FATAL"
|
|
||||||
logPanic = "PANIC"
|
|
||||||
logError = "ERROR"
|
|
||||||
logWarning = "WARNING"
|
|
||||||
logInfo = "INFO"
|
|
||||||
logDebug = "DEBUG"
|
|
||||||
logAuth = "AUTH"
|
|
||||||
logUnknown = "UNKNOWN"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ParseLevel converts the specified string into the corresponding LevelType.
|
|
||||||
func ParseLevel(s string) (lt LevelType, err error) {
|
|
||||||
switch strings.ToUpper(s) {
|
|
||||||
case logFatal:
|
|
||||||
lt = LogFatal
|
|
||||||
case logPanic:
|
|
||||||
lt = LogPanic
|
|
||||||
case logError:
|
|
||||||
lt = LogError
|
|
||||||
case logWarning:
|
|
||||||
lt = LogWarning
|
|
||||||
case logInfo:
|
|
||||||
lt = LogInfo
|
|
||||||
case logDebug:
|
|
||||||
lt = LogDebug
|
|
||||||
case logAuth:
|
|
||||||
lt = LogAuth
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("bad log level '%s'", s)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// String implements the stringer interface for LevelType.
|
|
||||||
func (lt LevelType) String() string {
|
|
||||||
switch lt {
|
|
||||||
case LogNone:
|
|
||||||
return logNone
|
|
||||||
case LogFatal:
|
|
||||||
return logFatal
|
|
||||||
case LogPanic:
|
|
||||||
return logPanic
|
|
||||||
case LogError:
|
|
||||||
return logError
|
|
||||||
case LogWarning:
|
|
||||||
return logWarning
|
|
||||||
case LogInfo:
|
|
||||||
return logInfo
|
|
||||||
case LogDebug:
|
|
||||||
return logDebug
|
|
||||||
case LogAuth:
|
|
||||||
return logAuth
|
|
||||||
default:
|
|
||||||
return logUnknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter defines functions for filtering HTTP request/response content.
|
|
||||||
type Filter struct {
|
|
||||||
// URL returns a potentially modified string representation of a request URL.
|
|
||||||
URL func(u *url.URL) string
|
|
||||||
|
|
||||||
// Header returns a potentially modified set of values for the specified key.
|
|
||||||
// To completely exclude the header key/values return false.
|
|
||||||
Header func(key string, val []string) (bool, []string)
|
|
||||||
|
|
||||||
// Body returns a potentially modified request/response body.
|
|
||||||
Body func(b []byte) []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f Filter) processURL(u *url.URL) string {
|
|
||||||
if f.URL == nil {
|
|
||||||
return u.String()
|
|
||||||
}
|
|
||||||
return f.URL(u)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f Filter) processHeader(k string, val []string) (bool, []string) {
|
|
||||||
if f.Header == nil {
|
|
||||||
return true, val
|
|
||||||
}
|
|
||||||
return f.Header(k, val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f Filter) processBody(b []byte) []byte {
|
|
||||||
if f.Body == nil {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
return f.Body(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Writer defines methods for writing to a logging facility.
|
|
||||||
type Writer interface {
|
|
||||||
// Writeln writes the specified message with the standard log entry header and new-line character.
|
|
||||||
Writeln(level LevelType, message string)
|
|
||||||
|
|
||||||
// Writef writes the specified format specifier with the standard log entry header and no new-line character.
|
|
||||||
Writef(level LevelType, format string, a ...interface{})
|
|
||||||
|
|
||||||
// WriteRequest writes the specified HTTP request to the logger if the log level is greater than
|
|
||||||
// or equal to LogInfo. The request body, if set, is logged at level LogDebug or higher.
|
|
||||||
// Custom filters can be specified to exclude URL, header, and/or body content from the log.
|
|
||||||
// By default no request content is excluded.
|
|
||||||
WriteRequest(req *http.Request, filter Filter)
|
|
||||||
|
|
||||||
// WriteResponse writes the specified HTTP response to the logger if the log level is greater than
|
|
||||||
// or equal to LogInfo. The response body, if set, is logged at level LogDebug or higher.
|
|
||||||
// Custom filters can be specified to exclude URL, header, and/or body content from the log.
|
|
||||||
// By default no response content is excluded.
|
|
||||||
WriteResponse(resp *http.Response, filter Filter)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instance is the default log writer initialized during package init.
|
|
||||||
// This can be replaced with a custom implementation as required.
|
|
||||||
var Instance Writer
|
|
||||||
|
|
||||||
// default log level
|
|
||||||
var logLevel = LogNone
|
|
||||||
|
|
||||||
// Level returns the value specified in AZURE_GO_AUTOREST_LOG_LEVEL.
|
|
||||||
// If no value was specified the default value is LogNone.
|
|
||||||
// Custom loggers can call this to retrieve the configured log level.
|
|
||||||
func Level() LevelType {
|
|
||||||
return logLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// separated for testing purposes
|
|
||||||
initDefaultLogger()
|
|
||||||
}
|
|
||||||
|
|
||||||
func initDefaultLogger() {
|
|
||||||
// init with nilLogger so callers don't have to do a nil check on Default
|
|
||||||
Instance = nilLogger{}
|
|
||||||
llStr := strings.ToLower(os.Getenv("AZURE_GO_SDK_LOG_LEVEL"))
|
|
||||||
if llStr == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
logLevel, err = ParseLevel(llStr)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "go-autorest: failed to parse log level: %s\n", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if logLevel == LogNone {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// default to stderr
|
|
||||||
dest := os.Stderr
|
|
||||||
lfStr := os.Getenv("AZURE_GO_SDK_LOG_FILE")
|
|
||||||
if strings.EqualFold(lfStr, "stdout") {
|
|
||||||
dest = os.Stdout
|
|
||||||
} else if lfStr != "" {
|
|
||||||
lf, err := os.Create(lfStr)
|
|
||||||
if err == nil {
|
|
||||||
dest = lf
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(os.Stderr, "go-autorest: failed to create log file, using stderr: %s\n", err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Instance = fileLogger{
|
|
||||||
logLevel: logLevel,
|
|
||||||
mu: &sync.Mutex{},
|
|
||||||
logFile: dest,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the nil logger does nothing
|
|
||||||
type nilLogger struct{}
|
|
||||||
|
|
||||||
func (nilLogger) Writeln(LevelType, string) {}
|
|
||||||
|
|
||||||
func (nilLogger) Writef(LevelType, string, ...interface{}) {}
|
|
||||||
|
|
||||||
func (nilLogger) WriteRequest(*http.Request, Filter) {}
|
|
||||||
|
|
||||||
func (nilLogger) WriteResponse(*http.Response, Filter) {}
|
|
||||||
|
|
||||||
// A File is used instead of a Logger so the stream can be flushed after every write.
|
|
||||||
type fileLogger struct {
|
|
||||||
logLevel LevelType
|
|
||||||
mu *sync.Mutex // for synchronizing writes to logFile
|
|
||||||
logFile *os.File
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fl fileLogger) Writeln(level LevelType, message string) {
|
|
||||||
fl.Writef(level, "%s\n", message)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fl fileLogger) Writef(level LevelType, format string, a ...interface{}) {
|
|
||||||
if fl.logLevel >= level {
|
|
||||||
fl.mu.Lock()
|
|
||||||
defer fl.mu.Unlock()
|
|
||||||
fmt.Fprintf(fl.logFile, "%s %s", entryHeader(level), fmt.Sprintf(format, a...))
|
|
||||||
fl.logFile.Sync()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fl fileLogger) WriteRequest(req *http.Request, filter Filter) {
|
|
||||||
if req == nil || fl.logLevel < LogInfo {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
fmt.Fprintf(b, "%s REQUEST: %s %s\n", entryHeader(LogInfo), req.Method, filter.processURL(req.URL))
|
|
||||||
// dump headers
|
|
||||||
for k, v := range req.Header {
|
|
||||||
if ok, mv := filter.processHeader(k, v); ok {
|
|
||||||
fmt.Fprintf(b, "%s: %s\n", k, strings.Join(mv, ","))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if fl.shouldLogBody(req.Header, req.Body) {
|
|
||||||
// dump body
|
|
||||||
body, err := ioutil.ReadAll(req.Body)
|
|
||||||
if err == nil {
|
|
||||||
fmt.Fprintln(b, string(filter.processBody(body)))
|
|
||||||
if nc, ok := req.Body.(io.Seeker); ok {
|
|
||||||
// rewind to the beginning
|
|
||||||
nc.Seek(0, io.SeekStart)
|
|
||||||
} else {
|
|
||||||
// recreate the body
|
|
||||||
req.Body = ioutil.NopCloser(bytes.NewReader(body))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(b, "failed to read body: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fl.mu.Lock()
|
|
||||||
defer fl.mu.Unlock()
|
|
||||||
fmt.Fprint(fl.logFile, b.String())
|
|
||||||
fl.logFile.Sync()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fl fileLogger) WriteResponse(resp *http.Response, filter Filter) {
|
|
||||||
if resp == nil || fl.logLevel < LogInfo {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
fmt.Fprintf(b, "%s RESPONSE: %d %s\n", entryHeader(LogInfo), resp.StatusCode, filter.processURL(resp.Request.URL))
|
|
||||||
// dump headers
|
|
||||||
for k, v := range resp.Header {
|
|
||||||
if ok, mv := filter.processHeader(k, v); ok {
|
|
||||||
fmt.Fprintf(b, "%s: %s\n", k, strings.Join(mv, ","))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if fl.shouldLogBody(resp.Header, resp.Body) {
|
|
||||||
// dump body
|
|
||||||
defer resp.Body.Close()
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err == nil {
|
|
||||||
fmt.Fprintln(b, string(filter.processBody(body)))
|
|
||||||
resp.Body = ioutil.NopCloser(bytes.NewReader(body))
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(b, "failed to read body: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fl.mu.Lock()
|
|
||||||
defer fl.mu.Unlock()
|
|
||||||
fmt.Fprint(fl.logFile, b.String())
|
|
||||||
fl.logFile.Sync()
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns true if the provided body should be included in the log
|
|
||||||
func (fl fileLogger) shouldLogBody(header http.Header, body io.ReadCloser) bool {
|
|
||||||
ct := header.Get("Content-Type")
|
|
||||||
return fl.logLevel >= LogDebug && body != nil && !strings.Contains(ct, "application/octet-stream")
|
|
||||||
}
|
|
||||||
|
|
||||||
// creates standard header for log entries, it contains a timestamp and the log level
|
|
||||||
func entryHeader(level LevelType) string {
|
|
||||||
// this format provides a fixed number of digits so the size of the timestamp is constant
|
|
||||||
return fmt.Sprintf("(%s) %s:", time.Now().Format("2006-01-02T15:04:05.0000000Z07:00"), level.String())
|
|
||||||
}
|
|
||||||
191
vendor/github.com/Azure/go-autorest/tracing/LICENSE
generated
vendored
191
vendor/github.com/Azure/go-autorest/tracing/LICENSE
generated
vendored
@@ -1,191 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
Copyright 2015 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.
|
|
||||||
24
vendor/github.com/Azure/go-autorest/tracing/go_mod_tidy_hack.go
generated
vendored
24
vendor/github.com/Azure/go-autorest/tracing/go_mod_tidy_hack.go
generated
vendored
@@ -1,24 +0,0 @@
|
|||||||
// +build modhack
|
|
||||||
|
|
||||||
package tracing
|
|
||||||
|
|
||||||
// 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 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"
|
|
||||||
67
vendor/github.com/Azure/go-autorest/tracing/tracing.go
generated
vendored
67
vendor/github.com/Azure/go-autorest/tracing/tracing.go
generated
vendored
@@ -1,67 +0,0 @@
|
|||||||
package tracing
|
|
||||||
|
|
||||||
// Copyright 2018 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 (
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Tracer represents an HTTP tracing facility.
|
|
||||||
type Tracer interface {
|
|
||||||
NewTransport(base *http.Transport) http.RoundTripper
|
|
||||||
StartSpan(ctx context.Context, name string) context.Context
|
|
||||||
EndSpan(ctx context.Context, httpStatusCode int, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
tracer Tracer
|
|
||||||
)
|
|
||||||
|
|
||||||
// Register will register the provided Tracer. Pass nil to unregister a Tracer.
|
|
||||||
func Register(t Tracer) {
|
|
||||||
tracer = t
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsEnabled returns true if a Tracer has been registered.
|
|
||||||
func IsEnabled() bool {
|
|
||||||
return tracer != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewTransport creates a new instrumenting http.RoundTripper for the
|
|
||||||
// registered Tracer. If no Tracer has been registered it returns nil.
|
|
||||||
func NewTransport(base *http.Transport) http.RoundTripper {
|
|
||||||
if tracer != nil {
|
|
||||||
return tracer.NewTransport(base)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartSpan starts a trace span with the specified name, associating it with the
|
|
||||||
// provided context. Has no effect if a Tracer has not been registered.
|
|
||||||
func StartSpan(ctx context.Context, name string) context.Context {
|
|
||||||
if tracer != nil {
|
|
||||||
return tracer.StartSpan(ctx, name)
|
|
||||||
}
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
// EndSpan ends a previously started span stored in the context.
|
|
||||||
// Has no effect if a Tracer has not been registered.
|
|
||||||
func EndSpan(ctx context.Context, httpStatusCode int, err error) {
|
|
||||||
if tracer != nil {
|
|
||||||
tracer.EndSpan(ctx, httpStatusCode, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
6
vendor/github.com/emicklei/go-restful/.travis.yml
generated
vendored
6
vendor/github.com/emicklei/go-restful/.travis.yml
generated
vendored
@@ -1,6 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.x
|
|
||||||
|
|
||||||
script: go test -v
|
|
||||||
7
vendor/github.com/emicklei/go-restful/Makefile
generated
vendored
7
vendor/github.com/emicklei/go-restful/Makefile
generated
vendored
@@ -1,7 +0,0 @@
|
|||||||
all: test
|
|
||||||
|
|
||||||
test:
|
|
||||||
go test -v .
|
|
||||||
|
|
||||||
ex:
|
|
||||||
cd examples && ls *.go | xargs go build -o /tmp/ignore
|
|
||||||
@@ -68,3 +68,4 @@ examples/restful-html-template
|
|||||||
|
|
||||||
s.html
|
s.html
|
||||||
restful-path-tail
|
restful-path-tail
|
||||||
|
.idea
|
||||||
1
vendor/github.com/emicklei/go-restful/v3/.goconvey
generated
vendored
Normal file
1
vendor/github.com/emicklei/go-restful/v3/.goconvey
generated
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ignore
|
||||||
13
vendor/github.com/emicklei/go-restful/v3/.travis.yml
generated
vendored
Normal file
13
vendor/github.com/emicklei/go-restful/v3/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
language: go
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.x
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- go test -v
|
||||||
|
|
||||||
|
script:
|
||||||
|
- go test -race -coverprofile=coverage.txt -covermode=atomic
|
||||||
|
|
||||||
|
after_success:
|
||||||
|
- bash <(curl -s https://codecov.io/bash)
|
||||||
@@ -1,7 +1,106 @@
|
|||||||
## Change history of go-restful
|
# Change history of go-restful
|
||||||
|
|
||||||
|
## [v3.8.0] - 20221-06-06
|
||||||
|
|
||||||
|
- use exact matching of allowed domain entries, issue #489 (#493)
|
||||||
|
- this changes fixes [security] Authorization Bypass Through User-Controlled Key
|
||||||
|
by changing the behaviour of the AllowedDomains setting in the CORS filter.
|
||||||
|
To support the previous behaviour, the CORS filter type now has a AllowedDomainFunc
|
||||||
|
callback mechanism which is called when a simple domain match fails.
|
||||||
|
- add test and fix for POST without body and Content-type, issue #492 (#496)
|
||||||
|
- [Minor] Bad practice to have a mix of Receiver types. (#491)
|
||||||
|
|
||||||
|
## [v3.7.2] - 2021-11-24
|
||||||
|
|
||||||
|
- restored FilterChain (#482 by SVilgelm)
|
||||||
|
|
||||||
|
|
||||||
|
## [v3.7.1] - 2021-10-04
|
||||||
|
|
||||||
|
- fix problem with contentEncodingEnabled setting (#479)
|
||||||
|
|
||||||
|
## [v3.7.0] - 2021-09-24
|
||||||
|
|
||||||
|
- feat(parameter): adds additional openapi mappings (#478)
|
||||||
|
|
||||||
|
## [v3.6.0] - 2021-09-18
|
||||||
|
|
||||||
|
- add support for vendor extensions (#477 thx erraggy)
|
||||||
|
|
||||||
|
## [v3.5.2] - 2021-07-14
|
||||||
|
|
||||||
|
- fix removing absent route from webservice (#472)
|
||||||
|
|
||||||
|
## [v3.5.1] - 2021-04-12
|
||||||
|
|
||||||
|
- fix handling no match access selected path
|
||||||
|
- remove obsolete field
|
||||||
|
|
||||||
|
## [v3.5.0] - 2021-04-10
|
||||||
|
|
||||||
|
- add check for wildcard (#463) in CORS
|
||||||
|
- add access to Route from Request, issue #459 (#462)
|
||||||
|
|
||||||
|
## [v3.4.0] - 2020-11-10
|
||||||
|
|
||||||
|
- Added OPTIONS to WebService
|
||||||
|
|
||||||
|
## [v3.3.2] - 2020-01-23
|
||||||
|
|
||||||
|
- Fixed duplicate compression in dispatch. #449
|
||||||
|
|
||||||
|
|
||||||
|
## [v3.3.1] - 2020-08-31
|
||||||
|
|
||||||
|
- Added check on writer to prevent compression of response twice. #447
|
||||||
|
|
||||||
|
## [v3.3.0] - 2020-08-19
|
||||||
|
|
||||||
|
- Enable content encoding on Handle and ServeHTTP (#446)
|
||||||
|
- List available representations in 406 body (#437)
|
||||||
|
- Convert to string using rune() (#443)
|
||||||
|
|
||||||
|
## [v3.2.0] - 2020-06-21
|
||||||
|
|
||||||
|
- 405 Method Not Allowed must have Allow header (#436) (thx Bracken <abdawson@gmail.com>)
|
||||||
|
- add field allowedMethodsWithoutContentType (#424)
|
||||||
|
|
||||||
|
## [v3.1.0]
|
||||||
|
|
||||||
|
- support describing response headers (#426)
|
||||||
|
- fix openapi examples (#425)
|
||||||
|
|
||||||
|
v3.0.0
|
||||||
|
|
||||||
|
- fix: use request/response resulting from filter chain
|
||||||
|
- add Go module
|
||||||
|
Module consumer should use github.com/emicklei/go-restful/v3 as import path
|
||||||
|
|
||||||
|
v2.10.0
|
||||||
|
|
||||||
|
- support for Custom Verbs (thanks Vinci Xu <277040271@qq.com>)
|
||||||
|
- fixed static example (thanks Arthur <yang_yapo@126.com>)
|
||||||
|
- simplify code (thanks Christian Muehlhaeuser <muesli@gmail.com>)
|
||||||
|
- added JWT HMAC with SHA-512 authentication code example (thanks Amim Knabben <amim.knabben@gmail.com>)
|
||||||
|
|
||||||
|
v2.9.6
|
||||||
|
|
||||||
|
- small optimization in filter code
|
||||||
|
|
||||||
|
v2.11.1
|
||||||
|
|
||||||
|
- fix WriteError return value (#415)
|
||||||
|
|
||||||
|
v2.11.0
|
||||||
|
|
||||||
|
- allow prefix and suffix in path variable expression (#414)
|
||||||
|
|
||||||
|
v2.9.6
|
||||||
|
|
||||||
|
- support google custome verb (#413)
|
||||||
|
|
||||||
v2.9.5
|
v2.9.5
|
||||||
|
|
||||||
- fix panic in Response.WriteError if err == nil
|
- fix panic in Response.WriteError if err == nil
|
||||||
|
|
||||||
v2.9.4
|
v2.9.4
|
||||||
8
vendor/github.com/emicklei/go-restful/v3/Makefile
generated
vendored
Normal file
8
vendor/github.com/emicklei/go-restful/v3/Makefile
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
all: test
|
||||||
|
|
||||||
|
test:
|
||||||
|
go vet .
|
||||||
|
go test -cover -v .
|
||||||
|
|
||||||
|
ex:
|
||||||
|
find ./examples -type f -name "*.go" | xargs -I {} go build -o /tmp/ignore {}
|
||||||
@@ -4,9 +4,10 @@ package for building REST-style Web Services using Google Go
|
|||||||
|
|
||||||
[](https://travis-ci.org/emicklei/go-restful)
|
[](https://travis-ci.org/emicklei/go-restful)
|
||||||
[](https://goreportcard.com/report/github.com/emicklei/go-restful)
|
[](https://goreportcard.com/report/github.com/emicklei/go-restful)
|
||||||
[](https://godoc.org/github.com/emicklei/go-restful)
|
[](https://pkg.go.dev/github.com/emicklei/go-restful)
|
||||||
|
[](https://codecov.io/gh/emicklei/go-restful)
|
||||||
|
|
||||||
- [Code examples](https://github.com/emicklei/go-restful/tree/master/examples)
|
- [Code examples use v3](https://github.com/emicklei/go-restful/tree/v3/examples)
|
||||||
|
|
||||||
REST asks developers to use HTTP methods explicitly and in a way that's consistent with the protocol definition. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods. According to this mapping:
|
REST asks developers to use HTTP methods explicitly and in a way that's consistent with the protocol definition. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods. According to this mapping:
|
||||||
|
|
||||||
@@ -18,6 +19,28 @@ REST asks developers to use HTTP methods explicitly and in a way that's consiste
|
|||||||
- PATCH = Update partial content of a resource
|
- PATCH = Update partial content of a resource
|
||||||
- OPTIONS = Get information about the communication options for the request URI
|
- OPTIONS = Get information about the communication options for the request URI
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
#### Without Go Modules
|
||||||
|
|
||||||
|
All versions up to `v2.*.*` (on the master) are not supporting Go modules.
|
||||||
|
|
||||||
|
```
|
||||||
|
import (
|
||||||
|
restful "github.com/emicklei/go-restful"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Using Go Modules
|
||||||
|
|
||||||
|
As of version `v3.0.0` (on the v3 branch), this package supports Go modules.
|
||||||
|
|
||||||
|
```
|
||||||
|
import (
|
||||||
|
restful "github.com/emicklei/go-restful/v3"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
### Example
|
### Example
|
||||||
|
|
||||||
```Go
|
```Go
|
||||||
@@ -39,15 +62,15 @@ func (u UserResource) findUser(request *restful.Request, response *restful.Respo
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
[Full API of a UserResource](https://github.com/emicklei/go-restful/tree/master/examples/restful-user-resource.go)
|
[Full API of a UserResource](https://github.com/emicklei/go-restful/blob/v3/examples/user-resource/restful-user-resource.go)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
- Routes for request → function mapping with path parameter (e.g. {id}) support
|
- Routes for request → function mapping with path parameter (e.g. {id} but also prefix_{var} and {var}_suffix) support
|
||||||
- Configurable router:
|
- Configurable router:
|
||||||
- (default) Fast routing algorithm that allows static elements, regular expressions and dynamic parameters in the URL path (e.g. /meetings/{id} or /static/{subpath:*}
|
- (default) Fast routing algorithm that allows static elements, [google custom method](https://cloud.google.com/apis/design/custom_methods), regular expressions and dynamic parameters in the URL path (e.g. /resource/name:customVerb, /meetings/{id} or /static/{subpath:*})
|
||||||
- Routing algorithm after [JSR311](http://jsr311.java.net/nonav/releases/1.1/spec/spec.html) that is implemented using (but does **not** accept) regular expressions
|
- Routing algorithm after [JSR311](http://jsr311.java.net/nonav/releases/1.1/spec/spec.html) that is implemented using (but does **not** accept) regular expressions
|
||||||
- Request API for reading structs from JSON/XML and accesing parameters (path,query,header)
|
- Request API for reading structs from JSON/XML and accessing parameters (path,query,header)
|
||||||
- Response API for writing structs to JSON/XML and setting headers
|
- Response API for writing structs to JSON/XML and setting headers
|
||||||
- Customizable encoding using EntityReaderWriter registration
|
- Customizable encoding using EntityReaderWriter registration
|
||||||
- Filters for intercepting the request → response flow on Service or Route level
|
- Filters for intercepting the request → response flow on Service or Route level
|
||||||
@@ -71,12 +94,11 @@ There are several hooks to customize the behavior of the go-restful package.
|
|||||||
- Trace logging
|
- Trace logging
|
||||||
- Compression
|
- Compression
|
||||||
- Encoders for other serializers
|
- Encoders for other serializers
|
||||||
- Use [jsoniter](https://github.com/json-iterator/go) by build this package using a tag, e.g. `go build -tags=jsoniter .`
|
- Use [jsoniter](https://github.com/json-iterator/go) by build this package using a tag, e.g. `go build -tags=jsoniter .`
|
||||||
|
|
||||||
TODO: write examples of these.
|
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
|
|
||||||
|
- [Example programs](./examples)
|
||||||
- [Example posted on blog](http://ernestmicklei.com/2012/11/go-restful-first-working-example/)
|
- [Example posted on blog](http://ernestmicklei.com/2012/11/go-restful-first-working-example/)
|
||||||
- [Design explained on blog](http://ernestmicklei.com/2012/11/go-restful-api-design/)
|
- [Design explained on blog](http://ernestmicklei.com/2012/11/go-restful-api-design/)
|
||||||
- [sourcegraph](https://sourcegraph.com/github.com/emicklei/go-restful)
|
- [sourcegraph](https://sourcegraph.com/github.com/emicklei/go-restful)
|
||||||
@@ -85,4 +107,4 @@ TODO: write examples of these.
|
|||||||
|
|
||||||
Type ```git shortlog -s``` for a full list of contributors.
|
Type ```git shortlog -s``` for a full list of contributors.
|
||||||
|
|
||||||
© 2012 - 2018, http://ernestmicklei.com. MIT License. Contributions are welcome.
|
© 2012 - 2022, http://ernestmicklei.com. MIT License. Contributions are welcome.
|
||||||
13
vendor/github.com/emicklei/go-restful/v3/SECURITY.md
generated
vendored
Normal file
13
vendor/github.com/emicklei/go-restful/v3/SECURITY.md
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
| ------- | ------------------ |
|
||||||
|
| v3.7.x | :white_check_mark: |
|
||||||
|
| < v3.0.1 | :x: |
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
Create an Issue and put the label `[security]` in the title of the issue.
|
||||||
|
Valid reported security issues are expected to be solved within a week.
|
||||||
@@ -83,7 +83,11 @@ func (c *CompressingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WantsCompressedResponse reads the Accept-Encoding header to see if and which encoding is requested.
|
// WantsCompressedResponse reads the Accept-Encoding header to see if and which encoding is requested.
|
||||||
func wantsCompressedResponse(httpRequest *http.Request) (bool, string) {
|
// It also inspects the httpWriter whether its content-encoding is already set (non-empty).
|
||||||
|
func wantsCompressedResponse(httpRequest *http.Request, httpWriter http.ResponseWriter) (bool, string) {
|
||||||
|
if contentEncoding := httpWriter.Header().Get(HEADER_ContentEncoding); contentEncoding != "" {
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
header := httpRequest.Header.Get(HEADER_AcceptEncoding)
|
header := httpRequest.Header.Get(HEADER_AcceptEncoding)
|
||||||
gi := strings.Index(header, ENCODING_GZIP)
|
gi := strings.Index(header, ENCODING_GZIP)
|
||||||
zi := strings.Index(header, ENCODING_DEFLATE)
|
zi := strings.Index(header, ENCODING_DEFLATE)
|
||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/emicklei/go-restful/log"
|
"github.com/emicklei/go-restful/v3/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Container holds a collection of WebServices and a http.ServeMux to dispatch http requests.
|
// Container holds a collection of WebServices and a http.ServeMux to dispatch http requests.
|
||||||
@@ -185,6 +185,11 @@ func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter)
|
|||||||
// when a ServiceError is returned during route selection. Default implementation
|
// when a ServiceError is returned during route selection. Default implementation
|
||||||
// calls resp.WriteErrorString(err.Code, err.Message)
|
// calls resp.WriteErrorString(err.Code, err.Message)
|
||||||
func writeServiceError(err ServiceError, req *Request, resp *Response) {
|
func writeServiceError(err ServiceError, req *Request, resp *Response) {
|
||||||
|
for header, values := range err.Header {
|
||||||
|
for _, value := range values {
|
||||||
|
resp.Header().Add(header, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
resp.WriteErrorString(err.Code, err.Message)
|
resp.WriteErrorString(err.Code, err.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,6 +206,7 @@ func (c *Container) Dispatch(httpWriter http.ResponseWriter, httpRequest *http.R
|
|||||||
|
|
||||||
// Dispatch the incoming Http Request to a matching WebService.
|
// Dispatch the incoming Http Request to a matching WebService.
|
||||||
func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) {
|
func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) {
|
||||||
|
// so we can assign a compressing one later
|
||||||
writer := httpWriter
|
writer := httpWriter
|
||||||
|
|
||||||
// CompressingResponseWriter should be closed after all operations are done
|
// CompressingResponseWriter should be closed after all operations are done
|
||||||
@@ -231,28 +237,8 @@ func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.R
|
|||||||
c.webServices,
|
c.webServices,
|
||||||
httpRequest)
|
httpRequest)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Detect if compression is needed
|
|
||||||
// assume without compression, test for override
|
|
||||||
contentEncodingEnabled := c.contentEncodingEnabled
|
|
||||||
if route != nil && route.contentEncodingEnabled != nil {
|
|
||||||
contentEncodingEnabled = *route.contentEncodingEnabled
|
|
||||||
}
|
|
||||||
if contentEncodingEnabled {
|
|
||||||
doCompress, encoding := wantsCompressedResponse(httpRequest)
|
|
||||||
if doCompress {
|
|
||||||
var err error
|
|
||||||
writer, err = NewCompressingResponseWriter(httpWriter, encoding)
|
|
||||||
if err != nil {
|
|
||||||
log.Print("unable to install compressor: ", err)
|
|
||||||
httpWriter.WriteHeader(http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// a non-200 response has already been written
|
// a non-200 response (may be compressed) has already been written
|
||||||
// run container filters anyway ; they should not touch the response...
|
// run container filters anyway ; they should not touch the response...
|
||||||
chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) {
|
chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) {
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
@@ -265,6 +251,29 @@ func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.R
|
|||||||
chain.ProcessFilter(NewRequest(httpRequest), NewResponse(writer))
|
chain.ProcessFilter(NewRequest(httpRequest), NewResponse(writer))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unless httpWriter is already an CompressingResponseWriter see if we need to install one
|
||||||
|
if _, isCompressing := httpWriter.(*CompressingResponseWriter); !isCompressing {
|
||||||
|
// Detect if compression is needed
|
||||||
|
// assume without compression, test for override
|
||||||
|
contentEncodingEnabled := c.contentEncodingEnabled
|
||||||
|
if route != nil && route.contentEncodingEnabled != nil {
|
||||||
|
contentEncodingEnabled = *route.contentEncodingEnabled
|
||||||
|
}
|
||||||
|
if contentEncodingEnabled {
|
||||||
|
doCompress, encoding := wantsCompressedResponse(httpRequest, httpWriter)
|
||||||
|
if doCompress {
|
||||||
|
var err error
|
||||||
|
writer, err = NewCompressingResponseWriter(httpWriter, encoding)
|
||||||
|
if err != nil {
|
||||||
|
log.Print("unable to install compressor: ", err)
|
||||||
|
httpWriter.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pathProcessor, routerProcessesPath := c.router.(PathProcessor)
|
pathProcessor, routerProcessesPath := c.router.(PathProcessor)
|
||||||
if !routerProcessesPath {
|
if !routerProcessesPath {
|
||||||
pathProcessor = defaultPathProcessor{}
|
pathProcessor = defaultPathProcessor{}
|
||||||
@@ -272,16 +281,18 @@ func (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.R
|
|||||||
pathParams := pathProcessor.ExtractParameters(route, webService, httpRequest.URL.Path)
|
pathParams := pathProcessor.ExtractParameters(route, webService, httpRequest.URL.Path)
|
||||||
wrappedRequest, wrappedResponse := route.wrapRequestResponse(writer, httpRequest, pathParams)
|
wrappedRequest, wrappedResponse := route.wrapRequestResponse(writer, httpRequest, pathParams)
|
||||||
// pass through filters (if any)
|
// pass through filters (if any)
|
||||||
if len(c.containerFilters)+len(webService.filters)+len(route.Filters) > 0 {
|
if size := len(c.containerFilters) + len(webService.filters) + len(route.Filters); size > 0 {
|
||||||
// compose filter chain
|
// compose filter chain
|
||||||
allFilters := []FilterFunction{}
|
allFilters := make([]FilterFunction, 0, size)
|
||||||
allFilters = append(allFilters, c.containerFilters...)
|
allFilters = append(allFilters, c.containerFilters...)
|
||||||
allFilters = append(allFilters, webService.filters...)
|
allFilters = append(allFilters, webService.filters...)
|
||||||
allFilters = append(allFilters, route.Filters...)
|
allFilters = append(allFilters, route.Filters...)
|
||||||
chain := FilterChain{Filters: allFilters, Target: func(req *Request, resp *Response) {
|
chain := FilterChain{
|
||||||
// handle request by route after passing all filters
|
Filters: allFilters,
|
||||||
route.Function(wrappedRequest, wrappedResponse)
|
Target: route.Function,
|
||||||
}}
|
ParameterDocs: route.ParameterDocs,
|
||||||
|
Operation: route.Operation,
|
||||||
|
}
|
||||||
chain.ProcessFilter(wrappedRequest, wrappedResponse)
|
chain.ProcessFilter(wrappedRequest, wrappedResponse)
|
||||||
} else {
|
} else {
|
||||||
// no filters, handle request by route
|
// no filters, handle request by route
|
||||||
@@ -299,13 +310,75 @@ func fixedPrefixPath(pathspec string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ServeHTTP implements net/http.Handler therefore a Container can be a Handler in a http.Server
|
// ServeHTTP implements net/http.Handler therefore a Container can be a Handler in a http.Server
|
||||||
func (c *Container) ServeHTTP(httpwriter http.ResponseWriter, httpRequest *http.Request) {
|
func (c *Container) ServeHTTP(httpWriter http.ResponseWriter, httpRequest *http.Request) {
|
||||||
c.ServeMux.ServeHTTP(httpwriter, httpRequest)
|
// Skip, if content encoding is disabled
|
||||||
|
if !c.contentEncodingEnabled {
|
||||||
|
c.ServeMux.ServeHTTP(httpWriter, httpRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// content encoding is enabled
|
||||||
|
|
||||||
|
// Skip, if httpWriter is already an CompressingResponseWriter
|
||||||
|
if _, ok := httpWriter.(*CompressingResponseWriter); ok {
|
||||||
|
c.ServeMux.ServeHTTP(httpWriter, httpRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
writer := httpWriter
|
||||||
|
// CompressingResponseWriter should be closed after all operations are done
|
||||||
|
defer func() {
|
||||||
|
if compressWriter, ok := writer.(*CompressingResponseWriter); ok {
|
||||||
|
compressWriter.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
doCompress, encoding := wantsCompressedResponse(httpRequest, httpWriter)
|
||||||
|
if doCompress {
|
||||||
|
var err error
|
||||||
|
writer, err = NewCompressingResponseWriter(httpWriter, encoding)
|
||||||
|
if err != nil {
|
||||||
|
log.Print("unable to install compressor: ", err)
|
||||||
|
httpWriter.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ServeMux.ServeHTTP(writer, httpRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics.
|
// Handle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics.
|
||||||
func (c *Container) Handle(pattern string, handler http.Handler) {
|
func (c *Container) Handle(pattern string, handler http.Handler) {
|
||||||
c.ServeMux.Handle(pattern, handler)
|
c.ServeMux.Handle(pattern, http.HandlerFunc(func(httpWriter http.ResponseWriter, httpRequest *http.Request) {
|
||||||
|
// Skip, if httpWriter is already an CompressingResponseWriter
|
||||||
|
if _, ok := httpWriter.(*CompressingResponseWriter); ok {
|
||||||
|
handler.ServeHTTP(httpWriter, httpRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
writer := httpWriter
|
||||||
|
|
||||||
|
// CompressingResponseWriter should be closed after all operations are done
|
||||||
|
defer func() {
|
||||||
|
if compressWriter, ok := writer.(*CompressingResponseWriter); ok {
|
||||||
|
compressWriter.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if c.contentEncodingEnabled {
|
||||||
|
doCompress, encoding := wantsCompressedResponse(httpRequest, httpWriter)
|
||||||
|
if doCompress {
|
||||||
|
var err error
|
||||||
|
writer, err = NewCompressingResponseWriter(httpWriter, encoding)
|
||||||
|
if err != nil {
|
||||||
|
log.Print("unable to install compressor: ", err)
|
||||||
|
httpWriter.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.ServeHTTP(writer, httpRequest)
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleWithFilter registers the handler for the given pattern.
|
// HandleWithFilter registers the handler for the given pattern.
|
||||||
@@ -319,7 +392,7 @@ func (c *Container) HandleWithFilter(pattern string, handler http.Handler) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) {
|
chain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) {
|
||||||
handler.ServeHTTP(httpResponse, httpRequest)
|
handler.ServeHTTP(resp, req.Request)
|
||||||
}}
|
}}
|
||||||
chain.ProcessFilter(NewRequest(httpRequest), NewResponse(httpResponse))
|
chain.ProcessFilter(NewRequest(httpRequest), NewResponse(httpResponse))
|
||||||
}
|
}
|
||||||
@@ -18,9 +18,22 @@ import (
|
|||||||
// http://enable-cors.org/server.html
|
// http://enable-cors.org/server.html
|
||||||
// http://www.html5rocks.com/en/tutorials/cors/#toc-handling-a-not-so-simple-request
|
// http://www.html5rocks.com/en/tutorials/cors/#toc-handling-a-not-so-simple-request
|
||||||
type CrossOriginResourceSharing struct {
|
type CrossOriginResourceSharing struct {
|
||||||
ExposeHeaders []string // list of Header names
|
ExposeHeaders []string // list of Header names
|
||||||
AllowedHeaders []string // list of Header names
|
|
||||||
AllowedDomains []string // list of allowed values for Http Origin. An allowed value can be a regular expression to support subdomain matching. If empty all are allowed.
|
// AllowedHeaders is alist of Header names. Checking is case-insensitive.
|
||||||
|
// The list may contain the special wildcard string ".*" ; all is allowed
|
||||||
|
AllowedHeaders []string
|
||||||
|
|
||||||
|
// AllowedDomains is a list of allowed values for Http Origin.
|
||||||
|
// The list may contain the special wildcard string ".*" ; all is allowed
|
||||||
|
// If empty all are allowed.
|
||||||
|
AllowedDomains []string
|
||||||
|
|
||||||
|
// AllowedDomainFunc is optional and is a function that will do the check
|
||||||
|
// when the origin is not part of the AllowedDomains and it does not contain the wildcard ".*".
|
||||||
|
AllowedDomainFunc func(origin string) bool
|
||||||
|
|
||||||
|
// AllowedMethods is either empty or has a list of http methods names. Checking is case-insensitive.
|
||||||
AllowedMethods []string
|
AllowedMethods []string
|
||||||
MaxAge int // number of seconds before requiring new Options request
|
MaxAge int // number of seconds before requiring new Options request
|
||||||
CookiesAllowed bool
|
CookiesAllowed bool
|
||||||
@@ -119,36 +132,24 @@ func (c CrossOriginResourceSharing) isOriginAllowed(origin string) bool {
|
|||||||
if len(origin) == 0 {
|
if len(origin) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
lowerOrigin := strings.ToLower(origin)
|
||||||
if len(c.AllowedDomains) == 0 {
|
if len(c.AllowedDomains) == 0 {
|
||||||
|
if c.AllowedDomainFunc != nil {
|
||||||
|
return c.AllowedDomainFunc(lowerOrigin)
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
allowed := false
|
// exact match on each allowed domain
|
||||||
for _, domain := range c.AllowedDomains {
|
for _, domain := range c.AllowedDomains {
|
||||||
if domain == origin {
|
if domain == ".*" || strings.ToLower(domain) == lowerOrigin {
|
||||||
allowed = true
|
return true
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if c.AllowedDomainFunc != nil {
|
||||||
if !allowed {
|
return c.AllowedDomainFunc(origin)
|
||||||
if len(c.allowedOriginPatterns) == 0 {
|
|
||||||
// compile allowed domains to allowed origin patterns
|
|
||||||
allowedOriginRegexps, err := compileRegexps(c.AllowedDomains)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
c.allowedOriginPatterns = allowedOriginRegexps
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, pattern := range c.allowedOriginPatterns {
|
|
||||||
if allowed = pattern.MatchString(origin); allowed {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
return allowed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c CrossOriginResourceSharing) setAllowOriginHeader(req *Request, resp *Response) {
|
func (c CrossOriginResourceSharing) setAllowOriginHeader(req *Request, resp *Response) {
|
||||||
@@ -184,19 +185,9 @@ func (c CrossOriginResourceSharing) isValidAccessControlRequestHeader(header str
|
|||||||
if strings.ToLower(each) == strings.ToLower(header) {
|
if strings.ToLower(each) == strings.ToLower(header) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if each == "*" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take a list of strings and compile them into a list of regular expressions.
|
|
||||||
func compileRegexps(regexpStrings []string) ([]*regexp.Regexp, error) {
|
|
||||||
regexps := []*regexp.Regexp{}
|
|
||||||
for _, regexpStr := range regexpStrings {
|
|
||||||
r, err := regexp.Compile(regexpStr)
|
|
||||||
if err != nil {
|
|
||||||
return regexps, err
|
|
||||||
}
|
|
||||||
regexps = append(regexps, r)
|
|
||||||
}
|
|
||||||
return regexps, nil
|
|
||||||
}
|
|
||||||
@@ -47,7 +47,7 @@ func (c CurlyRouter) SelectRoute(
|
|||||||
func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortableCurlyRoutes {
|
func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortableCurlyRoutes {
|
||||||
candidates := make(sortableCurlyRoutes, 0, 8)
|
candidates := make(sortableCurlyRoutes, 0, 8)
|
||||||
for _, each := range ws.routes {
|
for _, each := range ws.routes {
|
||||||
matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens)
|
matches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens, each.hasCustomVerb)
|
||||||
if matches {
|
if matches {
|
||||||
candidates.add(curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers?
|
candidates.add(curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers?
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ func (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortab
|
|||||||
}
|
}
|
||||||
|
|
||||||
// matchesRouteByPathTokens computes whether it matches, howmany parameters do match and what the number of static path elements are.
|
// matchesRouteByPathTokens computes whether it matches, howmany parameters do match and what the number of static path elements are.
|
||||||
func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []string) (matches bool, paramCount int, staticCount int) {
|
func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []string, routeHasCustomVerb bool) (matches bool, paramCount int, staticCount int) {
|
||||||
if len(routeTokens) < len(requestTokens) {
|
if len(routeTokens) < len(requestTokens) {
|
||||||
// proceed in matching only if last routeToken is wildcard
|
// proceed in matching only if last routeToken is wildcard
|
||||||
count := len(routeTokens)
|
count := len(routeTokens)
|
||||||
@@ -72,6 +72,15 @@ func (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []strin
|
|||||||
return false, 0, 0
|
return false, 0, 0
|
||||||
}
|
}
|
||||||
requestToken := requestTokens[i]
|
requestToken := requestTokens[i]
|
||||||
|
if routeHasCustomVerb && hasCustomVerb(routeToken){
|
||||||
|
if !isMatchCustomVerb(routeToken, requestToken) {
|
||||||
|
return false, 0, 0
|
||||||
|
}
|
||||||
|
staticCount++
|
||||||
|
requestToken = removeCustomVerb(requestToken)
|
||||||
|
routeToken = removeCustomVerb(routeToken)
|
||||||
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(routeToken, "{") {
|
if strings.HasPrefix(routeToken, "{") {
|
||||||
paramCount++
|
paramCount++
|
||||||
if colon := strings.Index(routeToken, ":"); colon != -1 {
|
if colon := strings.Index(routeToken, ":"); colon != -1 {
|
||||||
29
vendor/github.com/emicklei/go-restful/v3/custom_verb.go
generated
vendored
Normal file
29
vendor/github.com/emicklei/go-restful/v3/custom_verb.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
customVerbReg = regexp.MustCompile(":([A-Za-z]+)$")
|
||||||
|
)
|
||||||
|
|
||||||
|
func hasCustomVerb(routeToken string) bool {
|
||||||
|
return customVerbReg.MatchString(routeToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isMatchCustomVerb(routeToken string, pathToken string) bool {
|
||||||
|
rs := customVerbReg.FindStringSubmatch(routeToken)
|
||||||
|
if len(rs) < 2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
customVerb := rs[1]
|
||||||
|
specificVerbReg := regexp.MustCompile(fmt.Sprintf(":%s$", customVerb))
|
||||||
|
return specificVerbReg.MatchString(pathToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeCustomVerb(str string) string {
|
||||||
|
return customVerbReg.ReplaceAllString(str, "")
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ This package has the logic to find the best matching Route and if found, call it
|
|||||||
|
|
||||||
The (*Request, *Response) arguments provide functions for reading information from the request and writing information back to the response.
|
The (*Request, *Response) arguments provide functions for reading information from the request and writing information back to the response.
|
||||||
|
|
||||||
See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-user-resource.go with a full implementation.
|
See the example https://github.com/emicklei/go-restful/blob/v3/examples/user-resource/restful-user-resource.go with a full implementation.
|
||||||
|
|
||||||
Regular expression matching Routes
|
Regular expression matching Routes
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ These are processed before calling the function associated with the Route.
|
|||||||
// install 2 chained route filters (processed before calling findUser)
|
// install 2 chained route filters (processed before calling findUser)
|
||||||
ws.Route(ws.GET("/{user-id}").Filter(routeLogging).Filter(NewCountFilter().routeCounter).To(findUser))
|
ws.Route(ws.GET("/{user-id}").Filter(routeLogging).Filter(NewCountFilter().routeCounter).To(findUser))
|
||||||
|
|
||||||
See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-filters.go with full implementations.
|
See the example https://github.com/emicklei/go-restful/blob/v3/examples/filters/restful-filters.go with full implementations.
|
||||||
|
|
||||||
Response Encoding
|
Response Encoding
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ Two encodings are supported: gzip and deflate. To enable this for all responses:
|
|||||||
If a Http request includes the Accept-Encoding header then the response content will be compressed using the specified encoding.
|
If a Http request includes the Accept-Encoding header then the response content will be compressed using the specified encoding.
|
||||||
Alternatively, you can create a Filter that performs the encoding and install it per WebService or Route.
|
Alternatively, you can create a Filter that performs the encoding and install it per WebService or Route.
|
||||||
|
|
||||||
See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-encoding-filter.go
|
See the example https://github.com/emicklei/go-restful/blob/v3/examples/encoding/restful-encoding-filter.go
|
||||||
|
|
||||||
OPTIONS support
|
OPTIONS support
|
||||||
|
|
||||||
21
vendor/github.com/emicklei/go-restful/v3/extensions.go
generated
vendored
Normal file
21
vendor/github.com/emicklei/go-restful/v3/extensions.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package restful
|
||||||
|
|
||||||
|
// Copyright 2021 Ernest Micklei. All rights reserved.
|
||||||
|
// Use of this source code is governed by a license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// ExtensionProperties provides storage of vendor extensions for entities
|
||||||
|
type ExtensionProperties struct {
|
||||||
|
// Extensions vendor extensions used to describe extra functionality
|
||||||
|
// (https://swagger.io/docs/specification/2-0/swagger-extensions/)
|
||||||
|
Extensions map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddExtension adds or updates a key=value pair to the extension map.
|
||||||
|
func (ep *ExtensionProperties) AddExtension(key string, value interface{}) {
|
||||||
|
if ep.Extensions == nil {
|
||||||
|
ep.Extensions = map[string]interface{}{key: value}
|
||||||
|
} else {
|
||||||
|
ep.Extensions[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,11 @@ package restful
|
|||||||
|
|
||||||
// FilterChain is a request scoped object to process one or more filters before calling the target RouteFunction.
|
// FilterChain is a request scoped object to process one or more filters before calling the target RouteFunction.
|
||||||
type FilterChain struct {
|
type FilterChain struct {
|
||||||
Filters []FilterFunction // ordered list of FilterFunction
|
Filters []FilterFunction // ordered list of FilterFunction
|
||||||
Index int // index into filters that is currently in progress
|
Index int // index into filters that is currently in progress
|
||||||
Target RouteFunction // function to call after passing all filters
|
Target RouteFunction // function to call after passing all filters
|
||||||
|
ParameterDocs []*Parameter // the parameter docs for the route
|
||||||
|
Operation string // the name of the operation
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessFilter passes the request,response pair through the next of Filters.
|
// ProcessFilter passes the request,response pair through the next of Filters.
|
||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RouterJSR311 implements the flow for matching Requests to Routes (and consequently Resource Functions)
|
// RouterJSR311 implements the flow for matching Requests to Routes (and consequently Resource Functions)
|
||||||
@@ -98,7 +99,18 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R
|
|||||||
if trace {
|
if trace {
|
||||||
traceLogger.Printf("no Route found (in %d routes) that matches HTTP method %s\n", len(previous), httpRequest.Method)
|
traceLogger.Printf("no Route found (in %d routes) that matches HTTP method %s\n", len(previous), httpRequest.Method)
|
||||||
}
|
}
|
||||||
return nil, NewError(http.StatusMethodNotAllowed, "405: Method Not Allowed")
|
allowed := []string{}
|
||||||
|
allowedLoop:
|
||||||
|
for _, candidate := range previous {
|
||||||
|
for _, method := range allowed {
|
||||||
|
if method == candidate.Method {
|
||||||
|
continue allowedLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
allowed = append(allowed, candidate.Method)
|
||||||
|
}
|
||||||
|
header := http.Header{"Allow": []string{strings.Join(allowed, ", ")}}
|
||||||
|
return nil, NewErrorWithHeader(http.StatusMethodNotAllowed, "405: Method Not Allowed", header)
|
||||||
}
|
}
|
||||||
|
|
||||||
// content-type
|
// content-type
|
||||||
@@ -135,7 +147,24 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R
|
|||||||
if trace {
|
if trace {
|
||||||
traceLogger.Printf("no Route found (from %d) that matches HTTP Accept: %s\n", len(previous), accept)
|
traceLogger.Printf("no Route found (from %d) that matches HTTP Accept: %s\n", len(previous), accept)
|
||||||
}
|
}
|
||||||
return nil, NewError(http.StatusNotAcceptable, "406: Not Acceptable")
|
available := []string{}
|
||||||
|
for _, candidate := range previous {
|
||||||
|
available = append(available, candidate.Produces...)
|
||||||
|
}
|
||||||
|
// if POST,PUT,PATCH without body
|
||||||
|
method, length := httpRequest.Method, httpRequest.Header.Get("Content-Length")
|
||||||
|
if (method == http.MethodPost ||
|
||||||
|
method == http.MethodPut ||
|
||||||
|
method == http.MethodPatch) && length == "" {
|
||||||
|
return nil, NewError(
|
||||||
|
http.StatusUnsupportedMediaType,
|
||||||
|
fmt.Sprintf("415: Unsupported Media Type\n\nAvailable representations: %s", strings.Join(available, ", ")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return nil, NewError(
|
||||||
|
http.StatusNotAcceptable,
|
||||||
|
fmt.Sprintf("406: Not Acceptable\n\nAvailable representations: %s", strings.Join(available, ", ")),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
// return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil
|
// return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil
|
||||||
return candidates[0], nil
|
return candidates[0], nil
|
||||||
@@ -4,7 +4,7 @@ package restful
|
|||||||
// Use of this source code is governed by a license
|
// Use of this source code is governed by a license
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
import (
|
import (
|
||||||
"github.com/emicklei/go-restful/log"
|
"github.com/emicklei/go-restful/v3/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var trace bool = false
|
var trace bool = false
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user