mirror of
https://github.com/1Password/onepassword-operator.git
synced 2025-10-24 16:30:47 +00:00
Merge pull request #153 from 1Password/update-dependencies
Update dependencies
This commit is contained in:
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go 1.x
|
- name: Set up Go 1.x
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: ^1.19
|
go-version: ^1.19
|
||||||
|
|
||||||
|
|||||||
16
.github/workflows/release-pr.yml
vendored
16
.github/workflows/release-pr.yml
vendored
@@ -47,15 +47,16 @@ jobs:
|
|||||||
|
|
||||||
- name: Parse release version
|
- name: Parse release version
|
||||||
id: get_version
|
id: get_version
|
||||||
run: echo "::set-output name=version::$(echo $GITHUB_REF | sed 's|^refs/heads/release/v?*||g')"
|
run: echo "version=$(echo "$GITHUB_REF" | sed 's|^refs/heads/release/v?*||g')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Prepare Pull Request
|
- name: Prepare Pull Request
|
||||||
id: prep_pr
|
id: prep_pr
|
||||||
run: |
|
run: |
|
||||||
CHANGELOG_PATH=$(printf "%s/CHANGELOG.md" "${GITHUB_WORKSPACE}")
|
CHANGELOG_PATH=$(printf "%s/CHANGELOG.md" "${GITHUB_WORKSPACE}")
|
||||||
|
|
||||||
LOG_ENTRY=$(awk '/START\/v[0-9]+\.[0-9]+\.[0-9]+*/{f=1; next} /---/{if (f == 1) exit} f' "${CHANGELOG_PATH}")
|
LOG_ENTRY=$(awk '/START\/v[0-9]+\.[0-9]+\.[0-9]+*/{f=1; next} /---/{if (f == 1) exit} f' "${CHANGELOG_PATH}")
|
||||||
export PR_BODY=$(cat <<EOF
|
DELIMITER="$(openssl rand -hex 8)" # DELIMITER is randomly generated and unique for each run. For more information, see https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#understanding-the-risk-of-script-injections.
|
||||||
|
|
||||||
|
PR_BODY_CONTENT="
|
||||||
This is an automated PR for a new release.
|
This is an automated PR for a new release.
|
||||||
|
|
||||||
Please check the following before approving:
|
Please check the following before approving:
|
||||||
@@ -64,14 +65,9 @@ jobs:
|
|||||||
---
|
---
|
||||||
## Release Changelog Preview
|
## Release Changelog Preview
|
||||||
${LOG_ENTRY}
|
${LOG_ENTRY}
|
||||||
EOF
|
"
|
||||||
)
|
|
||||||
|
|
||||||
# Sanitizes multiline strings for action outputs (https://medium.com/agorapulse-stories/23f56447d209)
|
echo "pr_body<<${DELIMITER}${PR_BODY_CONTENT}${DELIMITER}" >> "${GITHUB_OUTPUT}"
|
||||||
PR_BODY="${PR_BODY//'%'/'%25'}"
|
|
||||||
PR_BODY="${PR_BODY//$'\n'/'%0A'}"
|
|
||||||
PR_BODY="${PR_BODY//$'\r'/'%0D'}"
|
|
||||||
echo "::set-output name=pr_body::$(echo "$PR_BODY")"
|
|
||||||
|
|
||||||
- name: Create Pull Request via API
|
- name: Create Pull Request via API
|
||||||
id: post_pr
|
id: post_pr
|
||||||
|
|||||||
80
go.mod
80
go.mod
@@ -1,87 +1,81 @@
|
|||||||
module github.com/1Password/onepassword-operator
|
module github.com/1Password/onepassword-operator
|
||||||
|
|
||||||
go 1.18
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/1Password/connect-sdk-go v1.5.0
|
github.com/1Password/connect-sdk-go v1.5.0
|
||||||
github.com/onsi/ginkgo/v2 v2.1.6
|
github.com/onsi/ginkgo/v2 v2.9.2
|
||||||
github.com/onsi/gomega v1.20.2
|
github.com/onsi/gomega v1.27.5
|
||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.2
|
||||||
k8s.io/api v0.25.3
|
k8s.io/api v0.26.3
|
||||||
k8s.io/apimachinery v0.25.3
|
k8s.io/apimachinery v0.26.3
|
||||||
k8s.io/client-go v0.25.3
|
k8s.io/client-go v0.26.3
|
||||||
k8s.io/kubectl v0.25.0
|
k8s.io/kubectl v0.26.3
|
||||||
sigs.k8s.io/controller-runtime v0.13.0
|
sigs.k8s.io/controller-runtime v0.14.5
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/compute v1.10.0 // indirect
|
|
||||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
|
||||||
github.com/Azure/go-autorest/autorest v0.11.28 // indirect
|
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.21 // 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/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
|
github.com/emicklei/go-restful/v3 v3.10.2 // indirect
|
||||||
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||||
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
|
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||||
github.com/go-logr/logr v1.2.3 // indirect
|
github.com/go-logr/logr v1.2.3 // indirect
|
||||||
github.com/go-logr/zapr v1.2.3 // 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.6 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||||
github.com/go-openapi/swag v0.22.3 // indirect
|
github.com/go-openapi/swag v0.22.3 // indirect
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
|
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/golang/protobuf v1.5.3 // indirect
|
||||||
github.com/google/gnostic v0.6.9 // indirect
|
github.com/google/gnostic v0.6.9 // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/google/go-cmp v0.5.9 // indirect
|
||||||
github.com/google/gofuzz v1.2.0 // indirect
|
github.com/google/gofuzz v1.2.0 // indirect
|
||||||
|
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
github.com/imdario/mergo v0.3.13 // indirect
|
github.com/imdario/mergo v0.3.15 // 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
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/prometheus/client_golang v1.13.0 // indirect
|
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||||
github.com/prometheus/client_model v0.3.0 // indirect
|
github.com/prometheus/client_model v0.3.0 // indirect
|
||||||
github.com/prometheus/common v0.37.0 // indirect
|
github.com/prometheus/common v0.42.0 // indirect
|
||||||
github.com/prometheus/procfs v0.8.0 // indirect
|
github.com/prometheus/procfs v0.9.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
|
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
|
||||||
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
||||||
go.uber.org/atomic v1.10.0 // indirect
|
go.uber.org/atomic v1.10.0 // indirect
|
||||||
go.uber.org/multierr v1.8.0 // indirect
|
go.uber.org/multierr v1.10.0 // indirect
|
||||||
go.uber.org/zap v1.23.0 // indirect
|
go.uber.org/zap v1.24.0 // indirect
|
||||||
golang.org/x/crypto v0.1.0 // indirect
|
golang.org/x/net v0.8.0 // indirect
|
||||||
golang.org/x/net v0.1.0 // indirect
|
golang.org/x/oauth2 v0.6.0 // indirect
|
||||||
golang.org/x/oauth2 v0.1.0 // indirect
|
golang.org/x/sys v0.6.0 // indirect
|
||||||
golang.org/x/sys v0.1.0 // indirect
|
golang.org/x/term v0.6.0 // indirect
|
||||||
golang.org/x/term v0.1.0 // indirect
|
golang.org/x/text v0.8.0 // indirect
|
||||||
golang.org/x/text v0.4.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/time v0.1.0 // indirect
|
golang.org/x/tools v0.7.0 // indirect
|
||||||
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
|
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
k8s.io/apiextensions-apiserver v0.25.3 // indirect
|
k8s.io/apiextensions-apiserver v0.26.3 // indirect
|
||||||
k8s.io/component-base v0.25.3 // indirect
|
k8s.io/component-base v0.26.3 // indirect
|
||||||
k8s.io/klog/v2 v2.80.1 // indirect
|
k8s.io/klog/v2 v2.90.1 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
|
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a // indirect
|
||||||
k8s.io/utils v0.0.0-20221012122500-cfd413dd9e85 // indirect
|
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
499
go.sum
499
go.sum
@@ -1,83 +1,24 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
|
||||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
|
||||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
|
||||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
|
||||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
|
||||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
|
||||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
|
||||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
|
||||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
|
||||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
|
||||||
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.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
|
||||||
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.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
|
||||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
|
||||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
|
||||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
|
||||||
cloud.google.com/go/compute v1.10.0 h1:aoLIYaA1fX3ywihqpBk2APQKOo20nXsp1GEZQbx5Jk4=
|
|
||||||
cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU=
|
|
||||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
|
||||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
|
||||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
|
||||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
|
||||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
|
||||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
|
||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
|
||||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
|
||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
|
||||||
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/1Password/connect-sdk-go v1.5.0 h1:F0WJcLSzGg3iXEDY49/ULdszYKsQLGTzn+2cyYXqiyk=
|
github.com/1Password/connect-sdk-go v1.5.0 h1:F0WJcLSzGg3iXEDY49/ULdszYKsQLGTzn+2cyYXqiyk=
|
||||||
github.com/1Password/connect-sdk-go v1.5.0/go.mod h1:TdynFeyvaRoackENbJ8RfJokH+WAowAu1MLmUbdMq6s=
|
github.com/1Password/connect-sdk-go v1.5.0/go.mod h1:TdynFeyvaRoackENbJ8RfJokH+WAowAu1MLmUbdMq6s=
|
||||||
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/autorest v0.11.28 h1:ndAExarwr5Y+GaHE6VCaY1kyS/HwwGGyuimVhWsHOEM=
|
|
||||||
github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA=
|
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.21 h1:jjQnVFXPfekaqb8vIsv2G1lxshoW+oGv4MDlhRtnYZk=
|
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.21/go.mod h1:zua7mBUaCc5YnSLKYgGJR/w5ePdMDA6H56upLsHzA9U=
|
|
||||||
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/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
|
||||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw=
|
|
||||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU=
|
|
||||||
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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
|
github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
|
||||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
|
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/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.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/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-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
@@ -87,8 +28,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||||
github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE=
|
github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE=
|
||||||
github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
github.com/emicklei/go-restful/v3 v3.10.2/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=
|
||||||
@@ -106,57 +47,31 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4
|
|||||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||||
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=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
|
||||||
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
|
||||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
|
||||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
|
||||||
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/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
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/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 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A=
|
||||||
github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4=
|
github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||||
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
|
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||||
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
|
|
||||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
|
||||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
||||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
|
||||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
|
||||||
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
|
|
||||||
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
|
||||||
github.com/golang/mock v1.4.0/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.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
|
||||||
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=
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||||
@@ -167,19 +82,16 @@ 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.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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0=
|
github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0=
|
||||||
github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E=
|
github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.4.1/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.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.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/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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
@@ -187,133 +99,81 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
|||||||
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.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd h1:r8yyd+DJDmsUhGrRBxH5Pj7KeFK5l+Y3FsgT8keqKtk=
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
|
||||||
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-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/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-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
|
||||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
|
||||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
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/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
|
||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
|
||||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
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.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
|
||||||
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 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
|
||||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
|
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||||
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
|
||||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM=
|
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
|
||||||
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=
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
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.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU=
|
||||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
|
||||||
github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU=
|
github.com/onsi/gomega v1.27.5 h1:T/X6I0RNFw/kTqgfkZPcQ5KU6vCnWNBGdtrIx2dpGeQ=
|
||||||
github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
github.com/onsi/gomega v1.27.5/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
|
||||||
github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY=
|
|
||||||
github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
|
|
||||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
||||||
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.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
|
||||||
github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=
|
|
||||||
github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
||||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
||||||
github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
|
|
||||||
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
|
||||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
|
||||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
|
||||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
|
||||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
|
||||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
|
||||||
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.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
|
||||||
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/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
|
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||||
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
|
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
|
||||||
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||||
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
|
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
|
||||||
@@ -321,15 +181,8 @@ github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6
|
|||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/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=
|
||||||
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.2/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.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
@@ -338,220 +191,96 @@ go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0
|
|||||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
|
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||||
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||||
go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
|
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||||
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
|
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
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-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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
|
||||||
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
|
||||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
|
||||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
|
||||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
|
||||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
|
||||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/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-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
|
||||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.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/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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/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-20200513185701-a91f0712d120/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-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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
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-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
|
||||||
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
|
|
||||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
|
||||||
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-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
|
||||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
|
||||||
golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y=
|
|
||||||
golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/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/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-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-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-20191001151750-bb3f8db39f24/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-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/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-20200515095857-1151b9dac4a9/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-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-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-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-20210124154548-22da62e12c0c/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-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-20210615035016-665e8c7367d1/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-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/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/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
||||||
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
|
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.3.0/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.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
|
|
||||||
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
|
||||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
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-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
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.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||||
|
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||||
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=
|
||||||
@@ -562,73 +291,19 @@ gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJ
|
|||||||
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
|
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
|
||||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
|
||||||
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
|
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
|
||||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.24.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.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
|
||||||
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.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
|
||||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/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-20200331122359-1ee6d9798940/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-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
|
||||||
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-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||||
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.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
|
||||||
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.31.0/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.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||||
@@ -640,71 +315,55 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
|
|||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
|
||||||
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/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
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=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
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/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.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
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-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
k8s.io/apiextensions-apiserver v0.26.3 h1:5PGMm3oEzdB1W/FTMgGIDmm100vn7IaUP5er36dB+YE=
|
||||||
k8s.io/api v0.25.3 h1:Q1v5UFfYe87vi5H7NU0p4RXC26PPMT8KOpr1TLQbCMQ=
|
k8s.io/apiextensions-apiserver v0.26.3/go.mod h1:jdA5MdjNWGP+njw1EKMZc64xAT5fIhN6VJrElV3sfpQ=
|
||||||
k8s.io/api v0.25.3/go.mod h1:o42gKscFrEVjHdQnyRenACrMtbuJsVdP+WVjqejfzmI=
|
k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k=
|
||||||
k8s.io/apiextensions-apiserver v0.25.3 h1:bfI4KS31w2f9WM1KLGwnwuVlW3RSRPuIsfNF/3HzR0k=
|
k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=
|
||||||
k8s.io/apiextensions-apiserver v0.25.3/go.mod h1:ZJqwpCkxIx9itilmZek7JgfUAM0dnTsA48I4krPqRmo=
|
k8s.io/client-go v0.26.3 h1:k1UY+KXfkxV2ScEL3gilKcF7761xkYsSD6BC9szIu8s=
|
||||||
k8s.io/apimachinery v0.25.3 h1:7o9ium4uyUOM76t6aunP0nZuex7gDf8VGwkR5RcJnQc=
|
k8s.io/client-go v0.26.3/go.mod h1:ZPNu9lm8/dbRIPAgteN30RSXea6vrCpFvq+MateTUuQ=
|
||||||
k8s.io/apimachinery v0.25.3/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo=
|
k8s.io/component-base v0.26.3 h1:oC0WMK/ggcbGDTkdcqefI4wIZRYdK3JySx9/HADpV0g=
|
||||||
k8s.io/client-go v0.25.3 h1:oB4Dyl8d6UbfDHD8Bv8evKylzs3BXzzufLiO27xuPs0=
|
k8s.io/component-base v0.26.3/go.mod h1:5kj1kZYwSC6ZstHJN7oHBqcJC6yyn41eR+Sqa/mQc8E=
|
||||||
k8s.io/client-go v0.25.3/go.mod h1:t39LPczAIMwycjcXkVc+CB+PZV69jQuNx4um5ORDjQA=
|
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
|
||||||
k8s.io/component-base v0.25.3 h1:UrsxciGdrCY03ULT1h/S/gXFCOPnLhUVwSyx+hM/zq4=
|
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||||
k8s.io/component-base v0.25.3/go.mod h1:WYoS8L+IlTZgU7rhAl5Ctpw0WdMxDfCC5dkxcEFa/TI=
|
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a h1:gmovKNur38vgoWfGtP5QOGNOA7ki4n6qNYoFAgMlNvg=
|
||||||
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
|
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY=
|
||||||
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
k8s.io/kubectl v0.26.3 h1:bZ5SgFyeEXw6XTc1Qji0iNdtqAC76lmeIIQULg2wNXM=
|
||||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
|
k8s.io/kubectl v0.26.3/go.mod h1:02+gv7Qn4dupzN3fi/9OvqqdW+uG/4Zi56vc4Zmsp1g=
|
||||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4=
|
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 h1:xMMXJlJbsU8w3V5N2FLDQ8YgU8s1EoULdbQBcAeNJkY=
|
||||||
k8s.io/kubectl v0.25.0 h1:/Wn1cFqo8ik3iee1EvpxYre3bkWsGLXzLQI6uCCAkQc=
|
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
k8s.io/kubectl v0.25.0/go.mod h1:n16ULWsOl2jmQpzt2o7Dud1t4o0+Y186ICb4O+GwKAU=
|
|
||||||
k8s.io/utils v0.0.0-20221012122500-cfd413dd9e85 h1:cTdVh7LYu82xeClmfzGtgyspNh6UxpwLWGi8R4sspNo=
|
|
||||||
k8s.io/utils v0.0.0-20221012122500-cfd413dd9e85/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
sigs.k8s.io/controller-runtime v0.14.5 h1:6xaWFqzT5KuAQ9ufgUaj1G/+C4Y1GRkhrxl+BJ9i+5s=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
sigs.k8s.io/controller-runtime v0.14.5/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
|
||||||
sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ=
|
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||||
sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI=
|
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
|
|
||||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
|
||||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||||
|
|||||||
542
vendor/cloud.google.com/go/compute/metadata/metadata.go
generated
vendored
542
vendor/cloud.google.com/go/compute/metadata/metadata.go
generated
vendored
@@ -1,542 +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://cloud.google.com/compute/docs/metadata/overview.
|
|
||||||
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: newDefaultHTTPClient()}
|
|
||||||
|
|
||||||
func newDefaultHTTPClient() *http.Client {
|
|
||||||
return &http.Client{
|
|
||||||
Transport: &http.Transport{
|
|
||||||
Dial: (&net.Dialer{
|
|
||||||
Timeout: 2 * time.Second,
|
|
||||||
KeepAlive: 30 * time.Second,
|
|
||||||
}).Dial,
|
|
||||||
},
|
|
||||||
Timeout: 5 * time.Second,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 := newDefaultHTTPClient().Do(req.WithContext(ctx))
|
|
||||||
if err != nil {
|
|
||||||
resc <- false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
resc <- res.Header.Get("Metadata-Flavor") == "Google"
|
|
||||||
}()
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
resolver := &net.Resolver{}
|
|
||||||
addrs, err := resolver.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) {
|
|
||||||
ctx := context.TODO()
|
|
||||||
// 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)
|
|
||||||
var res *http.Response
|
|
||||||
var reqErr error
|
|
||||||
retryer := newRetryer()
|
|
||||||
for {
|
|
||||||
res, reqErr = c.hc.Do(req)
|
|
||||||
var code int
|
|
||||||
if res != nil {
|
|
||||||
code = res.StatusCode
|
|
||||||
}
|
|
||||||
if delay, shouldRetry := retryer.Retry(code, reqErr); shouldRetry {
|
|
||||||
if err := sleep(ctx, delay); err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if reqErr != nil {
|
|
||||||
return "", "", reqErr
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
114
vendor/cloud.google.com/go/compute/metadata/retry.go
generated
vendored
114
vendor/cloud.google.com/go/compute/metadata/retry.go
generated
vendored
@@ -1,114 +0,0 @@
|
|||||||
// Copyright 2021 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
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
"math/rand"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
maxRetryAttempts = 5
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
syscallRetryable = func(err error) bool { return false }
|
|
||||||
)
|
|
||||||
|
|
||||||
// defaultBackoff is basically equivalent to gax.Backoff without the need for
|
|
||||||
// the dependency.
|
|
||||||
type defaultBackoff struct {
|
|
||||||
max time.Duration
|
|
||||||
mul float64
|
|
||||||
cur time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *defaultBackoff) Pause() time.Duration {
|
|
||||||
d := time.Duration(1 + rand.Int63n(int64(b.cur)))
|
|
||||||
b.cur = time.Duration(float64(b.cur) * b.mul)
|
|
||||||
if b.cur > b.max {
|
|
||||||
b.cur = b.max
|
|
||||||
}
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
|
|
||||||
// sleep is the equivalent of gax.Sleep without the need for the dependency.
|
|
||||||
func sleep(ctx context.Context, d time.Duration) error {
|
|
||||||
t := time.NewTimer(d)
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
t.Stop()
|
|
||||||
return ctx.Err()
|
|
||||||
case <-t.C:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newRetryer() *metadataRetryer {
|
|
||||||
return &metadataRetryer{bo: &defaultBackoff{
|
|
||||||
cur: 100 * time.Millisecond,
|
|
||||||
max: 30 * time.Second,
|
|
||||||
mul: 2,
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
type backoff interface {
|
|
||||||
Pause() time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
type metadataRetryer struct {
|
|
||||||
bo backoff
|
|
||||||
attempts int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *metadataRetryer) Retry(status int, err error) (time.Duration, bool) {
|
|
||||||
if status == http.StatusOK {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
retryOk := shouldRetry(status, err)
|
|
||||||
if !retryOk {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
if r.attempts == maxRetryAttempts {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
r.attempts++
|
|
||||||
return r.bo.Pause(), true
|
|
||||||
}
|
|
||||||
|
|
||||||
func shouldRetry(status int, err error) bool {
|
|
||||||
if 500 <= status && status <= 599 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if err == io.ErrUnexpectedEOF {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// Transient network errors should be retried.
|
|
||||||
if syscallRetryable(err) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if err, ok := err.(interface{ Temporary() bool }); ok {
|
|
||||||
if err.Temporary() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err, ok := err.(interface{ Unwrap() error }); ok {
|
|
||||||
return shouldRetry(status, err.Unwrap())
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
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.
|
|
||||||
294
vendor/github.com/Azure/go-autorest/autorest/adal/README.md
generated
vendored
294
vendor/github.com/Azure/go-autorest/autorest/adal/README.md
generated
vendored
@@ -1,294 +0,0 @@
|
|||||||
# NOTE: This module will go out of support by March 31, 2023. For authenticating with Azure AD, use module [azidentity](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity) instead. For help migrating from `adal` to `azidentiy` please consult the [migration guide](https://aka.ms/azsdk/go/identity/migration). General information about the retirement of this and other legacy modules can be found [here](https://azure.microsoft.com/updates/support-for-azure-sdk-libraries-that-do-not-conform-to-our-current-azure-sdk-guidelines-will-be-retired-as-of-31-march-2023/).
|
|
||||||
|
|
||||||
# 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/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/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/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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
25
vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go
generated
vendored
25
vendor/github.com/Azure/go-autorest/autorest/adal/go_mod_tidy_hack.go
generated
vendored
@@ -1,25 +0,0 @@
|
|||||||
//go:build modhack
|
|
||||||
// +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
|
|
||||||
}
|
|
||||||
101
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
101
vendor/github.com/Azure/go-autorest/autorest/adal/sender.go
generated
vendored
@@ -1,101 +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"
|
|
||||||
"net/http"
|
|
||||||
"net/http/cookiejar"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"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() {
|
|
||||||
// copied from http.DefaultTransport with a TLS minimum version.
|
|
||||||
transport := &http.Transport{
|
|
||||||
Proxy: http.ProxyFromEnvironment,
|
|
||||||
DialContext: (&net.Dialer{
|
|
||||||
Timeout: 30 * time.Second,
|
|
||||||
KeepAlive: 30 * time.Second,
|
|
||||||
}).DialContext,
|
|
||||||
ForceAttemptHTTP2: true,
|
|
||||||
MaxIdleConns: 100,
|
|
||||||
IdleConnTimeout: 90 * time.Second,
|
|
||||||
TLSHandshakeTimeout: 10 * time.Second,
|
|
||||||
ExpectContinueTimeout: 1 * time.Second,
|
|
||||||
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
|
|
||||||
}
|
|
||||||
1396
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
1396
vendor/github.com/Azure/go-autorest/autorest/adal/token.go
generated
vendored
File diff suppressed because it is too large
Load Diff
76
vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go
generated
vendored
76
vendor/github.com/Azure/go-autorest/autorest/adal/token_1.13.go
generated
vendored
@@ -1,76 +0,0 @@
|
|||||||
//go:build go1.13
|
|
||||||
// +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, 2*time.Second)
|
|
||||||
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
|
|
||||||
}
|
|
||||||
75
vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go
generated
vendored
75
vendor/github.com/Azure/go-autorest/autorest/adal/token_legacy.go
generated
vendored
@@ -1,75 +0,0 @@
|
|||||||
//go:build !go1.13
|
|
||||||
// +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, 2*time.Second)
|
|
||||||
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
|
|
||||||
}
|
|
||||||
995
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
995
vendor/github.com/Azure/go-autorest/autorest/azure/async.go
generated
vendored
@@ -1,995 +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/logger"
|
|
||||||
"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 {
|
|
||||||
logger.Instance.Writeln(logger.LogInfo, "WaitForCompletionRef: initial polling delay")
|
|
||||||
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 {
|
|
||||||
logger.Instance.Writeln(logger.LogInfo, "WaitForCompletionRef: Using client polling delay")
|
|
||||||
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.
|
|
||||||
logger.Instance.Writef(logger.LogError, "WaitForCompletionRef: %s\n", err)
|
|
||||||
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=%s", 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=%s", 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=%s", 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/templates/template-functions-resource?tabs=json#resourceid.
|
|
||||||
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, 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, 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, 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
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
331
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
331
vendor/github.com/Azure/go-autorest/autorest/azure/environments.go
generated
vendored
@@ -1,331 +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,
|
|
||||||
"AZURECLOUD": PublicCloud,
|
|
||||||
"AZUREPUBLICCLOUD": PublicCloud,
|
|
||||||
"AZUREUSGOVERNMENT": USGovernmentCloud,
|
|
||||||
"AZUREUSGOVERNMENTCLOUD": USGovernmentCloud, //TODO: deprecate
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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"`
|
|
||||||
OSSRDBMS string `json:"ossRDBMS"`
|
|
||||||
Storage string `json:"storage"`
|
|
||||||
Synapse string `json:"synapse"`
|
|
||||||
ServiceBus string `json:"serviceBus"`
|
|
||||||
SQLDatabase string `json:"sqlDatabase"`
|
|
||||||
CosmosDB string `json:"cosmosDB"`
|
|
||||||
ManagedHSM string `json:"managedHSM"`
|
|
||||||
MicrosoftGraph string `json:"microsoftGraph"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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"`
|
|
||||||
ManagedHSMEndpoint string `json:"managedHSMEndpoint"`
|
|
||||||
GraphEndpoint string `json:"graphEndpoint"`
|
|
||||||
ServiceBusEndpoint string `json:"serviceBusEndpoint"`
|
|
||||||
BatchManagementEndpoint string `json:"batchManagementEndpoint"`
|
|
||||||
MicrosoftGraphEndpoint string `json:"microsoftGraphEndpoint"`
|
|
||||||
StorageEndpointSuffix string `json:"storageEndpointSuffix"`
|
|
||||||
CosmosDBDNSSuffix string `json:"cosmosDBDNSSuffix"`
|
|
||||||
MariaDBDNSSuffix string `json:"mariaDBDNSSuffix"`
|
|
||||||
MySQLDatabaseDNSSuffix string `json:"mySqlDatabaseDNSSuffix"`
|
|
||||||
PostgresqlDatabaseDNSSuffix string `json:"postgresqlDatabaseDNSSuffix"`
|
|
||||||
SQLDatabaseDNSSuffix string `json:"sqlDatabaseDNSSuffix"`
|
|
||||||
TrafficManagerDNSSuffix string `json:"trafficManagerDNSSuffix"`
|
|
||||||
KeyVaultDNSSuffix string `json:"keyVaultDNSSuffix"`
|
|
||||||
ManagedHSMDNSSuffix string `json:"managedHSMDNSSuffix"`
|
|
||||||
ServiceBusEndpointSuffix string `json:"serviceBusEndpointSuffix"`
|
|
||||||
ServiceManagementVMDNSSuffix string `json:"serviceManagementVMDNSSuffix"`
|
|
||||||
ResourceManagerVMDNSSuffix string `json:"resourceManagerVMDNSSuffix"`
|
|
||||||
ContainerRegistryDNSSuffix string `json:"containerRegistryDNSSuffix"`
|
|
||||||
TokenAudience string `json:"tokenAudience"`
|
|
||||||
APIManagementHostNameSuffix string `json:"apiManagementHostNameSuffix"`
|
|
||||||
SynapseEndpointSuffix string `json:"synapseEndpointSuffix"`
|
|
||||||
DatalakeSuffix string `json:"datalakeSuffix"`
|
|
||||||
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/",
|
|
||||||
ManagedHSMEndpoint: "https://managedhsm.azure.net/",
|
|
||||||
GraphEndpoint: "https://graph.windows.net/",
|
|
||||||
ServiceBusEndpoint: "https://servicebus.windows.net/",
|
|
||||||
BatchManagementEndpoint: "https://batch.core.windows.net/",
|
|
||||||
MicrosoftGraphEndpoint: "https://graph.microsoft.com/",
|
|
||||||
StorageEndpointSuffix: "core.windows.net",
|
|
||||||
CosmosDBDNSSuffix: "documents.azure.com",
|
|
||||||
MariaDBDNSSuffix: "mariadb.database.azure.com",
|
|
||||||
MySQLDatabaseDNSSuffix: "mysql.database.azure.com",
|
|
||||||
PostgresqlDatabaseDNSSuffix: "postgres.database.azure.com",
|
|
||||||
SQLDatabaseDNSSuffix: "database.windows.net",
|
|
||||||
TrafficManagerDNSSuffix: "trafficmanager.net",
|
|
||||||
KeyVaultDNSSuffix: "vault.azure.net",
|
|
||||||
ManagedHSMDNSSuffix: "managedhsm.azure.net",
|
|
||||||
ServiceBusEndpointSuffix: "servicebus.windows.net",
|
|
||||||
ServiceManagementVMDNSSuffix: "cloudapp.net",
|
|
||||||
ResourceManagerVMDNSSuffix: "cloudapp.azure.com",
|
|
||||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
|
||||||
TokenAudience: "https://management.azure.com/",
|
|
||||||
APIManagementHostNameSuffix: "azure-api.net",
|
|
||||||
SynapseEndpointSuffix: "dev.azuresynapse.net",
|
|
||||||
DatalakeSuffix: "azuredatalakestore.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",
|
|
||||||
OSSRDBMS: "https://ossrdbms-aad.database.windows.net",
|
|
||||||
Storage: "https://storage.azure.com/",
|
|
||||||
Synapse: "https://dev.azuresynapse.net",
|
|
||||||
ServiceBus: "https://servicebus.azure.net/",
|
|
||||||
SQLDatabase: "https://database.windows.net/",
|
|
||||||
CosmosDB: "https://cosmos.azure.com",
|
|
||||||
ManagedHSM: "https://managedhsm.azure.net",
|
|
||||||
MicrosoftGraph: "https://graph.microsoft.com/",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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/",
|
|
||||||
ManagedHSMEndpoint: NotAvailable,
|
|
||||||
GraphEndpoint: "https://graph.windows.net/",
|
|
||||||
ServiceBusEndpoint: "https://servicebus.usgovcloudapi.net/",
|
|
||||||
BatchManagementEndpoint: "https://batch.core.usgovcloudapi.net/",
|
|
||||||
MicrosoftGraphEndpoint: "https://graph.microsoft.us/",
|
|
||||||
StorageEndpointSuffix: "core.usgovcloudapi.net",
|
|
||||||
CosmosDBDNSSuffix: "documents.azure.us",
|
|
||||||
MariaDBDNSSuffix: "mariadb.database.usgovcloudapi.net",
|
|
||||||
MySQLDatabaseDNSSuffix: "mysql.database.usgovcloudapi.net",
|
|
||||||
PostgresqlDatabaseDNSSuffix: "postgres.database.usgovcloudapi.net",
|
|
||||||
SQLDatabaseDNSSuffix: "database.usgovcloudapi.net",
|
|
||||||
TrafficManagerDNSSuffix: "usgovtrafficmanager.net",
|
|
||||||
KeyVaultDNSSuffix: "vault.usgovcloudapi.net",
|
|
||||||
ManagedHSMDNSSuffix: NotAvailable,
|
|
||||||
ServiceBusEndpointSuffix: "servicebus.usgovcloudapi.net",
|
|
||||||
ServiceManagementVMDNSSuffix: "usgovcloudapp.net",
|
|
||||||
ResourceManagerVMDNSSuffix: "cloudapp.usgovcloudapi.net",
|
|
||||||
ContainerRegistryDNSSuffix: "azurecr.us",
|
|
||||||
TokenAudience: "https://management.usgovcloudapi.net/",
|
|
||||||
APIManagementHostNameSuffix: "azure-api.us",
|
|
||||||
SynapseEndpointSuffix: "dev.azuresynapse.usgovcloudapi.net",
|
|
||||||
DatalakeSuffix: 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",
|
|
||||||
OSSRDBMS: "https://ossrdbms-aad.database.usgovcloudapi.net",
|
|
||||||
Storage: "https://storage.azure.com/",
|
|
||||||
Synapse: "https://dev.azuresynapse.usgovcloudapi.net",
|
|
||||||
ServiceBus: "https://servicebus.azure.net/",
|
|
||||||
SQLDatabase: "https://database.usgovcloudapi.net/",
|
|
||||||
CosmosDB: "https://cosmos.azure.com",
|
|
||||||
ManagedHSM: NotAvailable,
|
|
||||||
MicrosoftGraph: "https://graph.microsoft.us/",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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/",
|
|
||||||
ManagedHSMEndpoint: NotAvailable,
|
|
||||||
GraphEndpoint: "https://graph.chinacloudapi.cn/",
|
|
||||||
ServiceBusEndpoint: "https://servicebus.chinacloudapi.cn/",
|
|
||||||
BatchManagementEndpoint: "https://batch.chinacloudapi.cn/",
|
|
||||||
MicrosoftGraphEndpoint: "https://microsoftgraph.chinacloudapi.cn/",
|
|
||||||
StorageEndpointSuffix: "core.chinacloudapi.cn",
|
|
||||||
CosmosDBDNSSuffix: "documents.azure.cn",
|
|
||||||
MariaDBDNSSuffix: "mariadb.database.chinacloudapi.cn",
|
|
||||||
MySQLDatabaseDNSSuffix: "mysql.database.chinacloudapi.cn",
|
|
||||||
PostgresqlDatabaseDNSSuffix: "postgres.database.chinacloudapi.cn",
|
|
||||||
SQLDatabaseDNSSuffix: "database.chinacloudapi.cn",
|
|
||||||
TrafficManagerDNSSuffix: "trafficmanager.cn",
|
|
||||||
KeyVaultDNSSuffix: "vault.azure.cn",
|
|
||||||
ManagedHSMDNSSuffix: NotAvailable,
|
|
||||||
ServiceBusEndpointSuffix: "servicebus.chinacloudapi.cn",
|
|
||||||
ServiceManagementVMDNSSuffix: "chinacloudapp.cn",
|
|
||||||
ResourceManagerVMDNSSuffix: "cloudapp.chinacloudapi.cn",
|
|
||||||
ContainerRegistryDNSSuffix: "azurecr.cn",
|
|
||||||
TokenAudience: "https://management.chinacloudapi.cn/",
|
|
||||||
APIManagementHostNameSuffix: "azure-api.cn",
|
|
||||||
SynapseEndpointSuffix: "dev.azuresynapse.azure.cn",
|
|
||||||
DatalakeSuffix: NotAvailable,
|
|
||||||
ResourceIdentifiers: ResourceIdentifier{
|
|
||||||
Graph: "https://graph.chinacloudapi.cn/",
|
|
||||||
KeyVault: "https://vault.azure.cn",
|
|
||||||
Datalake: NotAvailable,
|
|
||||||
Batch: "https://batch.chinacloudapi.cn/",
|
|
||||||
OperationalInsights: NotAvailable,
|
|
||||||
OSSRDBMS: "https://ossrdbms-aad.database.chinacloudapi.cn",
|
|
||||||
Storage: "https://storage.azure.com/",
|
|
||||||
Synapse: "https://dev.azuresynapse.net",
|
|
||||||
ServiceBus: "https://servicebus.azure.net/",
|
|
||||||
SQLDatabase: "https://database.chinacloudapi.cn/",
|
|
||||||
CosmosDB: "https://cosmos.azure.com",
|
|
||||||
ManagedHSM: NotAvailable,
|
|
||||||
MicrosoftGraph: "https://microsoftgraph.chinacloudapi.cn",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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/",
|
|
||||||
ManagedHSMEndpoint: NotAvailable,
|
|
||||||
GraphEndpoint: "https://graph.cloudapi.de/",
|
|
||||||
ServiceBusEndpoint: "https://servicebus.cloudapi.de/",
|
|
||||||
BatchManagementEndpoint: "https://batch.cloudapi.de/",
|
|
||||||
MicrosoftGraphEndpoint: NotAvailable,
|
|
||||||
StorageEndpointSuffix: "core.cloudapi.de",
|
|
||||||
CosmosDBDNSSuffix: "documents.microsoftazure.de",
|
|
||||||
MariaDBDNSSuffix: "mariadb.database.cloudapi.de",
|
|
||||||
MySQLDatabaseDNSSuffix: "mysql.database.cloudapi.de",
|
|
||||||
PostgresqlDatabaseDNSSuffix: "postgres.database.cloudapi.de",
|
|
||||||
SQLDatabaseDNSSuffix: "database.cloudapi.de",
|
|
||||||
TrafficManagerDNSSuffix: "azuretrafficmanager.de",
|
|
||||||
KeyVaultDNSSuffix: "vault.microsoftazure.de",
|
|
||||||
ManagedHSMDNSSuffix: NotAvailable,
|
|
||||||
ServiceBusEndpointSuffix: "servicebus.cloudapi.de",
|
|
||||||
ServiceManagementVMDNSSuffix: "azurecloudapp.de",
|
|
||||||
ResourceManagerVMDNSSuffix: "cloudapp.microsoftazure.de",
|
|
||||||
ContainerRegistryDNSSuffix: NotAvailable,
|
|
||||||
TokenAudience: "https://management.microsoftazure.de/",
|
|
||||||
APIManagementHostNameSuffix: NotAvailable,
|
|
||||||
SynapseEndpointSuffix: NotAvailable,
|
|
||||||
DatalakeSuffix: NotAvailable,
|
|
||||||
ResourceIdentifiers: ResourceIdentifier{
|
|
||||||
Graph: "https://graph.cloudapi.de/",
|
|
||||||
KeyVault: "https://vault.microsoftazure.de",
|
|
||||||
Datalake: NotAvailable,
|
|
||||||
Batch: "https://batch.cloudapi.de/",
|
|
||||||
OperationalInsights: NotAvailable,
|
|
||||||
OSSRDBMS: "https://ossrdbms-aad.database.cloudapi.de",
|
|
||||||
Storage: "https://storage.azure.com/",
|
|
||||||
Synapse: NotAvailable,
|
|
||||||
ServiceBus: "https://servicebus.azure.net/",
|
|
||||||
SQLDatabase: "https://database.cloudapi.de/",
|
|
||||||
CosmosDB: "https://cosmos.azure.com",
|
|
||||||
ManagedHSM: NotAvailable,
|
|
||||||
MicrosoftGraph: NotAvailable,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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: %w", 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 = 30 * 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
|
|
||||||
}
|
|
||||||
25
vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go
generated
vendored
25
vendor/github.com/Azure/go-autorest/autorest/go_mod_tidy_hack.go
generated
vendored
@@ -1,25 +0,0 @@
|
|||||||
//go:build modhack
|
|
||||||
// +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"
|
|
||||||
549
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
549
vendor/github.com/Azure/go-autorest/autorest/preparer.go
generated
vendored
@@ -1,549 +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 != "" {
|
|
||||||
// handle unencoded semicolons (ideally the server would send them already encoded)
|
|
||||||
u.RawQuery = strings.Replace(u.RawQuery, ";", "%3B", -1)
|
|
||||||
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
|
|
||||||
}
|
|
||||||
55
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
55
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.7.go
generated
vendored
@@ -1,55 +0,0 @@
|
|||||||
//go:build !go1.8
|
|
||||||
// +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
|
|
||||||
}
|
|
||||||
67
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
67
vendor/github.com/Azure/go-autorest/autorest/retriablerequest_1.8.go
generated
vendored
@@ -1,67 +0,0 @@
|
|||||||
//go:build go1.8
|
|
||||||
// +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
|
|
||||||
}
|
|
||||||
458
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
458
vendor/github.com/Azure/go-autorest/autorest/sender.go
generated
vendored
@@ -1,458 +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"
|
|
||||||
"net/http"
|
|
||||||
"net/http/cookiejar"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Azure/go-autorest/logger"
|
|
||||||
"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() {
|
|
||||||
// copied from http.DefaultTransport with a TLS minimum version.
|
|
||||||
transport := &http.Transport{
|
|
||||||
Proxy: http.ProxyFromEnvironment,
|
|
||||||
DialContext: (&net.Dialer{
|
|
||||||
Timeout: 30 * time.Second,
|
|
||||||
KeepAlive: 30 * time.Second,
|
|
||||||
}).DialContext,
|
|
||||||
ForceAttemptHTTP2: true,
|
|
||||||
MaxIdleConns: 100,
|
|
||||||
IdleConnTimeout: 90 * time.Second,
|
|
||||||
TLSHandshakeTimeout: 10 * time.Second,
|
|
||||||
ExpectContinueTimeout: 1 * time.Second,
|
|
||||||
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
|
|
||||||
}
|
|
||||||
logger.Instance.Writef(logger.LogError, "DoRetryForAttempts: received error for attempt %d: %v\n", attempt+1, 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
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
logger.Instance.Writef(logger.LogError, "DoRetryForStatusCodes: received error for attempt %d: %v\n", attempt+1, 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
|
|
||||||
}
|
|
||||||
logger.Instance.Writef(logger.LogError, "DoRetryForDuration: received error for attempt %d: %v\n", attempt+1, 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
|
|
||||||
}
|
|
||||||
logger.Instance.Writef(logger.LogInfo, "DelayForBackoffWithCap: sleeping for %s\n", d)
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
30
vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go
generated
vendored
30
vendor/github.com/Azure/go-autorest/autorest/utility_1.13.go
generated
vendored
@@ -1,30 +0,0 @@
|
|||||||
//go:build go1.13
|
|
||||||
// +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)
|
|
||||||
}
|
|
||||||
32
vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go
generated
vendored
32
vendor/github.com/Azure/go-autorest/autorest/utility_legacy.go
generated
vendored
@@ -1,32 +0,0 @@
|
|||||||
//go:build !go1.13
|
|
||||||
// +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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
29
vendor/github.com/cespare/xxhash/v2/README.md
generated
vendored
29
vendor/github.com/cespare/xxhash/v2/README.md
generated
vendored
@@ -3,8 +3,7 @@
|
|||||||
[](https://pkg.go.dev/github.com/cespare/xxhash/v2)
|
[](https://pkg.go.dev/github.com/cespare/xxhash/v2)
|
||||||
[](https://github.com/cespare/xxhash/actions/workflows/test.yml)
|
[](https://github.com/cespare/xxhash/actions/workflows/test.yml)
|
||||||
|
|
||||||
xxhash is a Go implementation of the 64-bit
|
xxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a
|
||||||
[xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a
|
|
||||||
high-quality hashing algorithm that is much faster than anything in the Go
|
high-quality hashing algorithm that is much faster than anything in the Go
|
||||||
standard library.
|
standard library.
|
||||||
|
|
||||||
@@ -25,8 +24,11 @@ func (*Digest) WriteString(string) (int, error)
|
|||||||
func (*Digest) Sum64() uint64
|
func (*Digest) Sum64() uint64
|
||||||
```
|
```
|
||||||
|
|
||||||
This implementation provides a fast pure-Go implementation and an even faster
|
The package is written with optimized pure Go and also contains even faster
|
||||||
assembly implementation for amd64.
|
assembly implementations for amd64 and arm64. If desired, the `purego` build tag
|
||||||
|
opts into using the Go code even on those architectures.
|
||||||
|
|
||||||
|
[xxHash]: http://cyan4973.github.io/xxHash/
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
@@ -46,18 +48,19 @@ Here are some quick benchmarks comparing the pure-Go and assembly
|
|||||||
implementations of Sum64.
|
implementations of Sum64.
|
||||||
|
|
||||||
| input size | purego | asm |
|
| input size | purego | asm |
|
||||||
| --- | --- | --- |
|
| ---------- | --------- | --------- |
|
||||||
| 5 B | 979.66 MB/s | 1291.17 MB/s |
|
| 4 B | 1.3 GB/s | 1.2 GB/s |
|
||||||
| 100 B | 7475.26 MB/s | 7973.40 MB/s |
|
| 16 B | 2.9 GB/s | 3.5 GB/s |
|
||||||
| 4 KB | 17573.46 MB/s | 17602.65 MB/s |
|
| 100 B | 6.9 GB/s | 8.1 GB/s |
|
||||||
| 10 MB | 17131.46 MB/s | 17142.16 MB/s |
|
| 4 KB | 11.7 GB/s | 16.7 GB/s |
|
||||||
|
| 10 MB | 12.0 GB/s | 17.3 GB/s |
|
||||||
|
|
||||||
These numbers were generated on Ubuntu 18.04 with an Intel i7-8700K CPU using
|
These numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C
|
||||||
the following commands under Go 1.11.2:
|
CPU using the following commands under Go 1.19.2:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ go test -tags purego -benchtime 10s -bench '/xxhash,direct,bytes'
|
benchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$')
|
||||||
$ go test -benchtime 10s -bench '/xxhash,direct,bytes'
|
benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$')
|
||||||
```
|
```
|
||||||
|
|
||||||
## Projects using this package
|
## Projects using this package
|
||||||
|
|||||||
10
vendor/github.com/cespare/xxhash/v2/testall.sh
generated
vendored
Normal file
10
vendor/github.com/cespare/xxhash/v2/testall.sh
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -eu -o pipefail
|
||||||
|
|
||||||
|
# Small convenience script for running the tests with various combinations of
|
||||||
|
# arch/tags. This assumes we're running on amd64 and have qemu available.
|
||||||
|
|
||||||
|
go test ./...
|
||||||
|
go test -tags purego ./...
|
||||||
|
GOARCH=arm64 go test
|
||||||
|
GOARCH=arm64 go test -tags purego
|
||||||
47
vendor/github.com/cespare/xxhash/v2/xxhash.go
generated
vendored
47
vendor/github.com/cespare/xxhash/v2/xxhash.go
generated
vendored
@@ -16,19 +16,11 @@ const (
|
|||||||
prime5 uint64 = 2870177450012600261
|
prime5 uint64 = 2870177450012600261
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where
|
// Store the primes in an array as well.
|
||||||
// possible in the Go code is worth a small (but measurable) performance boost
|
//
|
||||||
// by avoiding some MOVQs. Vars are needed for the asm and also are useful for
|
// The consts are used when possible in Go code to avoid MOVs but we need a
|
||||||
// convenience in the Go code in a few places where we need to intentionally
|
// contiguous array of the assembly code.
|
||||||
// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the
|
var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5}
|
||||||
// result overflows a uint64).
|
|
||||||
var (
|
|
||||||
prime1v = prime1
|
|
||||||
prime2v = prime2
|
|
||||||
prime3v = prime3
|
|
||||||
prime4v = prime4
|
|
||||||
prime5v = prime5
|
|
||||||
)
|
|
||||||
|
|
||||||
// Digest implements hash.Hash64.
|
// Digest implements hash.Hash64.
|
||||||
type Digest struct {
|
type Digest struct {
|
||||||
@@ -50,10 +42,10 @@ func New() *Digest {
|
|||||||
|
|
||||||
// Reset clears the Digest's state so that it can be reused.
|
// Reset clears the Digest's state so that it can be reused.
|
||||||
func (d *Digest) Reset() {
|
func (d *Digest) Reset() {
|
||||||
d.v1 = prime1v + prime2
|
d.v1 = primes[0] + prime2
|
||||||
d.v2 = prime2
|
d.v2 = prime2
|
||||||
d.v3 = 0
|
d.v3 = 0
|
||||||
d.v4 = -prime1v
|
d.v4 = -primes[0]
|
||||||
d.total = 0
|
d.total = 0
|
||||||
d.n = 0
|
d.n = 0
|
||||||
}
|
}
|
||||||
@@ -69,21 +61,23 @@ func (d *Digest) Write(b []byte) (n int, err error) {
|
|||||||
n = len(b)
|
n = len(b)
|
||||||
d.total += uint64(n)
|
d.total += uint64(n)
|
||||||
|
|
||||||
|
memleft := d.mem[d.n&(len(d.mem)-1):]
|
||||||
|
|
||||||
if d.n+n < 32 {
|
if d.n+n < 32 {
|
||||||
// This new data doesn't even fill the current block.
|
// This new data doesn't even fill the current block.
|
||||||
copy(d.mem[d.n:], b)
|
copy(memleft, b)
|
||||||
d.n += n
|
d.n += n
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.n > 0 {
|
if d.n > 0 {
|
||||||
// Finish off the partial block.
|
// Finish off the partial block.
|
||||||
copy(d.mem[d.n:], b)
|
c := copy(memleft, b)
|
||||||
d.v1 = round(d.v1, u64(d.mem[0:8]))
|
d.v1 = round(d.v1, u64(d.mem[0:8]))
|
||||||
d.v2 = round(d.v2, u64(d.mem[8:16]))
|
d.v2 = round(d.v2, u64(d.mem[8:16]))
|
||||||
d.v3 = round(d.v3, u64(d.mem[16:24]))
|
d.v3 = round(d.v3, u64(d.mem[16:24]))
|
||||||
d.v4 = round(d.v4, u64(d.mem[24:32]))
|
d.v4 = round(d.v4, u64(d.mem[24:32]))
|
||||||
b = b[32-d.n:]
|
b = b[c:]
|
||||||
d.n = 0
|
d.n = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,21 +127,20 @@ func (d *Digest) Sum64() uint64 {
|
|||||||
|
|
||||||
h += d.total
|
h += d.total
|
||||||
|
|
||||||
i, end := 0, d.n
|
b := d.mem[:d.n&(len(d.mem)-1)]
|
||||||
for ; i+8 <= end; i += 8 {
|
for ; len(b) >= 8; b = b[8:] {
|
||||||
k1 := round(0, u64(d.mem[i:i+8]))
|
k1 := round(0, u64(b[:8]))
|
||||||
h ^= k1
|
h ^= k1
|
||||||
h = rol27(h)*prime1 + prime4
|
h = rol27(h)*prime1 + prime4
|
||||||
}
|
}
|
||||||
if i+4 <= end {
|
if len(b) >= 4 {
|
||||||
h ^= uint64(u32(d.mem[i:i+4])) * prime1
|
h ^= uint64(u32(b[:4])) * prime1
|
||||||
h = rol23(h)*prime2 + prime3
|
h = rol23(h)*prime2 + prime3
|
||||||
i += 4
|
b = b[4:]
|
||||||
}
|
}
|
||||||
for i < end {
|
for ; len(b) > 0; b = b[1:] {
|
||||||
h ^= uint64(d.mem[i]) * prime5
|
h ^= uint64(b[0]) * prime5
|
||||||
h = rol11(h) * prime1
|
h = rol11(h) * prime1
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h ^= h >> 33
|
h ^= h >> 33
|
||||||
|
|||||||
308
vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s
generated
vendored
308
vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s
generated
vendored
@@ -1,215 +1,209 @@
|
|||||||
|
//go:build !appengine && gc && !purego
|
||||||
// +build !appengine
|
// +build !appengine
|
||||||
// +build gc
|
// +build gc
|
||||||
// +build !purego
|
// +build !purego
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
// Register allocation:
|
// Registers:
|
||||||
// AX h
|
#define h AX
|
||||||
// SI pointer to advance through b
|
#define d AX
|
||||||
// DX n
|
#define p SI // pointer to advance through b
|
||||||
// BX loop end
|
#define n DX
|
||||||
// R8 v1, k1
|
#define end BX // loop end
|
||||||
// R9 v2
|
#define v1 R8
|
||||||
// R10 v3
|
#define v2 R9
|
||||||
// R11 v4
|
#define v3 R10
|
||||||
// R12 tmp
|
#define v4 R11
|
||||||
// R13 prime1v
|
#define x R12
|
||||||
// R14 prime2v
|
#define prime1 R13
|
||||||
// DI prime4v
|
#define prime2 R14
|
||||||
|
#define prime4 DI
|
||||||
|
|
||||||
// round reads from and advances the buffer pointer in SI.
|
#define round(acc, x) \
|
||||||
// It assumes that R13 has prime1v and R14 has prime2v.
|
IMULQ prime2, x \
|
||||||
#define round(r) \
|
ADDQ x, acc \
|
||||||
MOVQ (SI), R12 \
|
ROLQ $31, acc \
|
||||||
ADDQ $8, SI \
|
IMULQ prime1, acc
|
||||||
IMULQ R14, R12 \
|
|
||||||
ADDQ R12, r \
|
|
||||||
ROLQ $31, r \
|
|
||||||
IMULQ R13, r
|
|
||||||
|
|
||||||
// mergeRound applies a merge round on the two registers acc and val.
|
// round0 performs the operation x = round(0, x).
|
||||||
// It assumes that R13 has prime1v, R14 has prime2v, and DI has prime4v.
|
#define round0(x) \
|
||||||
#define mergeRound(acc, val) \
|
IMULQ prime2, x \
|
||||||
IMULQ R14, val \
|
ROLQ $31, x \
|
||||||
ROLQ $31, val \
|
IMULQ prime1, x
|
||||||
IMULQ R13, val \
|
|
||||||
XORQ val, acc \
|
// mergeRound applies a merge round on the two registers acc and x.
|
||||||
IMULQ R13, acc \
|
// It assumes that prime1, prime2, and prime4 have been loaded.
|
||||||
ADDQ DI, acc
|
#define mergeRound(acc, x) \
|
||||||
|
round0(x) \
|
||||||
|
XORQ x, acc \
|
||||||
|
IMULQ prime1, acc \
|
||||||
|
ADDQ prime4, acc
|
||||||
|
|
||||||
|
// blockLoop processes as many 32-byte blocks as possible,
|
||||||
|
// updating v1, v2, v3, and v4. It assumes that there is at least one block
|
||||||
|
// to process.
|
||||||
|
#define blockLoop() \
|
||||||
|
loop: \
|
||||||
|
MOVQ +0(p), x \
|
||||||
|
round(v1, x) \
|
||||||
|
MOVQ +8(p), x \
|
||||||
|
round(v2, x) \
|
||||||
|
MOVQ +16(p), x \
|
||||||
|
round(v3, x) \
|
||||||
|
MOVQ +24(p), x \
|
||||||
|
round(v4, x) \
|
||||||
|
ADDQ $32, p \
|
||||||
|
CMPQ p, end \
|
||||||
|
JLE loop
|
||||||
|
|
||||||
// func Sum64(b []byte) uint64
|
// func Sum64(b []byte) uint64
|
||||||
TEXT ·Sum64(SB), NOSPLIT, $0-32
|
TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32
|
||||||
// Load fixed primes.
|
// Load fixed primes.
|
||||||
MOVQ ·prime1v(SB), R13
|
MOVQ ·primes+0(SB), prime1
|
||||||
MOVQ ·prime2v(SB), R14
|
MOVQ ·primes+8(SB), prime2
|
||||||
MOVQ ·prime4v(SB), DI
|
MOVQ ·primes+24(SB), prime4
|
||||||
|
|
||||||
// Load slice.
|
// Load slice.
|
||||||
MOVQ b_base+0(FP), SI
|
MOVQ b_base+0(FP), p
|
||||||
MOVQ b_len+8(FP), DX
|
MOVQ b_len+8(FP), n
|
||||||
LEAQ (SI)(DX*1), BX
|
LEAQ (p)(n*1), end
|
||||||
|
|
||||||
// The first loop limit will be len(b)-32.
|
// The first loop limit will be len(b)-32.
|
||||||
SUBQ $32, BX
|
SUBQ $32, end
|
||||||
|
|
||||||
// Check whether we have at least one block.
|
// Check whether we have at least one block.
|
||||||
CMPQ DX, $32
|
CMPQ n, $32
|
||||||
JLT noBlocks
|
JLT noBlocks
|
||||||
|
|
||||||
// Set up initial state (v1, v2, v3, v4).
|
// Set up initial state (v1, v2, v3, v4).
|
||||||
MOVQ R13, R8
|
MOVQ prime1, v1
|
||||||
ADDQ R14, R8
|
ADDQ prime2, v1
|
||||||
MOVQ R14, R9
|
MOVQ prime2, v2
|
||||||
XORQ R10, R10
|
XORQ v3, v3
|
||||||
XORQ R11, R11
|
XORQ v4, v4
|
||||||
SUBQ R13, R11
|
SUBQ prime1, v4
|
||||||
|
|
||||||
// Loop until SI > BX.
|
blockLoop()
|
||||||
blockLoop:
|
|
||||||
round(R8)
|
|
||||||
round(R9)
|
|
||||||
round(R10)
|
|
||||||
round(R11)
|
|
||||||
|
|
||||||
CMPQ SI, BX
|
MOVQ v1, h
|
||||||
JLE blockLoop
|
ROLQ $1, h
|
||||||
|
MOVQ v2, x
|
||||||
|
ROLQ $7, x
|
||||||
|
ADDQ x, h
|
||||||
|
MOVQ v3, x
|
||||||
|
ROLQ $12, x
|
||||||
|
ADDQ x, h
|
||||||
|
MOVQ v4, x
|
||||||
|
ROLQ $18, x
|
||||||
|
ADDQ x, h
|
||||||
|
|
||||||
MOVQ R8, AX
|
mergeRound(h, v1)
|
||||||
ROLQ $1, AX
|
mergeRound(h, v2)
|
||||||
MOVQ R9, R12
|
mergeRound(h, v3)
|
||||||
ROLQ $7, R12
|
mergeRound(h, v4)
|
||||||
ADDQ R12, AX
|
|
||||||
MOVQ R10, R12
|
|
||||||
ROLQ $12, R12
|
|
||||||
ADDQ R12, AX
|
|
||||||
MOVQ R11, R12
|
|
||||||
ROLQ $18, R12
|
|
||||||
ADDQ R12, AX
|
|
||||||
|
|
||||||
mergeRound(AX, R8)
|
|
||||||
mergeRound(AX, R9)
|
|
||||||
mergeRound(AX, R10)
|
|
||||||
mergeRound(AX, R11)
|
|
||||||
|
|
||||||
JMP afterBlocks
|
JMP afterBlocks
|
||||||
|
|
||||||
noBlocks:
|
noBlocks:
|
||||||
MOVQ ·prime5v(SB), AX
|
MOVQ ·primes+32(SB), h
|
||||||
|
|
||||||
afterBlocks:
|
afterBlocks:
|
||||||
ADDQ DX, AX
|
ADDQ n, h
|
||||||
|
|
||||||
// Right now BX has len(b)-32, and we want to loop until SI > len(b)-8.
|
ADDQ $24, end
|
||||||
ADDQ $24, BX
|
CMPQ p, end
|
||||||
|
JG try4
|
||||||
|
|
||||||
CMPQ SI, BX
|
loop8:
|
||||||
JG fourByte
|
MOVQ (p), x
|
||||||
|
ADDQ $8, p
|
||||||
|
round0(x)
|
||||||
|
XORQ x, h
|
||||||
|
ROLQ $27, h
|
||||||
|
IMULQ prime1, h
|
||||||
|
ADDQ prime4, h
|
||||||
|
|
||||||
wordLoop:
|
CMPQ p, end
|
||||||
// Calculate k1.
|
JLE loop8
|
||||||
MOVQ (SI), R8
|
|
||||||
ADDQ $8, SI
|
|
||||||
IMULQ R14, R8
|
|
||||||
ROLQ $31, R8
|
|
||||||
IMULQ R13, R8
|
|
||||||
|
|
||||||
XORQ R8, AX
|
try4:
|
||||||
ROLQ $27, AX
|
ADDQ $4, end
|
||||||
IMULQ R13, AX
|
CMPQ p, end
|
||||||
ADDQ DI, AX
|
JG try1
|
||||||
|
|
||||||
CMPQ SI, BX
|
MOVL (p), x
|
||||||
JLE wordLoop
|
ADDQ $4, p
|
||||||
|
IMULQ prime1, x
|
||||||
|
XORQ x, h
|
||||||
|
|
||||||
fourByte:
|
ROLQ $23, h
|
||||||
ADDQ $4, BX
|
IMULQ prime2, h
|
||||||
CMPQ SI, BX
|
ADDQ ·primes+16(SB), h
|
||||||
JG singles
|
|
||||||
|
|
||||||
MOVL (SI), R8
|
try1:
|
||||||
ADDQ $4, SI
|
ADDQ $4, end
|
||||||
IMULQ R13, R8
|
CMPQ p, end
|
||||||
XORQ R8, AX
|
|
||||||
|
|
||||||
ROLQ $23, AX
|
|
||||||
IMULQ R14, AX
|
|
||||||
ADDQ ·prime3v(SB), AX
|
|
||||||
|
|
||||||
singles:
|
|
||||||
ADDQ $4, BX
|
|
||||||
CMPQ SI, BX
|
|
||||||
JGE finalize
|
JGE finalize
|
||||||
|
|
||||||
singlesLoop:
|
loop1:
|
||||||
MOVBQZX (SI), R12
|
MOVBQZX (p), x
|
||||||
ADDQ $1, SI
|
ADDQ $1, p
|
||||||
IMULQ ·prime5v(SB), R12
|
IMULQ ·primes+32(SB), x
|
||||||
XORQ R12, AX
|
XORQ x, h
|
||||||
|
ROLQ $11, h
|
||||||
|
IMULQ prime1, h
|
||||||
|
|
||||||
ROLQ $11, AX
|
CMPQ p, end
|
||||||
IMULQ R13, AX
|
JL loop1
|
||||||
|
|
||||||
CMPQ SI, BX
|
|
||||||
JL singlesLoop
|
|
||||||
|
|
||||||
finalize:
|
finalize:
|
||||||
MOVQ AX, R12
|
MOVQ h, x
|
||||||
SHRQ $33, R12
|
SHRQ $33, x
|
||||||
XORQ R12, AX
|
XORQ x, h
|
||||||
IMULQ R14, AX
|
IMULQ prime2, h
|
||||||
MOVQ AX, R12
|
MOVQ h, x
|
||||||
SHRQ $29, R12
|
SHRQ $29, x
|
||||||
XORQ R12, AX
|
XORQ x, h
|
||||||
IMULQ ·prime3v(SB), AX
|
IMULQ ·primes+16(SB), h
|
||||||
MOVQ AX, R12
|
MOVQ h, x
|
||||||
SHRQ $32, R12
|
SHRQ $32, x
|
||||||
XORQ R12, AX
|
XORQ x, h
|
||||||
|
|
||||||
MOVQ AX, ret+24(FP)
|
MOVQ h, ret+24(FP)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// writeBlocks uses the same registers as above except that it uses AX to store
|
|
||||||
// the d pointer.
|
|
||||||
|
|
||||||
// func writeBlocks(d *Digest, b []byte) int
|
// func writeBlocks(d *Digest, b []byte) int
|
||||||
TEXT ·writeBlocks(SB), NOSPLIT, $0-40
|
TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40
|
||||||
// Load fixed primes needed for round.
|
// Load fixed primes needed for round.
|
||||||
MOVQ ·prime1v(SB), R13
|
MOVQ ·primes+0(SB), prime1
|
||||||
MOVQ ·prime2v(SB), R14
|
MOVQ ·primes+8(SB), prime2
|
||||||
|
|
||||||
// Load slice.
|
// Load slice.
|
||||||
MOVQ b_base+8(FP), SI
|
MOVQ b_base+8(FP), p
|
||||||
MOVQ b_len+16(FP), DX
|
MOVQ b_len+16(FP), n
|
||||||
LEAQ (SI)(DX*1), BX
|
LEAQ (p)(n*1), end
|
||||||
SUBQ $32, BX
|
SUBQ $32, end
|
||||||
|
|
||||||
// Load vN from d.
|
// Load vN from d.
|
||||||
MOVQ d+0(FP), AX
|
MOVQ s+0(FP), d
|
||||||
MOVQ 0(AX), R8 // v1
|
MOVQ 0(d), v1
|
||||||
MOVQ 8(AX), R9 // v2
|
MOVQ 8(d), v2
|
||||||
MOVQ 16(AX), R10 // v3
|
MOVQ 16(d), v3
|
||||||
MOVQ 24(AX), R11 // v4
|
MOVQ 24(d), v4
|
||||||
|
|
||||||
// We don't need to check the loop condition here; this function is
|
// We don't need to check the loop condition here; this function is
|
||||||
// always called with at least one block of data to process.
|
// always called with at least one block of data to process.
|
||||||
blockLoop:
|
blockLoop()
|
||||||
round(R8)
|
|
||||||
round(R9)
|
|
||||||
round(R10)
|
|
||||||
round(R11)
|
|
||||||
|
|
||||||
CMPQ SI, BX
|
|
||||||
JLE blockLoop
|
|
||||||
|
|
||||||
// Copy vN back to d.
|
// Copy vN back to d.
|
||||||
MOVQ R8, 0(AX)
|
MOVQ v1, 0(d)
|
||||||
MOVQ R9, 8(AX)
|
MOVQ v2, 8(d)
|
||||||
MOVQ R10, 16(AX)
|
MOVQ v3, 16(d)
|
||||||
MOVQ R11, 24(AX)
|
MOVQ v4, 24(d)
|
||||||
|
|
||||||
// The number of bytes written is SI minus the old base pointer.
|
// The number of bytes written is p minus the old base pointer.
|
||||||
SUBQ b_base+8(FP), SI
|
SUBQ b_base+8(FP), p
|
||||||
MOVQ SI, ret+32(FP)
|
MOVQ p, ret+32(FP)
|
||||||
|
|
||||||
RET
|
RET
|
||||||
|
|||||||
183
vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s
generated
vendored
Normal file
183
vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
//go:build !appengine && gc && !purego
|
||||||
|
// +build !appengine
|
||||||
|
// +build gc
|
||||||
|
// +build !purego
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// Registers:
|
||||||
|
#define digest R1
|
||||||
|
#define h R2 // return value
|
||||||
|
#define p R3 // input pointer
|
||||||
|
#define n R4 // input length
|
||||||
|
#define nblocks R5 // n / 32
|
||||||
|
#define prime1 R7
|
||||||
|
#define prime2 R8
|
||||||
|
#define prime3 R9
|
||||||
|
#define prime4 R10
|
||||||
|
#define prime5 R11
|
||||||
|
#define v1 R12
|
||||||
|
#define v2 R13
|
||||||
|
#define v3 R14
|
||||||
|
#define v4 R15
|
||||||
|
#define x1 R20
|
||||||
|
#define x2 R21
|
||||||
|
#define x3 R22
|
||||||
|
#define x4 R23
|
||||||
|
|
||||||
|
#define round(acc, x) \
|
||||||
|
MADD prime2, acc, x, acc \
|
||||||
|
ROR $64-31, acc \
|
||||||
|
MUL prime1, acc
|
||||||
|
|
||||||
|
// round0 performs the operation x = round(0, x).
|
||||||
|
#define round0(x) \
|
||||||
|
MUL prime2, x \
|
||||||
|
ROR $64-31, x \
|
||||||
|
MUL prime1, x
|
||||||
|
|
||||||
|
#define mergeRound(acc, x) \
|
||||||
|
round0(x) \
|
||||||
|
EOR x, acc \
|
||||||
|
MADD acc, prime4, prime1, acc
|
||||||
|
|
||||||
|
// blockLoop processes as many 32-byte blocks as possible,
|
||||||
|
// updating v1, v2, v3, and v4. It assumes that n >= 32.
|
||||||
|
#define blockLoop() \
|
||||||
|
LSR $5, n, nblocks \
|
||||||
|
PCALIGN $16 \
|
||||||
|
loop: \
|
||||||
|
LDP.P 16(p), (x1, x2) \
|
||||||
|
LDP.P 16(p), (x3, x4) \
|
||||||
|
round(v1, x1) \
|
||||||
|
round(v2, x2) \
|
||||||
|
round(v3, x3) \
|
||||||
|
round(v4, x4) \
|
||||||
|
SUB $1, nblocks \
|
||||||
|
CBNZ nblocks, loop
|
||||||
|
|
||||||
|
// func Sum64(b []byte) uint64
|
||||||
|
TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32
|
||||||
|
LDP b_base+0(FP), (p, n)
|
||||||
|
|
||||||
|
LDP ·primes+0(SB), (prime1, prime2)
|
||||||
|
LDP ·primes+16(SB), (prime3, prime4)
|
||||||
|
MOVD ·primes+32(SB), prime5
|
||||||
|
|
||||||
|
CMP $32, n
|
||||||
|
CSEL LT, prime5, ZR, h // if n < 32 { h = prime5 } else { h = 0 }
|
||||||
|
BLT afterLoop
|
||||||
|
|
||||||
|
ADD prime1, prime2, v1
|
||||||
|
MOVD prime2, v2
|
||||||
|
MOVD $0, v3
|
||||||
|
NEG prime1, v4
|
||||||
|
|
||||||
|
blockLoop()
|
||||||
|
|
||||||
|
ROR $64-1, v1, x1
|
||||||
|
ROR $64-7, v2, x2
|
||||||
|
ADD x1, x2
|
||||||
|
ROR $64-12, v3, x3
|
||||||
|
ROR $64-18, v4, x4
|
||||||
|
ADD x3, x4
|
||||||
|
ADD x2, x4, h
|
||||||
|
|
||||||
|
mergeRound(h, v1)
|
||||||
|
mergeRound(h, v2)
|
||||||
|
mergeRound(h, v3)
|
||||||
|
mergeRound(h, v4)
|
||||||
|
|
||||||
|
afterLoop:
|
||||||
|
ADD n, h
|
||||||
|
|
||||||
|
TBZ $4, n, try8
|
||||||
|
LDP.P 16(p), (x1, x2)
|
||||||
|
|
||||||
|
round0(x1)
|
||||||
|
|
||||||
|
// NOTE: here and below, sequencing the EOR after the ROR (using a
|
||||||
|
// rotated register) is worth a small but measurable speedup for small
|
||||||
|
// inputs.
|
||||||
|
ROR $64-27, h
|
||||||
|
EOR x1 @> 64-27, h, h
|
||||||
|
MADD h, prime4, prime1, h
|
||||||
|
|
||||||
|
round0(x2)
|
||||||
|
ROR $64-27, h
|
||||||
|
EOR x2 @> 64-27, h, h
|
||||||
|
MADD h, prime4, prime1, h
|
||||||
|
|
||||||
|
try8:
|
||||||
|
TBZ $3, n, try4
|
||||||
|
MOVD.P 8(p), x1
|
||||||
|
|
||||||
|
round0(x1)
|
||||||
|
ROR $64-27, h
|
||||||
|
EOR x1 @> 64-27, h, h
|
||||||
|
MADD h, prime4, prime1, h
|
||||||
|
|
||||||
|
try4:
|
||||||
|
TBZ $2, n, try2
|
||||||
|
MOVWU.P 4(p), x2
|
||||||
|
|
||||||
|
MUL prime1, x2
|
||||||
|
ROR $64-23, h
|
||||||
|
EOR x2 @> 64-23, h, h
|
||||||
|
MADD h, prime3, prime2, h
|
||||||
|
|
||||||
|
try2:
|
||||||
|
TBZ $1, n, try1
|
||||||
|
MOVHU.P 2(p), x3
|
||||||
|
AND $255, x3, x1
|
||||||
|
LSR $8, x3, x2
|
||||||
|
|
||||||
|
MUL prime5, x1
|
||||||
|
ROR $64-11, h
|
||||||
|
EOR x1 @> 64-11, h, h
|
||||||
|
MUL prime1, h
|
||||||
|
|
||||||
|
MUL prime5, x2
|
||||||
|
ROR $64-11, h
|
||||||
|
EOR x2 @> 64-11, h, h
|
||||||
|
MUL prime1, h
|
||||||
|
|
||||||
|
try1:
|
||||||
|
TBZ $0, n, finalize
|
||||||
|
MOVBU (p), x4
|
||||||
|
|
||||||
|
MUL prime5, x4
|
||||||
|
ROR $64-11, h
|
||||||
|
EOR x4 @> 64-11, h, h
|
||||||
|
MUL prime1, h
|
||||||
|
|
||||||
|
finalize:
|
||||||
|
EOR h >> 33, h
|
||||||
|
MUL prime2, h
|
||||||
|
EOR h >> 29, h
|
||||||
|
MUL prime3, h
|
||||||
|
EOR h >> 32, h
|
||||||
|
|
||||||
|
MOVD h, ret+24(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func writeBlocks(d *Digest, b []byte) int
|
||||||
|
TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40
|
||||||
|
LDP ·primes+0(SB), (prime1, prime2)
|
||||||
|
|
||||||
|
// Load state. Assume v[1-4] are stored contiguously.
|
||||||
|
MOVD d+0(FP), digest
|
||||||
|
LDP 0(digest), (v1, v2)
|
||||||
|
LDP 16(digest), (v3, v4)
|
||||||
|
|
||||||
|
LDP b_base+8(FP), (p, n)
|
||||||
|
|
||||||
|
blockLoop()
|
||||||
|
|
||||||
|
// Store updated state.
|
||||||
|
STP (v1, v2), 0(digest)
|
||||||
|
STP (v3, v4), 16(digest)
|
||||||
|
|
||||||
|
BIC $31, n
|
||||||
|
MOVD n, ret+32(FP)
|
||||||
|
RET
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
//go:build (amd64 || arm64) && !appengine && gc && !purego
|
||||||
|
// +build amd64 arm64
|
||||||
// +build !appengine
|
// +build !appengine
|
||||||
// +build gc
|
// +build gc
|
||||||
// +build !purego
|
// +build !purego
|
||||||
22
vendor/github.com/cespare/xxhash/v2/xxhash_other.go
generated
vendored
22
vendor/github.com/cespare/xxhash/v2/xxhash_other.go
generated
vendored
@@ -1,4 +1,5 @@
|
|||||||
// +build !amd64 appengine !gc purego
|
//go:build (!amd64 && !arm64) || appengine || !gc || purego
|
||||||
|
// +build !amd64,!arm64 appengine !gc purego
|
||||||
|
|
||||||
package xxhash
|
package xxhash
|
||||||
|
|
||||||
@@ -14,10 +15,10 @@ func Sum64(b []byte) uint64 {
|
|||||||
var h uint64
|
var h uint64
|
||||||
|
|
||||||
if n >= 32 {
|
if n >= 32 {
|
||||||
v1 := prime1v + prime2
|
v1 := primes[0] + prime2
|
||||||
v2 := prime2
|
v2 := prime2
|
||||||
v3 := uint64(0)
|
v3 := uint64(0)
|
||||||
v4 := -prime1v
|
v4 := -primes[0]
|
||||||
for len(b) >= 32 {
|
for len(b) >= 32 {
|
||||||
v1 = round(v1, u64(b[0:8:len(b)]))
|
v1 = round(v1, u64(b[0:8:len(b)]))
|
||||||
v2 = round(v2, u64(b[8:16:len(b)]))
|
v2 = round(v2, u64(b[8:16:len(b)]))
|
||||||
@@ -36,19 +37,18 @@ func Sum64(b []byte) uint64 {
|
|||||||
|
|
||||||
h += uint64(n)
|
h += uint64(n)
|
||||||
|
|
||||||
i, end := 0, len(b)
|
for ; len(b) >= 8; b = b[8:] {
|
||||||
for ; i+8 <= end; i += 8 {
|
k1 := round(0, u64(b[:8]))
|
||||||
k1 := round(0, u64(b[i:i+8:len(b)]))
|
|
||||||
h ^= k1
|
h ^= k1
|
||||||
h = rol27(h)*prime1 + prime4
|
h = rol27(h)*prime1 + prime4
|
||||||
}
|
}
|
||||||
if i+4 <= end {
|
if len(b) >= 4 {
|
||||||
h ^= uint64(u32(b[i:i+4:len(b)])) * prime1
|
h ^= uint64(u32(b[:4])) * prime1
|
||||||
h = rol23(h)*prime2 + prime3
|
h = rol23(h)*prime2 + prime3
|
||||||
i += 4
|
b = b[4:]
|
||||||
}
|
}
|
||||||
for ; i < end; i++ {
|
for ; len(b) > 0; b = b[1:] {
|
||||||
h ^= uint64(b[i]) * prime5
|
h ^= uint64(b[0]) * prime5
|
||||||
h = rol11(h) * prime1
|
h = rol11(h) * prime1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
vendor/github.com/cespare/xxhash/v2/xxhash_safe.go
generated
vendored
1
vendor/github.com/cespare/xxhash/v2/xxhash_safe.go
generated
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build appengine
|
||||||
// +build appengine
|
// +build appengine
|
||||||
|
|
||||||
// This file contains the safe implementations of otherwise unsafe-using code.
|
// This file contains the safe implementations of otherwise unsafe-using code.
|
||||||
|
|||||||
3
vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go
generated
vendored
3
vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go
generated
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
//go:build !appengine
|
||||||
// +build !appengine
|
// +build !appengine
|
||||||
|
|
||||||
// This file encapsulates usage of unsafe.
|
// This file encapsulates usage of unsafe.
|
||||||
@@ -11,7 +12,7 @@ import (
|
|||||||
|
|
||||||
// In the future it's possible that compiler optimizations will make these
|
// In the future it's possible that compiler optimizations will make these
|
||||||
// XxxString functions unnecessary by realizing that calls such as
|
// XxxString functions unnecessary by realizing that calls such as
|
||||||
// Sum64([]byte(s)) don't need to copy s. See https://golang.org/issue/2205.
|
// Sum64([]byte(s)) don't need to copy s. See https://go.dev/issue/2205.
|
||||||
// If that happens, even if we keep these functions they can be replaced with
|
// If that happens, even if we keep these functions they can be replaced with
|
||||||
// the trivial safe code.
|
// the trivial safe code.
|
||||||
|
|
||||||
|
|||||||
20
vendor/github.com/emicklei/go-restful/v3/CHANGES.md
generated
vendored
20
vendor/github.com/emicklei/go-restful/v3/CHANGES.md
generated
vendored
@@ -1,10 +1,26 @@
|
|||||||
# Change history of go-restful
|
# Change history of go-restful
|
||||||
|
|
||||||
## [v3.9.0] - 20221-07-21
|
## [v3.10.2] - 2023-03-09
|
||||||
|
|
||||||
|
- introduced MergePathStrategy to be able to revert behaviour of path concatenation to 3.9.0
|
||||||
|
see comment in Readme how to customize this behaviour.
|
||||||
|
|
||||||
|
## [v3.10.1] - 2022-11-19
|
||||||
|
|
||||||
|
- fix broken 3.10.0 by using path package for joining paths
|
||||||
|
|
||||||
|
## [v3.10.0] - 2022-10-11 - BROKEN
|
||||||
|
|
||||||
|
- changed tokenizer to match std route match behavior; do not trimright the path (#511)
|
||||||
|
- Add MIME_ZIP (#512)
|
||||||
|
- Add MIME_ZIP and HEADER_ContentDisposition (#513)
|
||||||
|
- Changed how to get query parameter issue #510
|
||||||
|
|
||||||
|
## [v3.9.0] - 2022-07-21
|
||||||
|
|
||||||
- add support for http.Handler implementations to work as FilterFunction, issue #504 (thanks to https://github.com/ggicci)
|
- add support for http.Handler implementations to work as FilterFunction, issue #504 (thanks to https://github.com/ggicci)
|
||||||
|
|
||||||
## [v3.8.0] - 20221-06-06
|
## [v3.8.0] - 2022-06-06
|
||||||
|
|
||||||
- use exact matching of allowed domain entries, issue #489 (#493)
|
- use exact matching of allowed domain entries, issue #489 (#493)
|
||||||
- this changes fixes [security] Authorization Bypass Through User-Controlled Key
|
- this changes fixes [security] Authorization Bypass Through User-Controlled Key
|
||||||
|
|||||||
4
vendor/github.com/emicklei/go-restful/v3/README.md
generated
vendored
4
vendor/github.com/emicklei/go-restful/v3/README.md
generated
vendored
@@ -96,6 +96,10 @@ There are several hooks to customize the behavior of the go-restful package.
|
|||||||
- Compression
|
- Compression
|
||||||
- Encoders for other serializers
|
- Encoders for other serializers
|
||||||
- Use [jsoniter](https://github.com/json-iterator/go) by building this package using a build tag, e.g. `go build -tags=jsoniter .`
|
- Use [jsoniter](https://github.com/json-iterator/go) by building this package using a build tag, e.g. `go build -tags=jsoniter .`
|
||||||
|
- Use the variable `MergePathStrategy` to change the behaviour of composing the Route path given a root path and a local route path
|
||||||
|
- versions >= 3.10.1 has set the value to `PathJoinStrategy` that fixes a reported [security issue](https://github.com/advisories/GHSA-r48q-9g5r-8q2h) but may cause your services not to work correctly anymore.
|
||||||
|
- versions <= 3.9 had the behaviour that can be restored in newer versions by setting the value to `TrimSlashStrategy`.
|
||||||
|
- you can set value to a custom implementation (must implement MergePathStrategyFunc)
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
|
|
||||||
|
|||||||
2
vendor/github.com/emicklei/go-restful/v3/constants.go
generated
vendored
2
vendor/github.com/emicklei/go-restful/v3/constants.go
generated
vendored
@@ -7,12 +7,14 @@ package restful
|
|||||||
const (
|
const (
|
||||||
MIME_XML = "application/xml" // Accept or Content-Type used in Consumes() and/or Produces()
|
MIME_XML = "application/xml" // Accept or Content-Type used in Consumes() and/or Produces()
|
||||||
MIME_JSON = "application/json" // Accept or Content-Type used in Consumes() and/or Produces()
|
MIME_JSON = "application/json" // Accept or Content-Type used in Consumes() and/or Produces()
|
||||||
|
MIME_ZIP = "application/zip" // Accept or Content-Type used in Consumes() and/or Produces()
|
||||||
MIME_OCTET = "application/octet-stream" // If Content-Type is not present in request, use the default
|
MIME_OCTET = "application/octet-stream" // If Content-Type is not present in request, use the default
|
||||||
|
|
||||||
HEADER_Allow = "Allow"
|
HEADER_Allow = "Allow"
|
||||||
HEADER_Accept = "Accept"
|
HEADER_Accept = "Accept"
|
||||||
HEADER_Origin = "Origin"
|
HEADER_Origin = "Origin"
|
||||||
HEADER_ContentType = "Content-Type"
|
HEADER_ContentType = "Content-Type"
|
||||||
|
HEADER_ContentDisposition = "Content-Disposition"
|
||||||
HEADER_LastModified = "Last-Modified"
|
HEADER_LastModified = "Last-Modified"
|
||||||
HEADER_AcceptEncoding = "Accept-Encoding"
|
HEADER_AcceptEncoding = "Accept-Encoding"
|
||||||
HEADER_ContentEncoding = "Content-Encoding"
|
HEADER_ContentEncoding = "Content-Encoding"
|
||||||
|
|||||||
3
vendor/github.com/emicklei/go-restful/v3/request.go
generated
vendored
3
vendor/github.com/emicklei/go-restful/v3/request.go
generated
vendored
@@ -31,6 +31,7 @@ func NewRequest(httpRequest *http.Request) *Request {
|
|||||||
// a "Unable to unmarshal content of type:" response is returned.
|
// a "Unable to unmarshal content of type:" response is returned.
|
||||||
// Valid values are restful.MIME_JSON and restful.MIME_XML
|
// Valid values are restful.MIME_JSON and restful.MIME_XML
|
||||||
// Example:
|
// Example:
|
||||||
|
//
|
||||||
// restful.DefaultRequestContentType(restful.MIME_JSON)
|
// restful.DefaultRequestContentType(restful.MIME_JSON)
|
||||||
func DefaultRequestContentType(mime string) {
|
func DefaultRequestContentType(mime string) {
|
||||||
defaultRequestContentType = mime
|
defaultRequestContentType = mime
|
||||||
@@ -48,7 +49,7 @@ func (r *Request) PathParameters() map[string]string {
|
|||||||
|
|
||||||
// QueryParameter returns the (first) Query parameter value by its name
|
// QueryParameter returns the (first) Query parameter value by its name
|
||||||
func (r *Request) QueryParameter(name string) string {
|
func (r *Request) QueryParameter(name string) string {
|
||||||
return r.Request.FormValue(name)
|
return r.Request.URL.Query().Get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryParameters returns the all the query parameters values by name
|
// QueryParameters returns the all the query parameters values by name
|
||||||
|
|||||||
3
vendor/github.com/emicklei/go-restful/v3/response.go
generated
vendored
3
vendor/github.com/emicklei/go-restful/v3/response.go
generated
vendored
@@ -109,6 +109,9 @@ func (r *Response) EntityWriter() (EntityReaderWriter, bool) {
|
|||||||
if DefaultResponseMimeType == MIME_XML {
|
if DefaultResponseMimeType == MIME_XML {
|
||||||
return entityAccessRegistry.accessorAt(MIME_XML)
|
return entityAccessRegistry.accessorAt(MIME_XML)
|
||||||
}
|
}
|
||||||
|
if DefaultResponseMimeType == MIME_ZIP {
|
||||||
|
return entityAccessRegistry.accessorAt(MIME_ZIP)
|
||||||
|
}
|
||||||
// Fallback to whatever the route says it can produce.
|
// Fallback to whatever the route says it can produce.
|
||||||
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||||
for _, each := range r.routeProduces {
|
for _, each := range r.routeProduces {
|
||||||
|
|||||||
4
vendor/github.com/emicklei/go-restful/v3/route.go
generated
vendored
4
vendor/github.com/emicklei/go-restful/v3/route.go
generated
vendored
@@ -164,7 +164,7 @@ func tokenizePath(path string) []string {
|
|||||||
if "/" == path {
|
if "/" == path {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return strings.Split(strings.Trim(path, "/"), "/")
|
return strings.Split(strings.TrimLeft(path, "/"), "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
// for debugging
|
// for debugging
|
||||||
@@ -176,3 +176,5 @@ func (r *Route) String() string {
|
|||||||
func (r *Route) EnableContentEncoding(enabled bool) {
|
func (r *Route) EnableContentEncoding(enabled bool) {
|
||||||
r.contentEncodingEnabled = &enabled
|
r.contentEncodingEnabled = &enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var TrimRightSlashEnabled = false
|
||||||
|
|||||||
26
vendor/github.com/emicklei/go-restful/v3/route_builder.go
generated
vendored
26
vendor/github.com/emicklei/go-restful/v3/route_builder.go
generated
vendored
@@ -7,6 +7,7 @@ package restful
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -46,6 +47,7 @@ type RouteBuilder struct {
|
|||||||
// Do evaluates each argument with the RouteBuilder itself.
|
// Do evaluates each argument with the RouteBuilder itself.
|
||||||
// This allows you to follow DRY principles without breaking the fluent programming style.
|
// This allows you to follow DRY principles without breaking the fluent programming style.
|
||||||
// Example:
|
// Example:
|
||||||
|
//
|
||||||
// ws.Route(ws.DELETE("/{name}").To(t.deletePerson).Do(Returns200, Returns500))
|
// ws.Route(ws.DELETE("/{name}").To(t.deletePerson).Do(Returns200, Returns500))
|
||||||
//
|
//
|
||||||
// func Returns500(b *RouteBuilder) {
|
// func Returns500(b *RouteBuilder) {
|
||||||
@@ -351,8 +353,28 @@ func (b *RouteBuilder) Build() Route {
|
|||||||
return route
|
return route
|
||||||
}
|
}
|
||||||
|
|
||||||
func concatPath(path1, path2 string) string {
|
type MergePathStrategyFunc func(rootPath, routePath string) string
|
||||||
return strings.TrimRight(path1, "/") + "/" + strings.TrimLeft(path2, "/")
|
|
||||||
|
var (
|
||||||
|
// behavior >= 3.10
|
||||||
|
PathJoinStrategy = func(rootPath, routePath string) string {
|
||||||
|
return path.Join(rootPath, routePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// behavior <= 3.9
|
||||||
|
TrimSlashStrategy = func(rootPath, routePath string) string {
|
||||||
|
return strings.TrimRight(rootPath, "/") + "/" + strings.TrimLeft(routePath, "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MergePathStrategy is the active strategy for merging a Route path when building the routing of all WebServices.
|
||||||
|
// The value is set to PathJoinStrategy
|
||||||
|
// PathJoinStrategy is a strategy that is more strict [Security - PRISMA-2022-0227]
|
||||||
|
MergePathStrategy = PathJoinStrategy
|
||||||
|
)
|
||||||
|
|
||||||
|
// merge two paths using the current (package global) merge path strategy.
|
||||||
|
func concatPath(rootPath, routePath string) string {
|
||||||
|
return MergePathStrategy(rootPath, routePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
var anonymousFuncCount int32
|
var anonymousFuncCount int32
|
||||||
|
|||||||
787
vendor/github.com/go-logr/logr/funcr/funcr.go
generated
vendored
Normal file
787
vendor/github.com/go-logr/logr/funcr/funcr.go
generated
vendored
Normal file
@@ -0,0 +1,787 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 The logr Authors.
|
||||||
|
|
||||||
|
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 funcr implements formatting of structured log messages and
|
||||||
|
// optionally captures the call site and timestamp.
|
||||||
|
//
|
||||||
|
// The simplest way to use it is via its implementation of a
|
||||||
|
// github.com/go-logr/logr.LogSink with output through an arbitrary
|
||||||
|
// "write" function. See New and NewJSON for details.
|
||||||
|
//
|
||||||
|
// Custom LogSinks
|
||||||
|
//
|
||||||
|
// For users who need more control, a funcr.Formatter can be embedded inside
|
||||||
|
// your own custom LogSink implementation. This is useful when the LogSink
|
||||||
|
// needs to implement additional methods, for example.
|
||||||
|
//
|
||||||
|
// Formatting
|
||||||
|
//
|
||||||
|
// This will respect logr.Marshaler, fmt.Stringer, and error interfaces for
|
||||||
|
// values which are being logged. When rendering a struct, funcr will use Go's
|
||||||
|
// standard JSON tags (all except "string").
|
||||||
|
package funcr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding"
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-logr/logr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New returns a logr.Logger which is implemented by an arbitrary function.
|
||||||
|
func New(fn func(prefix, args string), opts Options) logr.Logger {
|
||||||
|
return logr.New(newSink(fn, NewFormatter(opts)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewJSON returns a logr.Logger which is implemented by an arbitrary function
|
||||||
|
// and produces JSON output.
|
||||||
|
func NewJSON(fn func(obj string), opts Options) logr.Logger {
|
||||||
|
fnWrapper := func(_, obj string) {
|
||||||
|
fn(obj)
|
||||||
|
}
|
||||||
|
return logr.New(newSink(fnWrapper, NewFormatterJSON(opts)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Underlier exposes access to the underlying logging function. Since
|
||||||
|
// callers only have a logr.Logger, they have to know which
|
||||||
|
// implementation is in use, so this interface is less of an
|
||||||
|
// abstraction and more of a way to test type conversion.
|
||||||
|
type Underlier interface {
|
||||||
|
GetUnderlying() func(prefix, args string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSink(fn func(prefix, args string), formatter Formatter) logr.LogSink {
|
||||||
|
l := &fnlogger{
|
||||||
|
Formatter: formatter,
|
||||||
|
write: fn,
|
||||||
|
}
|
||||||
|
// For skipping fnlogger.Info and fnlogger.Error.
|
||||||
|
l.Formatter.AddCallDepth(1)
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options carries parameters which influence the way logs are generated.
|
||||||
|
type Options struct {
|
||||||
|
// LogCaller tells funcr to add a "caller" key to some or all log lines.
|
||||||
|
// This has some overhead, so some users might not want it.
|
||||||
|
LogCaller MessageClass
|
||||||
|
|
||||||
|
// LogCallerFunc tells funcr to also log the calling function name. This
|
||||||
|
// has no effect if caller logging is not enabled (see Options.LogCaller).
|
||||||
|
LogCallerFunc bool
|
||||||
|
|
||||||
|
// LogTimestamp tells funcr to add a "ts" key to log lines. This has some
|
||||||
|
// overhead, so some users might not want it.
|
||||||
|
LogTimestamp bool
|
||||||
|
|
||||||
|
// TimestampFormat tells funcr how to render timestamps when LogTimestamp
|
||||||
|
// is enabled. If not specified, a default format will be used. For more
|
||||||
|
// details, see docs for Go's time.Layout.
|
||||||
|
TimestampFormat string
|
||||||
|
|
||||||
|
// Verbosity tells funcr which V logs to produce. Higher values enable
|
||||||
|
// more logs. Info logs at or below this level will be written, while logs
|
||||||
|
// above this level will be discarded.
|
||||||
|
Verbosity int
|
||||||
|
|
||||||
|
// RenderBuiltinsHook allows users to mutate the list of key-value pairs
|
||||||
|
// while a log line is being rendered. The kvList argument follows logr
|
||||||
|
// conventions - each pair of slice elements is comprised of a string key
|
||||||
|
// and an arbitrary value (verified and sanitized before calling this
|
||||||
|
// hook). The value returned must follow the same conventions. This hook
|
||||||
|
// can be used to audit or modify logged data. For example, you might want
|
||||||
|
// to prefix all of funcr's built-in keys with some string. This hook is
|
||||||
|
// only called for built-in (provided by funcr itself) key-value pairs.
|
||||||
|
// Equivalent hooks are offered for key-value pairs saved via
|
||||||
|
// logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and
|
||||||
|
// for user-provided pairs (see RenderArgsHook).
|
||||||
|
RenderBuiltinsHook func(kvList []interface{}) []interface{}
|
||||||
|
|
||||||
|
// RenderValuesHook is the same as RenderBuiltinsHook, except that it is
|
||||||
|
// only called for key-value pairs saved via logr.Logger.WithValues. See
|
||||||
|
// RenderBuiltinsHook for more details.
|
||||||
|
RenderValuesHook func(kvList []interface{}) []interface{}
|
||||||
|
|
||||||
|
// RenderArgsHook is the same as RenderBuiltinsHook, except that it is only
|
||||||
|
// called for key-value pairs passed directly to Info and Error. See
|
||||||
|
// RenderBuiltinsHook for more details.
|
||||||
|
RenderArgsHook func(kvList []interface{}) []interface{}
|
||||||
|
|
||||||
|
// MaxLogDepth tells funcr how many levels of nested fields (e.g. a struct
|
||||||
|
// that contains a struct, etc.) it may log. Every time it finds a struct,
|
||||||
|
// slice, array, or map the depth is increased by one. When the maximum is
|
||||||
|
// reached, the value will be converted to a string indicating that the max
|
||||||
|
// depth has been exceeded. If this field is not specified, a default
|
||||||
|
// value will be used.
|
||||||
|
MaxLogDepth int
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageClass indicates which category or categories of messages to consider.
|
||||||
|
type MessageClass int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// None ignores all message classes.
|
||||||
|
None MessageClass = iota
|
||||||
|
// All considers all message classes.
|
||||||
|
All
|
||||||
|
// Info only considers info messages.
|
||||||
|
Info
|
||||||
|
// Error only considers error messages.
|
||||||
|
Error
|
||||||
|
)
|
||||||
|
|
||||||
|
// fnlogger inherits some of its LogSink implementation from Formatter
|
||||||
|
// and just needs to add some glue code.
|
||||||
|
type fnlogger struct {
|
||||||
|
Formatter
|
||||||
|
write func(prefix, args string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fnlogger) WithName(name string) logr.LogSink {
|
||||||
|
l.Formatter.AddName(name)
|
||||||
|
return &l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fnlogger) WithValues(kvList ...interface{}) logr.LogSink {
|
||||||
|
l.Formatter.AddValues(kvList)
|
||||||
|
return &l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fnlogger) WithCallDepth(depth int) logr.LogSink {
|
||||||
|
l.Formatter.AddCallDepth(depth)
|
||||||
|
return &l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fnlogger) Info(level int, msg string, kvList ...interface{}) {
|
||||||
|
prefix, args := l.FormatInfo(level, msg, kvList)
|
||||||
|
l.write(prefix, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fnlogger) Error(err error, msg string, kvList ...interface{}) {
|
||||||
|
prefix, args := l.FormatError(err, msg, kvList)
|
||||||
|
l.write(prefix, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fnlogger) GetUnderlying() func(prefix, args string) {
|
||||||
|
return l.write
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert conformance to the interfaces.
|
||||||
|
var _ logr.LogSink = &fnlogger{}
|
||||||
|
var _ logr.CallDepthLogSink = &fnlogger{}
|
||||||
|
var _ Underlier = &fnlogger{}
|
||||||
|
|
||||||
|
// NewFormatter constructs a Formatter which emits a JSON-like key=value format.
|
||||||
|
func NewFormatter(opts Options) Formatter {
|
||||||
|
return newFormatter(opts, outputKeyValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFormatterJSON constructs a Formatter which emits strict JSON.
|
||||||
|
func NewFormatterJSON(opts Options) Formatter {
|
||||||
|
return newFormatter(opts, outputJSON)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defaults for Options.
|
||||||
|
const defaultTimestampFormat = "2006-01-02 15:04:05.000000"
|
||||||
|
const defaultMaxLogDepth = 16
|
||||||
|
|
||||||
|
func newFormatter(opts Options, outfmt outputFormat) Formatter {
|
||||||
|
if opts.TimestampFormat == "" {
|
||||||
|
opts.TimestampFormat = defaultTimestampFormat
|
||||||
|
}
|
||||||
|
if opts.MaxLogDepth == 0 {
|
||||||
|
opts.MaxLogDepth = defaultMaxLogDepth
|
||||||
|
}
|
||||||
|
f := Formatter{
|
||||||
|
outputFormat: outfmt,
|
||||||
|
prefix: "",
|
||||||
|
values: nil,
|
||||||
|
depth: 0,
|
||||||
|
opts: opts,
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formatter is an opaque struct which can be embedded in a LogSink
|
||||||
|
// implementation. It should be constructed with NewFormatter. Some of
|
||||||
|
// its methods directly implement logr.LogSink.
|
||||||
|
type Formatter struct {
|
||||||
|
outputFormat outputFormat
|
||||||
|
prefix string
|
||||||
|
values []interface{}
|
||||||
|
valuesStr string
|
||||||
|
depth int
|
||||||
|
opts Options
|
||||||
|
}
|
||||||
|
|
||||||
|
// outputFormat indicates which outputFormat to use.
|
||||||
|
type outputFormat int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// outputKeyValue emits a JSON-like key=value format, but not strict JSON.
|
||||||
|
outputKeyValue outputFormat = iota
|
||||||
|
// outputJSON emits strict JSON.
|
||||||
|
outputJSON
|
||||||
|
)
|
||||||
|
|
||||||
|
// PseudoStruct is a list of key-value pairs that gets logged as a struct.
|
||||||
|
type PseudoStruct []interface{}
|
||||||
|
|
||||||
|
// render produces a log line, ready to use.
|
||||||
|
func (f Formatter) render(builtins, args []interface{}) string {
|
||||||
|
// Empirically bytes.Buffer is faster than strings.Builder for this.
|
||||||
|
buf := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
buf.WriteByte('{')
|
||||||
|
}
|
||||||
|
vals := builtins
|
||||||
|
if hook := f.opts.RenderBuiltinsHook; hook != nil {
|
||||||
|
vals = hook(f.sanitize(vals))
|
||||||
|
}
|
||||||
|
f.flatten(buf, vals, false, false) // keys are ours, no need to escape
|
||||||
|
continuing := len(builtins) > 0
|
||||||
|
if len(f.valuesStr) > 0 {
|
||||||
|
if continuing {
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
} else {
|
||||||
|
buf.WriteByte(' ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continuing = true
|
||||||
|
buf.WriteString(f.valuesStr)
|
||||||
|
}
|
||||||
|
vals = args
|
||||||
|
if hook := f.opts.RenderArgsHook; hook != nil {
|
||||||
|
vals = hook(f.sanitize(vals))
|
||||||
|
}
|
||||||
|
f.flatten(buf, vals, continuing, true) // escape user-provided keys
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
buf.WriteByte('}')
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// flatten renders a list of key-value pairs into a buffer. If continuing is
|
||||||
|
// true, it assumes that the buffer has previous values and will emit a
|
||||||
|
// separator (which depends on the output format) before the first pair it
|
||||||
|
// writes. If escapeKeys is true, the keys are assumed to have
|
||||||
|
// non-JSON-compatible characters in them and must be evaluated for escapes.
|
||||||
|
//
|
||||||
|
// This function returns a potentially modified version of kvList, which
|
||||||
|
// ensures that there is a value for every key (adding a value if needed) and
|
||||||
|
// that each key is a string (substituting a key if needed).
|
||||||
|
func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing bool, escapeKeys bool) []interface{} {
|
||||||
|
// This logic overlaps with sanitize() but saves one type-cast per key,
|
||||||
|
// which can be measurable.
|
||||||
|
if len(kvList)%2 != 0 {
|
||||||
|
kvList = append(kvList, noValue)
|
||||||
|
}
|
||||||
|
for i := 0; i < len(kvList); i += 2 {
|
||||||
|
k, ok := kvList[i].(string)
|
||||||
|
if !ok {
|
||||||
|
k = f.nonStringKey(kvList[i])
|
||||||
|
kvList[i] = k
|
||||||
|
}
|
||||||
|
v := kvList[i+1]
|
||||||
|
|
||||||
|
if i > 0 || continuing {
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
} else {
|
||||||
|
// In theory the format could be something we don't understand. In
|
||||||
|
// practice, we control it, so it won't be.
|
||||||
|
buf.WriteByte(' ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if escapeKeys {
|
||||||
|
buf.WriteString(prettyString(k))
|
||||||
|
} else {
|
||||||
|
// this is faster
|
||||||
|
buf.WriteByte('"')
|
||||||
|
buf.WriteString(k)
|
||||||
|
buf.WriteByte('"')
|
||||||
|
}
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
buf.WriteByte(':')
|
||||||
|
} else {
|
||||||
|
buf.WriteByte('=')
|
||||||
|
}
|
||||||
|
buf.WriteString(f.pretty(v))
|
||||||
|
}
|
||||||
|
return kvList
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f Formatter) pretty(value interface{}) string {
|
||||||
|
return f.prettyWithFlags(value, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
flagRawStruct = 0x1 // do not print braces on structs
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: This is not fast. Most of the overhead goes here.
|
||||||
|
func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) string {
|
||||||
|
if depth > f.opts.MaxLogDepth {
|
||||||
|
return `"<max-log-depth-exceeded>"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle types that take full control of logging.
|
||||||
|
if v, ok := value.(logr.Marshaler); ok {
|
||||||
|
// Replace the value with what the type wants to get logged.
|
||||||
|
// That then gets handled below via reflection.
|
||||||
|
value = invokeMarshaler(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle types that want to format themselves.
|
||||||
|
switch v := value.(type) {
|
||||||
|
case fmt.Stringer:
|
||||||
|
value = invokeStringer(v)
|
||||||
|
case error:
|
||||||
|
value = invokeError(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handling the most common types without reflect is a small perf win.
|
||||||
|
switch v := value.(type) {
|
||||||
|
case bool:
|
||||||
|
return strconv.FormatBool(v)
|
||||||
|
case string:
|
||||||
|
return prettyString(v)
|
||||||
|
case int:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case int8:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case int16:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case int32:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case int64:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case uint:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case uint8:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case uint16:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case uint32:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case uint64:
|
||||||
|
return strconv.FormatUint(v, 10)
|
||||||
|
case uintptr:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case float32:
|
||||||
|
return strconv.FormatFloat(float64(v), 'f', -1, 32)
|
||||||
|
case float64:
|
||||||
|
return strconv.FormatFloat(v, 'f', -1, 64)
|
||||||
|
case complex64:
|
||||||
|
return `"` + strconv.FormatComplex(complex128(v), 'f', -1, 64) + `"`
|
||||||
|
case complex128:
|
||||||
|
return `"` + strconv.FormatComplex(v, 'f', -1, 128) + `"`
|
||||||
|
case PseudoStruct:
|
||||||
|
buf := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||||
|
v = f.sanitize(v)
|
||||||
|
if flags&flagRawStruct == 0 {
|
||||||
|
buf.WriteByte('{')
|
||||||
|
}
|
||||||
|
for i := 0; i < len(v); i += 2 {
|
||||||
|
if i > 0 {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
}
|
||||||
|
k, _ := v[i].(string) // sanitize() above means no need to check success
|
||||||
|
// arbitrary keys might need escaping
|
||||||
|
buf.WriteString(prettyString(k))
|
||||||
|
buf.WriteByte(':')
|
||||||
|
buf.WriteString(f.prettyWithFlags(v[i+1], 0, depth+1))
|
||||||
|
}
|
||||||
|
if flags&flagRawStruct == 0 {
|
||||||
|
buf.WriteByte('}')
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := bytes.NewBuffer(make([]byte, 0, 256))
|
||||||
|
t := reflect.TypeOf(value)
|
||||||
|
if t == nil {
|
||||||
|
return "null"
|
||||||
|
}
|
||||||
|
v := reflect.ValueOf(value)
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return strconv.FormatBool(v.Bool())
|
||||||
|
case reflect.String:
|
||||||
|
return prettyString(v.String())
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return strconv.FormatInt(int64(v.Int()), 10)
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return strconv.FormatUint(uint64(v.Uint()), 10)
|
||||||
|
case reflect.Float32:
|
||||||
|
return strconv.FormatFloat(float64(v.Float()), 'f', -1, 32)
|
||||||
|
case reflect.Float64:
|
||||||
|
return strconv.FormatFloat(v.Float(), 'f', -1, 64)
|
||||||
|
case reflect.Complex64:
|
||||||
|
return `"` + strconv.FormatComplex(complex128(v.Complex()), 'f', -1, 64) + `"`
|
||||||
|
case reflect.Complex128:
|
||||||
|
return `"` + strconv.FormatComplex(v.Complex(), 'f', -1, 128) + `"`
|
||||||
|
case reflect.Struct:
|
||||||
|
if flags&flagRawStruct == 0 {
|
||||||
|
buf.WriteByte('{')
|
||||||
|
}
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
fld := t.Field(i)
|
||||||
|
if fld.PkgPath != "" {
|
||||||
|
// reflect says this field is only defined for non-exported fields.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !v.Field(i).CanInterface() {
|
||||||
|
// reflect isn't clear exactly what this means, but we can't use it.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name := ""
|
||||||
|
omitempty := false
|
||||||
|
if tag, found := fld.Tag.Lookup("json"); found {
|
||||||
|
if tag == "-" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if comma := strings.Index(tag, ","); comma != -1 {
|
||||||
|
if n := tag[:comma]; n != "" {
|
||||||
|
name = n
|
||||||
|
}
|
||||||
|
rest := tag[comma:]
|
||||||
|
if strings.Contains(rest, ",omitempty,") || strings.HasSuffix(rest, ",omitempty") {
|
||||||
|
omitempty = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
name = tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if omitempty && isEmpty(v.Field(i)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i > 0 {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
}
|
||||||
|
if fld.Anonymous && fld.Type.Kind() == reflect.Struct && name == "" {
|
||||||
|
buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), flags|flagRawStruct, depth+1))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if name == "" {
|
||||||
|
name = fld.Name
|
||||||
|
}
|
||||||
|
// field names can't contain characters which need escaping
|
||||||
|
buf.WriteByte('"')
|
||||||
|
buf.WriteString(name)
|
||||||
|
buf.WriteByte('"')
|
||||||
|
buf.WriteByte(':')
|
||||||
|
buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), 0, depth+1))
|
||||||
|
}
|
||||||
|
if flags&flagRawStruct == 0 {
|
||||||
|
buf.WriteByte('}')
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
buf.WriteByte('[')
|
||||||
|
for i := 0; i < v.Len(); i++ {
|
||||||
|
if i > 0 {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
}
|
||||||
|
e := v.Index(i)
|
||||||
|
buf.WriteString(f.prettyWithFlags(e.Interface(), 0, depth+1))
|
||||||
|
}
|
||||||
|
buf.WriteByte(']')
|
||||||
|
return buf.String()
|
||||||
|
case reflect.Map:
|
||||||
|
buf.WriteByte('{')
|
||||||
|
// This does not sort the map keys, for best perf.
|
||||||
|
it := v.MapRange()
|
||||||
|
i := 0
|
||||||
|
for it.Next() {
|
||||||
|
if i > 0 {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
}
|
||||||
|
// If a map key supports TextMarshaler, use it.
|
||||||
|
keystr := ""
|
||||||
|
if m, ok := it.Key().Interface().(encoding.TextMarshaler); ok {
|
||||||
|
txt, err := m.MarshalText()
|
||||||
|
if err != nil {
|
||||||
|
keystr = fmt.Sprintf("<error-MarshalText: %s>", err.Error())
|
||||||
|
} else {
|
||||||
|
keystr = string(txt)
|
||||||
|
}
|
||||||
|
keystr = prettyString(keystr)
|
||||||
|
} else {
|
||||||
|
// prettyWithFlags will produce already-escaped values
|
||||||
|
keystr = f.prettyWithFlags(it.Key().Interface(), 0, depth+1)
|
||||||
|
if t.Key().Kind() != reflect.String {
|
||||||
|
// JSON only does string keys. Unlike Go's standard JSON, we'll
|
||||||
|
// convert just about anything to a string.
|
||||||
|
keystr = prettyString(keystr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.WriteString(keystr)
|
||||||
|
buf.WriteByte(':')
|
||||||
|
buf.WriteString(f.prettyWithFlags(it.Value().Interface(), 0, depth+1))
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
buf.WriteByte('}')
|
||||||
|
return buf.String()
|
||||||
|
case reflect.Ptr, reflect.Interface:
|
||||||
|
if v.IsNil() {
|
||||||
|
return "null"
|
||||||
|
}
|
||||||
|
return f.prettyWithFlags(v.Elem().Interface(), 0, depth)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(`"<unhandled-%s>"`, t.Kind().String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func prettyString(s string) string {
|
||||||
|
// Avoid escaping (which does allocations) if we can.
|
||||||
|
if needsEscape(s) {
|
||||||
|
return strconv.Quote(s)
|
||||||
|
}
|
||||||
|
b := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||||
|
b.WriteByte('"')
|
||||||
|
b.WriteString(s)
|
||||||
|
b.WriteByte('"')
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// needsEscape determines whether the input string needs to be escaped or not,
|
||||||
|
// without doing any allocations.
|
||||||
|
func needsEscape(s string) bool {
|
||||||
|
for _, r := range s {
|
||||||
|
if !strconv.IsPrint(r) || r == '\\' || r == '"' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isEmpty(v reflect.Value) bool {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||||
|
return v.Len() == 0
|
||||||
|
case reflect.Bool:
|
||||||
|
return !v.Bool()
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return v.Int() == 0
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return v.Uint() == 0
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return v.Float() == 0
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
return v.Complex() == 0
|
||||||
|
case reflect.Interface, reflect.Ptr:
|
||||||
|
return v.IsNil()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func invokeMarshaler(m logr.Marshaler) (ret interface{}) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ret = fmt.Sprintf("<panic: %s>", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return m.MarshalLog()
|
||||||
|
}
|
||||||
|
|
||||||
|
func invokeStringer(s fmt.Stringer) (ret string) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ret = fmt.Sprintf("<panic: %s>", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return s.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func invokeError(e error) (ret string) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ret = fmt.Sprintf("<panic: %s>", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
return e.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Caller represents the original call site for a log line, after considering
|
||||||
|
// logr.Logger.WithCallDepth and logr.Logger.WithCallStackHelper. The File and
|
||||||
|
// Line fields will always be provided, while the Func field is optional.
|
||||||
|
// Users can set the render hook fields in Options to examine logged key-value
|
||||||
|
// pairs, one of which will be {"caller", Caller} if the Options.LogCaller
|
||||||
|
// field is enabled for the given MessageClass.
|
||||||
|
type Caller struct {
|
||||||
|
// File is the basename of the file for this call site.
|
||||||
|
File string `json:"file"`
|
||||||
|
// Line is the line number in the file for this call site.
|
||||||
|
Line int `json:"line"`
|
||||||
|
// Func is the function name for this call site, or empty if
|
||||||
|
// Options.LogCallerFunc is not enabled.
|
||||||
|
Func string `json:"function,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f Formatter) caller() Caller {
|
||||||
|
// +1 for this frame, +1 for Info/Error.
|
||||||
|
pc, file, line, ok := runtime.Caller(f.depth + 2)
|
||||||
|
if !ok {
|
||||||
|
return Caller{"<unknown>", 0, ""}
|
||||||
|
}
|
||||||
|
fn := ""
|
||||||
|
if f.opts.LogCallerFunc {
|
||||||
|
if fp := runtime.FuncForPC(pc); fp != nil {
|
||||||
|
fn = fp.Name()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Caller{filepath.Base(file), line, fn}
|
||||||
|
}
|
||||||
|
|
||||||
|
const noValue = "<no-value>"
|
||||||
|
|
||||||
|
func (f Formatter) nonStringKey(v interface{}) string {
|
||||||
|
return fmt.Sprintf("<non-string-key: %s>", f.snippet(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// snippet produces a short snippet string of an arbitrary value.
|
||||||
|
func (f Formatter) snippet(v interface{}) string {
|
||||||
|
const snipLen = 16
|
||||||
|
|
||||||
|
snip := f.pretty(v)
|
||||||
|
if len(snip) > snipLen {
|
||||||
|
snip = snip[:snipLen]
|
||||||
|
}
|
||||||
|
return snip
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanitize ensures that a list of key-value pairs has a value for every key
|
||||||
|
// (adding a value if needed) and that each key is a string (substituting a key
|
||||||
|
// if needed).
|
||||||
|
func (f Formatter) sanitize(kvList []interface{}) []interface{} {
|
||||||
|
if len(kvList)%2 != 0 {
|
||||||
|
kvList = append(kvList, noValue)
|
||||||
|
}
|
||||||
|
for i := 0; i < len(kvList); i += 2 {
|
||||||
|
_, ok := kvList[i].(string)
|
||||||
|
if !ok {
|
||||||
|
kvList[i] = f.nonStringKey(kvList[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return kvList
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init configures this Formatter from runtime info, such as the call depth
|
||||||
|
// imposed by logr itself.
|
||||||
|
// Note that this receiver is a pointer, so depth can be saved.
|
||||||
|
func (f *Formatter) Init(info logr.RuntimeInfo) {
|
||||||
|
f.depth += info.CallDepth
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enabled checks whether an info message at the given level should be logged.
|
||||||
|
func (f Formatter) Enabled(level int) bool {
|
||||||
|
return level <= f.opts.Verbosity
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDepth returns the current depth of this Formatter. This is useful for
|
||||||
|
// implementations which do their own caller attribution.
|
||||||
|
func (f Formatter) GetDepth() int {
|
||||||
|
return f.depth
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatInfo renders an Info log message into strings. The prefix will be
|
||||||
|
// empty when no names were set (via AddNames), or when the output is
|
||||||
|
// configured for JSON.
|
||||||
|
func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string) {
|
||||||
|
args := make([]interface{}, 0, 64) // using a constant here impacts perf
|
||||||
|
prefix = f.prefix
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
args = append(args, "logger", prefix)
|
||||||
|
prefix = ""
|
||||||
|
}
|
||||||
|
if f.opts.LogTimestamp {
|
||||||
|
args = append(args, "ts", time.Now().Format(f.opts.TimestampFormat))
|
||||||
|
}
|
||||||
|
if policy := f.opts.LogCaller; policy == All || policy == Info {
|
||||||
|
args = append(args, "caller", f.caller())
|
||||||
|
}
|
||||||
|
args = append(args, "level", level, "msg", msg)
|
||||||
|
return prefix, f.render(args, kvList)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatError renders an Error log message into strings. The prefix will be
|
||||||
|
// empty when no names were set (via AddNames), or when the output is
|
||||||
|
// configured for JSON.
|
||||||
|
func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string) {
|
||||||
|
args := make([]interface{}, 0, 64) // using a constant here impacts perf
|
||||||
|
prefix = f.prefix
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
args = append(args, "logger", prefix)
|
||||||
|
prefix = ""
|
||||||
|
}
|
||||||
|
if f.opts.LogTimestamp {
|
||||||
|
args = append(args, "ts", time.Now().Format(f.opts.TimestampFormat))
|
||||||
|
}
|
||||||
|
if policy := f.opts.LogCaller; policy == All || policy == Error {
|
||||||
|
args = append(args, "caller", f.caller())
|
||||||
|
}
|
||||||
|
args = append(args, "msg", msg)
|
||||||
|
var loggableErr interface{}
|
||||||
|
if err != nil {
|
||||||
|
loggableErr = err.Error()
|
||||||
|
}
|
||||||
|
args = append(args, "error", loggableErr)
|
||||||
|
return f.prefix, f.render(args, kvList)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddName appends the specified name. funcr uses '/' characters to separate
|
||||||
|
// name elements. Callers should not pass '/' in the provided name string, but
|
||||||
|
// this library does not actually enforce that.
|
||||||
|
func (f *Formatter) AddName(name string) {
|
||||||
|
if len(f.prefix) > 0 {
|
||||||
|
f.prefix += "/"
|
||||||
|
}
|
||||||
|
f.prefix += name
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddValues adds key-value pairs to the set of saved values to be logged with
|
||||||
|
// each log line.
|
||||||
|
func (f *Formatter) AddValues(kvList []interface{}) {
|
||||||
|
// Three slice args forces a copy.
|
||||||
|
n := len(f.values)
|
||||||
|
f.values = append(f.values[:n:n], kvList...)
|
||||||
|
|
||||||
|
vals := f.values
|
||||||
|
if hook := f.opts.RenderValuesHook; hook != nil {
|
||||||
|
vals = hook(f.sanitize(vals))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre-render values, so we don't have to do it on each Info/Error call.
|
||||||
|
buf := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||||
|
f.flatten(buf, vals, false, true) // escape user-provided keys
|
||||||
|
f.valuesStr = buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddCallDepth increases the number of stack-frames to skip when attributing
|
||||||
|
// the log line to a file and line.
|
||||||
|
func (f *Formatter) AddCallDepth(depth int) {
|
||||||
|
f.depth += depth
|
||||||
|
}
|
||||||
15
vendor/github.com/go-openapi/jsonpointer/.travis.yml
generated
vendored
15
vendor/github.com/go-openapi/jsonpointer/.travis.yml
generated
vendored
@@ -1,15 +0,0 @@
|
|||||||
after_success:
|
|
||||||
- bash <(curl -s https://codecov.io/bash)
|
|
||||||
go:
|
|
||||||
- 1.14.x
|
|
||||||
- 1.15.x
|
|
||||||
install:
|
|
||||||
- GO111MODULE=off go get -u gotest.tools/gotestsum
|
|
||||||
env:
|
|
||||||
- GO111MODULE=on
|
|
||||||
language: go
|
|
||||||
notifications:
|
|
||||||
slack:
|
|
||||||
secure: a5VgoiwB1G/AZqzmephPZIhEB9avMlsWSlVnM1dSAtYAwdrQHGTQxAmpOxYIoSPDhWNN5bfZmjd29++UlTwLcHSR+e0kJhH6IfDlsHj/HplNCJ9tyI0zYc7XchtdKgeMxMzBKCzgwFXGSbQGydXTliDNBo0HOzmY3cou/daMFTP60K+offcjS+3LRAYb1EroSRXZqrk1nuF/xDL3792DZUdPMiFR/L/Df6y74D6/QP4sTkTDFQitz4Wy/7jbsfj8dG6qK2zivgV6/l+w4OVjFkxVpPXogDWY10vVXNVynqxfJ7to2d1I9lNCHE2ilBCkWMIPdyJF7hjF8pKW+82yP4EzRh0vu8Xn0HT5MZpQxdRY/YMxNrWaG7SxsoEaO4q5uhgdzAqLYY3TRa7MjIK+7Ur+aqOeTXn6OKwVi0CjvZ6mIU3WUKSwiwkFZMbjRAkSb5CYwMEfGFO/z964xz83qGt6WAtBXNotqCQpTIiKtDHQeLOMfksHImCg6JLhQcWBVxamVgu0G3Pdh8Y6DyPnxraXY95+QDavbjqv7TeYT9T/FNnrkXaTTK0s4iWE5H4ACU0Qvz0wUYgfQrZv0/Hp7V17+rabUwnzYySHCy9SWX/7OV9Cfh31iMp9ZIffr76xmmThtOEqs8TrTtU6BWI3rWwvA9cXQipZTVtL0oswrGw=
|
|
||||||
script:
|
|
||||||
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
|
|
||||||
13
vendor/github.com/go-openapi/jsonreference/.golangci.yml
generated
vendored
13
vendor/github.com/go-openapi/jsonreference/.golangci.yml
generated
vendored
@@ -1,8 +1,6 @@
|
|||||||
linters-settings:
|
linters-settings:
|
||||||
govet:
|
govet:
|
||||||
check-shadowing: true
|
check-shadowing: true
|
||||||
golint:
|
|
||||||
min-confidence: 0
|
|
||||||
gocyclo:
|
gocyclo:
|
||||||
min-complexity: 30
|
min-complexity: 30
|
||||||
maligned:
|
maligned:
|
||||||
@@ -12,6 +10,8 @@ linters-settings:
|
|||||||
goconst:
|
goconst:
|
||||||
min-len: 2
|
min-len: 2
|
||||||
min-occurrences: 4
|
min-occurrences: 4
|
||||||
|
paralleltest:
|
||||||
|
ignore-missing: true
|
||||||
linters:
|
linters:
|
||||||
enable-all: true
|
enable-all: true
|
||||||
disable:
|
disable:
|
||||||
@@ -39,3 +39,12 @@ linters:
|
|||||||
- nestif
|
- nestif
|
||||||
- godot
|
- godot
|
||||||
- errorlint
|
- errorlint
|
||||||
|
- varcheck
|
||||||
|
- interfacer
|
||||||
|
- deadcode
|
||||||
|
- golint
|
||||||
|
- ifshort
|
||||||
|
- structcheck
|
||||||
|
- nosnakecase
|
||||||
|
- varnamelen
|
||||||
|
- exhaustruct
|
||||||
|
|||||||
24
vendor/github.com/go-openapi/jsonreference/.travis.yml
generated
vendored
24
vendor/github.com/go-openapi/jsonreference/.travis.yml
generated
vendored
@@ -1,24 +0,0 @@
|
|||||||
after_success:
|
|
||||||
- bash <(curl -s https://codecov.io/bash)
|
|
||||||
go:
|
|
||||||
- 1.14.x
|
|
||||||
- 1.x
|
|
||||||
install:
|
|
||||||
- go get gotest.tools/gotestsum
|
|
||||||
jobs:
|
|
||||||
include:
|
|
||||||
# include linting job, but only for latest go version and amd64 arch
|
|
||||||
- go: 1.x
|
|
||||||
arch: amd64
|
|
||||||
install:
|
|
||||||
go get github.com/golangci/golangci-lint/cmd/golangci-lint
|
|
||||||
script:
|
|
||||||
- golangci-lint run --new-from-rev master
|
|
||||||
env:
|
|
||||||
- GO111MODULE=on
|
|
||||||
language: go
|
|
||||||
notifications:
|
|
||||||
slack:
|
|
||||||
secure: OpQG/36F7DSF00HLm9WZMhyqFCYYyYTsVDObW226cWiR8PWYiNfLZiSEvIzT1Gx4dDjhigKTIqcLhG34CkL5iNXDjm9Yyo2RYhQPlK8NErNqUEXuBqn4RqYHW48VGhEhOyDd4Ei0E2FN5ZbgpvHgtpkdZ6XDi64r3Ac89isP9aPHXQTuv2Jog6b4/OKKiUTftLcTIst0p4Cp3gqOJWf1wnoj+IadWiECNVQT6zb47IYjtyw6+uV8iUjTzdKcRB6Zc6b4Dq7JAg1Zd7Jfxkql3hlKp4PNlRf9Cy7y5iA3G7MLyg3FcPX5z2kmcyPt2jOTRMBWUJ5zIQpOxizAcN8WsT3WWBL5KbuYK6k0PzujrIDLqdxGpNmjkkMfDBT9cKmZpm2FdW+oZgPFJP+oKmAo4u4KJz/vjiPTXgQlN5bmrLuRMCp+AwC5wkIohTqWZVPE2TK6ZSnMYcg/W39s+RP/9mJoyryAvPSpBOLTI+biCgaUCTOAZxNTWpMFc3tPYntc41WWkdKcooZ9JA5DwfcaVFyTGQ3YXz+HvX6G1z/gW0Q/A4dBi9mj2iE1xm7tRTT+4VQ2AXFvSEI1HJpfPgYnwAtwOD1v3Qm2EUHk9sCdtEDR4wVGEPIVn44GnwFMnGKx9JWppMPYwFu3SVDdHt+E+LOlhZUply11Aa+IVrT2KUQ=
|
|
||||||
script:
|
|
||||||
- gotestsum -f short-verbose -- -race -coverprofile=coverage.txt -covermode=atomic ./...
|
|
||||||
12
vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
generated
vendored
12
vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go
generated
vendored
@@ -7,8 +7,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultHttpPort = ":80"
|
defaultHTTPPort = ":80"
|
||||||
defaultHttpsPort = ":443"
|
defaultHTTPSPort = ":443"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Regular expressions used by the normalizations
|
// Regular expressions used by the normalizations
|
||||||
@@ -18,6 +18,7 @@ var rxDupSlashes = regexp.MustCompile(`/{2,}`)
|
|||||||
// NormalizeURL will normalize the specified URL
|
// NormalizeURL will normalize the specified URL
|
||||||
// This was added to replace a previous call to the no longer maintained purell library:
|
// This was added to replace a previous call to the no longer maintained purell library:
|
||||||
// The call that was used looked like the following:
|
// The call that was used looked like the following:
|
||||||
|
//
|
||||||
// url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes))
|
// url.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes))
|
||||||
//
|
//
|
||||||
// To explain all that was included in the call above, purell.FlagsSafe was really just the following:
|
// To explain all that was included in the call above, purell.FlagsSafe was really just the following:
|
||||||
@@ -25,11 +26,16 @@ var rxDupSlashes = regexp.MustCompile(`/{2,}`)
|
|||||||
// - FlagLowercaseHost
|
// - FlagLowercaseHost
|
||||||
// - FlagRemoveDefaultPort
|
// - FlagRemoveDefaultPort
|
||||||
// - FlagRemoveDuplicateSlashes (and this was mixed in with the |)
|
// - FlagRemoveDuplicateSlashes (and this was mixed in with the |)
|
||||||
|
//
|
||||||
|
// This also normalizes the URL into its urlencoded form by removing RawPath and RawFragment.
|
||||||
func NormalizeURL(u *url.URL) {
|
func NormalizeURL(u *url.URL) {
|
||||||
lowercaseScheme(u)
|
lowercaseScheme(u)
|
||||||
lowercaseHost(u)
|
lowercaseHost(u)
|
||||||
removeDefaultPort(u)
|
removeDefaultPort(u)
|
||||||
removeDuplicateSlashes(u)
|
removeDuplicateSlashes(u)
|
||||||
|
|
||||||
|
u.RawPath = ""
|
||||||
|
u.RawFragment = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func lowercaseScheme(u *url.URL) {
|
func lowercaseScheme(u *url.URL) {
|
||||||
@@ -48,7 +54,7 @@ func removeDefaultPort(u *url.URL) {
|
|||||||
if len(u.Host) > 0 {
|
if len(u.Host) > 0 {
|
||||||
scheme := strings.ToLower(u.Scheme)
|
scheme := strings.ToLower(u.Scheme)
|
||||||
u.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string {
|
u.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string {
|
||||||
if (scheme == "http" && val == defaultHttpPort) || (scheme == "https" && val == defaultHttpsPort) {
|
if (scheme == "http" && val == defaultHTTPPort) || (scheme == "https" && val == defaultHTTPSPort) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return val
|
return val
|
||||||
|
|||||||
14
vendor/github.com/go-task/slim-sprig/.editorconfig
generated
vendored
Normal file
14
vendor/github.com/go-task/slim-sprig/.editorconfig
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 8
|
||||||
|
|
||||||
|
[*.{md,yml,yaml,json}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
1
vendor/github.com/go-task/slim-sprig/.gitattributes
generated
vendored
Normal file
1
vendor/github.com/go-task/slim-sprig/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* text=auto
|
||||||
2
vendor/github.com/go-task/slim-sprig/.gitignore
generated
vendored
Normal file
2
vendor/github.com/go-task/slim-sprig/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
vendor/
|
||||||
|
/.glide
|
||||||
364
vendor/github.com/go-task/slim-sprig/CHANGELOG.md
generated
vendored
Normal file
364
vendor/github.com/go-task/slim-sprig/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## Release 3.2.0 (2020-12-14)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #211: Added randInt function (thanks @kochurovro)
|
||||||
|
- #223: Added fromJson and mustFromJson functions (thanks @mholt)
|
||||||
|
- #242: Added a bcrypt function (thanks @robbiet480)
|
||||||
|
- #253: Added randBytes function (thanks @MikaelSmith)
|
||||||
|
- #254: Added dig function for dicts (thanks @nyarly)
|
||||||
|
- #257: Added regexQuoteMeta for quoting regex metadata (thanks @rheaton)
|
||||||
|
- #261: Added filepath functions osBase, osDir, osExt, osClean, osIsAbs (thanks @zugl)
|
||||||
|
- #268: Added and and all functions for testing conditions (thanks @phuslu)
|
||||||
|
- #181: Added float64 arithmetic addf, add1f, subf, divf, mulf, maxf, and minf
|
||||||
|
(thanks @andrewmostello)
|
||||||
|
- #265: Added chunk function to split array into smaller arrays (thanks @karelbilek)
|
||||||
|
- #270: Extend certificate functions to handle non-RSA keys + add support for
|
||||||
|
ed25519 keys (thanks @misberner)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Removed testing and support for Go 1.12. ed25519 support requires Go 1.13 or newer
|
||||||
|
- Using semver 3.1.1 and mergo 0.3.11
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #249: Fix htmlDateInZone example (thanks @spawnia)
|
||||||
|
|
||||||
|
NOTE: The dependency github.com/imdario/mergo reverted the breaking change in
|
||||||
|
0.3.9 via 0.3.10 release.
|
||||||
|
|
||||||
|
## Release 3.1.0 (2020-04-16)
|
||||||
|
|
||||||
|
NOTE: The dependency github.com/imdario/mergo made a behavior change in 0.3.9
|
||||||
|
that impacts sprig functionality. Do not use sprig with a version newer than 0.3.8.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #225: Added support for generating htpasswd hash (thanks @rustycl0ck)
|
||||||
|
- #224: Added duration filter (thanks @frebib)
|
||||||
|
- #205: Added `seq` function (thanks @thadc23)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #203: Unlambda functions with correct signature (thanks @muesli)
|
||||||
|
- #236: Updated the license formatting for GitHub display purposes
|
||||||
|
- #238: Updated package dependency versions. Note, mergo not updated to 0.3.9
|
||||||
|
as it causes a breaking change for sprig. That issue is tracked at
|
||||||
|
https://github.com/imdario/mergo/issues/139
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #229: Fix `seq` example in docs (thanks @kalmant)
|
||||||
|
|
||||||
|
## Release 3.0.2 (2019-12-13)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #220: Updating to semver v3.0.3 to fix issue with <= ranges
|
||||||
|
- #218: fix typo elyptical->elliptic in ecdsa key description (thanks @laverya)
|
||||||
|
|
||||||
|
## Release 3.0.1 (2019-12-08)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #212: Updated semver fixing broken constraint checking with ^0.0
|
||||||
|
|
||||||
|
## Release 3.0.0 (2019-10-02)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #187: Added durationRound function (thanks @yjp20)
|
||||||
|
- #189: Added numerous template functions that return errors rather than panic (thanks @nrvnrvn)
|
||||||
|
- #193: Added toRawJson support (thanks @Dean-Coakley)
|
||||||
|
- #197: Added get support to dicts (thanks @Dean-Coakley)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #186: Moving dependency management to Go modules
|
||||||
|
- #186: Updated semver to v3. This has changes in the way ^ is handled
|
||||||
|
- #194: Updated documentation on merging and how it copies. Added example using deepCopy
|
||||||
|
- #196: trunc now supports negative values (thanks @Dean-Coakley)
|
||||||
|
|
||||||
|
## Release 2.22.0 (2019-10-02)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #173: Added getHostByName function to resolve dns names to ips (thanks @fcgravalos)
|
||||||
|
- #195: Added deepCopy function for use with dicts
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Updated merge and mergeOverwrite documentation to explain copying and how to
|
||||||
|
use deepCopy with it
|
||||||
|
|
||||||
|
## Release 2.21.0 (2019-09-18)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #122: Added encryptAES/decryptAES functions (thanks @n0madic)
|
||||||
|
- #128: Added toDecimal support (thanks @Dean-Coakley)
|
||||||
|
- #169: Added list contcat (thanks @astorath)
|
||||||
|
- #174: Added deepEqual function (thanks @bonifaido)
|
||||||
|
- #170: Added url parse and join functions (thanks @astorath)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #171: Updated glide config for Google UUID to v1 and to add ranges to semver and testify
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #172: Fix semver wildcard example (thanks @piepmatz)
|
||||||
|
- #175: Fix dateInZone doc example (thanks @s3than)
|
||||||
|
|
||||||
|
## Release 2.20.0 (2019-06-18)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #164: Adding function to get unix epoch for a time (@mattfarina)
|
||||||
|
- #166: Adding tests for date_in_zone (@mattfarina)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #144: Fix function comments based on best practices from Effective Go (@CodeLingoTeam)
|
||||||
|
- #150: Handles pointer type for time.Time in "htmlDate" (@mapreal19)
|
||||||
|
- #161, #157, #160, #153, #158, #156, #155, #159, #152 documentation updates (@badeadan)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
## Release 2.19.0 (2019-03-02)
|
||||||
|
|
||||||
|
IMPORTANT: This release reverts a change from 2.18.0
|
||||||
|
|
||||||
|
In the previous release (2.18), we prematurely merged a partial change to the crypto functions that led to creating two sets of crypto functions (I blame @technosophos -- since that's me). This release rolls back that change, and does what was originally intended: It alters the existing crypto functions to use secure random.
|
||||||
|
|
||||||
|
We debated whether this classifies as a change worthy of major revision, but given the proximity to the last release, we have decided that treating 2.18 as a faulty release is the correct course of action. We apologize for any inconvenience.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Fix substr panic 35fb796 (Alexey igrychev)
|
||||||
|
- Remove extra period 1eb7729 (Matthew Lorimor)
|
||||||
|
- Make random string functions use crypto by default 6ceff26 (Matthew Lorimor)
|
||||||
|
- README edits/fixes/suggestions 08fe136 (Lauri Apple)
|
||||||
|
|
||||||
|
|
||||||
|
## Release 2.18.0 (2019-02-12)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added mergeOverwrite function
|
||||||
|
- cryptographic functions that use secure random (see fe1de12)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Improve documentation of regexMatch function, resolves #139 90b89ce (Jan Tagscherer)
|
||||||
|
- Handle has for nil list 9c10885 (Daniel Cohen)
|
||||||
|
- Document behaviour of mergeOverwrite fe0dbe9 (Lukas Rieder)
|
||||||
|
- doc: adds missing documentation. 4b871e6 (Fernandez Ludovic)
|
||||||
|
- Replace outdated goutils imports 01893d2 (Matthew Lorimor)
|
||||||
|
- Surface crypto secure random strings from goutils fe1de12 (Matthew Lorimor)
|
||||||
|
- Handle untyped nil values as paramters to string functions 2b2ec8f (Morten Torkildsen)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix dict merge issue and provide mergeOverwrite .dst .src1 to overwrite from src -> dst 4c59c12 (Lukas Rieder)
|
||||||
|
- Fix substr var names and comments d581f80 (Dean Coakley)
|
||||||
|
- Fix substr documentation 2737203 (Dean Coakley)
|
||||||
|
|
||||||
|
## Release 2.17.1 (2019-01-03)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
The 2.17.0 release did not have a version pinned for xstrings, which caused compilation failures when xstrings < 1.2 was used. This adds the correct version string to glide.yaml.
|
||||||
|
|
||||||
|
## Release 2.17.0 (2019-01-03)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- adds alder32sum function and test 6908fc2 (marshallford)
|
||||||
|
- Added kebabcase function ca331a1 (Ilyes512)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Update goutils to 1.1.0 4e1125d (Matt Butcher)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix 'has' documentation e3f2a85 (dean-coakley)
|
||||||
|
- docs(dict): fix typo in pick example dc424f9 (Dustin Specker)
|
||||||
|
- fixes spelling errors... not sure how that happened 4cf188a (marshallford)
|
||||||
|
|
||||||
|
## Release 2.16.0 (2018-08-13)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- add splitn function fccb0b0 (Helgi Þorbjörnsson)
|
||||||
|
- Add slice func df28ca7 (gongdo)
|
||||||
|
- Generate serial number a3bdffd (Cody Coons)
|
||||||
|
- Extract values of dict with values function df39312 (Lawrence Jones)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Modify panic message for list.slice ae38335 (gongdo)
|
||||||
|
- Minor improvement in code quality - Removed an unreachable piece of code at defaults.go#L26:6 - Resolve formatting issues. 5834241 (Abhishek Kashyap)
|
||||||
|
- Remove duplicated documentation 1d97af1 (Matthew Fisher)
|
||||||
|
- Test on go 1.11 49df809 (Helgi Þormar Þorbjörnsson)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix file permissions c5f40b5 (gongdo)
|
||||||
|
- Fix example for buildCustomCert 7779e0d (Tin Lam)
|
||||||
|
|
||||||
|
## Release 2.15.0 (2018-04-02)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #68 and #69: Add json helpers to docs (thanks @arunvelsriram)
|
||||||
|
- #66: Add ternary function (thanks @binoculars)
|
||||||
|
- #67: Allow keys function to take multiple dicts (thanks @binoculars)
|
||||||
|
- #89: Added sha1sum to crypto function (thanks @benkeil)
|
||||||
|
- #81: Allow customizing Root CA that used by genSignedCert (thanks @chenzhiwei)
|
||||||
|
- #92: Add travis testing for go 1.10
|
||||||
|
- #93: Adding appveyor config for windows testing
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #90: Updating to more recent dependencies
|
||||||
|
- #73: replace satori/go.uuid with google/uuid (thanks @petterw)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #76: Fixed documentation typos (thanks @Thiht)
|
||||||
|
- Fixed rounding issue on the `ago` function. Note, the removes support for Go 1.8 and older
|
||||||
|
|
||||||
|
## Release 2.14.1 (2017-12-01)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- #60: Fix typo in function name documentation (thanks @neil-ca-moore)
|
||||||
|
- #61: Removing line with {{ due to blocking github pages genertion
|
||||||
|
- #64: Update the list functions to handle int, string, and other slices for compatibility
|
||||||
|
|
||||||
|
## Release 2.14.0 (2017-10-06)
|
||||||
|
|
||||||
|
This new version of Sprig adds a set of functions for generating and working with SSL certificates.
|
||||||
|
|
||||||
|
- `genCA` generates an SSL Certificate Authority
|
||||||
|
- `genSelfSignedCert` generates an SSL self-signed certificate
|
||||||
|
- `genSignedCert` generates an SSL certificate and key based on a given CA
|
||||||
|
|
||||||
|
## Release 2.13.0 (2017-09-18)
|
||||||
|
|
||||||
|
This release adds new functions, including:
|
||||||
|
|
||||||
|
- `regexMatch`, `regexFindAll`, `regexFind`, `regexReplaceAll`, `regexReplaceAllLiteral`, and `regexSplit` to work with regular expressions
|
||||||
|
- `floor`, `ceil`, and `round` math functions
|
||||||
|
- `toDate` converts a string to a date
|
||||||
|
- `nindent` is just like `indent` but also prepends a new line
|
||||||
|
- `ago` returns the time from `time.Now`
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- #40: Added basic regex functionality (thanks @alanquillin)
|
||||||
|
- #41: Added ceil floor and round functions (thanks @alanquillin)
|
||||||
|
- #48: Added toDate function (thanks @andreynering)
|
||||||
|
- #50: Added nindent function (thanks @binoculars)
|
||||||
|
- #46: Added ago function (thanks @slayer)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- #51: Updated godocs to include new string functions (thanks @curtisallen)
|
||||||
|
- #49: Added ability to merge multiple dicts (thanks @binoculars)
|
||||||
|
|
||||||
|
## Release 2.12.0 (2017-05-17)
|
||||||
|
|
||||||
|
- `snakecase`, `camelcase`, and `shuffle` are three new string functions
|
||||||
|
- `fail` allows you to bail out of a template render when conditions are not met
|
||||||
|
|
||||||
|
## Release 2.11.0 (2017-05-02)
|
||||||
|
|
||||||
|
- Added `toJson` and `toPrettyJson`
|
||||||
|
- Added `merge`
|
||||||
|
- Refactored documentation
|
||||||
|
|
||||||
|
## Release 2.10.0 (2017-03-15)
|
||||||
|
|
||||||
|
- Added `semver` and `semverCompare` for Semantic Versions
|
||||||
|
- `list` replaces `tuple`
|
||||||
|
- Fixed issue with `join`
|
||||||
|
- Added `first`, `last`, `intial`, `rest`, `prepend`, `append`, `toString`, `toStrings`, `sortAlpha`, `reverse`, `coalesce`, `pluck`, `pick`, `compact`, `keys`, `omit`, `uniq`, `has`, `without`
|
||||||
|
|
||||||
|
## Release 2.9.0 (2017-02-23)
|
||||||
|
|
||||||
|
- Added `splitList` to split a list
|
||||||
|
- Added crypto functions of `genPrivateKey` and `derivePassword`
|
||||||
|
|
||||||
|
## Release 2.8.0 (2016-12-21)
|
||||||
|
|
||||||
|
- Added access to several path functions (`base`, `dir`, `clean`, `ext`, and `abs`)
|
||||||
|
- Added functions for _mutating_ dictionaries (`set`, `unset`, `hasKey`)
|
||||||
|
|
||||||
|
## Release 2.7.0 (2016-12-01)
|
||||||
|
|
||||||
|
- Added `sha256sum` to generate a hash of an input
|
||||||
|
- Added functions to convert a numeric or string to `int`, `int64`, `float64`
|
||||||
|
|
||||||
|
## Release 2.6.0 (2016-10-03)
|
||||||
|
|
||||||
|
- Added a `uuidv4` template function for generating UUIDs inside of a template.
|
||||||
|
|
||||||
|
## Release 2.5.0 (2016-08-19)
|
||||||
|
|
||||||
|
- New `trimSuffix`, `trimPrefix`, `hasSuffix`, and `hasPrefix` functions
|
||||||
|
- New aliases have been added for a few functions that didn't follow the naming conventions (`trimAll` and `abbrevBoth`)
|
||||||
|
- `trimall` and `abbrevboth` (notice the case) are deprecated and will be removed in 3.0.0
|
||||||
|
|
||||||
|
## Release 2.4.0 (2016-08-16)
|
||||||
|
|
||||||
|
- Adds two functions: `until` and `untilStep`
|
||||||
|
|
||||||
|
## Release 2.3.0 (2016-06-21)
|
||||||
|
|
||||||
|
- cat: Concatenate strings with whitespace separators.
|
||||||
|
- replace: Replace parts of a string: `replace " " "-" "Me First"` renders "Me-First"
|
||||||
|
- plural: Format plurals: `len "foo" | plural "one foo" "many foos"` renders "many foos"
|
||||||
|
- indent: Indent blocks of text in a way that is sensitive to "\n" characters.
|
||||||
|
|
||||||
|
## Release 2.2.0 (2016-04-21)
|
||||||
|
|
||||||
|
- Added a `genPrivateKey` function (Thanks @bacongobbler)
|
||||||
|
|
||||||
|
## Release 2.1.0 (2016-03-30)
|
||||||
|
|
||||||
|
- `default` now prints the default value when it does not receive a value down the pipeline. It is much safer now to do `{{.Foo | default "bar"}}`.
|
||||||
|
- Added accessors for "hermetic" functions. These return only functions that, when given the same input, produce the same output.
|
||||||
|
|
||||||
|
## Release 2.0.0 (2016-03-29)
|
||||||
|
|
||||||
|
Because we switched from `int` to `int64` as the return value for all integer math functions, the library's major version number has been incremented.
|
||||||
|
|
||||||
|
- `min` complements `max` (formerly `biggest`)
|
||||||
|
- `empty` indicates that a value is the empty value for its type
|
||||||
|
- `tuple` creates a tuple inside of a template: `{{$t := tuple "a", "b" "c"}}`
|
||||||
|
- `dict` creates a dictionary inside of a template `{{$d := dict "key1" "val1" "key2" "val2"}}`
|
||||||
|
- Date formatters have been added for HTML dates (as used in `date` input fields)
|
||||||
|
- Integer math functions can convert from a number of types, including `string` (via `strconv.ParseInt`).
|
||||||
|
|
||||||
|
## Release 1.2.0 (2016-02-01)
|
||||||
|
|
||||||
|
- Added quote and squote
|
||||||
|
- Added b32enc and b32dec
|
||||||
|
- add now takes varargs
|
||||||
|
- biggest now takes varargs
|
||||||
|
|
||||||
|
## Release 1.1.0 (2015-12-29)
|
||||||
|
|
||||||
|
- Added #4: Added contains function. strings.Contains, but with the arguments
|
||||||
|
switched to simplify common pipelines. (thanks krancour)
|
||||||
|
- Added Travis-CI testing support
|
||||||
|
|
||||||
|
## Release 1.0.0 (2015-12-23)
|
||||||
|
|
||||||
|
- Initial release
|
||||||
19
vendor/github.com/go-task/slim-sprig/LICENSE.txt
generated
vendored
Normal file
19
vendor/github.com/go-task/slim-sprig/LICENSE.txt
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright (C) 2013-2020 Masterminds
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
73
vendor/github.com/go-task/slim-sprig/README.md
generated
vendored
Normal file
73
vendor/github.com/go-task/slim-sprig/README.md
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# Slim-Sprig: Template functions for Go templates [](https://godoc.org/github.com/go-task/slim-sprig) [](https://goreportcard.com/report/github.com/go-task/slim-sprig)
|
||||||
|
|
||||||
|
Slim-Sprig is a fork of [Sprig](https://github.com/Masterminds/sprig), but with
|
||||||
|
all functions that depend on external (non standard library) or crypto packages
|
||||||
|
removed.
|
||||||
|
The reason for this is to make this library more lightweight. Most of these
|
||||||
|
functions (specially crypto ones) are not needed on most apps, but costs a lot
|
||||||
|
in terms of binary size and compilation time.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
**Template developers**: Please use Slim-Sprig's [function documentation](https://go-task.github.io/slim-sprig/) for
|
||||||
|
detailed instructions and code snippets for the >100 template functions available.
|
||||||
|
|
||||||
|
**Go developers**: If you'd like to include Slim-Sprig as a library in your program,
|
||||||
|
our API documentation is available [at GoDoc.org](http://godoc.org/github.com/go-task/slim-sprig).
|
||||||
|
|
||||||
|
For standard usage, read on.
|
||||||
|
|
||||||
|
### Load the Slim-Sprig library
|
||||||
|
|
||||||
|
To load the Slim-Sprig `FuncMap`:
|
||||||
|
|
||||||
|
```go
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
|
||||||
|
"github.com/go-task/slim-sprig"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This example illustrates that the FuncMap *must* be set before the
|
||||||
|
// templates themselves are loaded.
|
||||||
|
tpl := template.Must(
|
||||||
|
template.New("base").Funcs(sprig.FuncMap()).ParseGlob("*.html")
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Calling the functions inside of templates
|
||||||
|
|
||||||
|
By convention, all functions are lowercase. This seems to follow the Go
|
||||||
|
idiom for template functions (as opposed to template methods, which are
|
||||||
|
TitleCase). For example, this:
|
||||||
|
|
||||||
|
```
|
||||||
|
{{ "hello!" | upper | repeat 5 }}
|
||||||
|
```
|
||||||
|
|
||||||
|
produces this:
|
||||||
|
|
||||||
|
```
|
||||||
|
HELLO!HELLO!HELLO!HELLO!HELLO!
|
||||||
|
```
|
||||||
|
|
||||||
|
## Principles Driving Our Function Selection
|
||||||
|
|
||||||
|
We followed these principles to decide which functions to add and how to implement them:
|
||||||
|
|
||||||
|
- Use template functions to build layout. The following
|
||||||
|
types of operations are within the domain of template functions:
|
||||||
|
- Formatting
|
||||||
|
- Layout
|
||||||
|
- Simple type conversions
|
||||||
|
- Utilities that assist in handling common formatting and layout needs (e.g. arithmetic)
|
||||||
|
- Template functions should not return errors unless there is no way to print
|
||||||
|
a sensible value. For example, converting a string to an integer should not
|
||||||
|
produce an error if conversion fails. Instead, it should display a default
|
||||||
|
value.
|
||||||
|
- Simple math is necessary for grid layouts, pagers, and so on. Complex math
|
||||||
|
(anything other than arithmetic) should be done outside of templates.
|
||||||
|
- Template functions only deal with the data passed into them. They never retrieve
|
||||||
|
data from a source.
|
||||||
|
- Finally, do not override core Go template functions.
|
||||||
12
vendor/github.com/go-task/slim-sprig/Taskfile.yml
generated
vendored
Normal file
12
vendor/github.com/go-task/slim-sprig/Taskfile.yml
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# https://taskfile.dev
|
||||||
|
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
default:
|
||||||
|
cmds:
|
||||||
|
- task: test
|
||||||
|
|
||||||
|
test:
|
||||||
|
cmds:
|
||||||
|
- go test -v .
|
||||||
24
vendor/github.com/go-task/slim-sprig/crypto.go
generated
vendored
Normal file
24
vendor/github.com/go-task/slim-sprig/crypto.go
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package sprig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"hash/adler32"
|
||||||
|
)
|
||||||
|
|
||||||
|
func sha256sum(input string) string {
|
||||||
|
hash := sha256.Sum256([]byte(input))
|
||||||
|
return hex.EncodeToString(hash[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func sha1sum(input string) string {
|
||||||
|
hash := sha1.Sum([]byte(input))
|
||||||
|
return hex.EncodeToString(hash[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func adler32sum(input string) string {
|
||||||
|
hash := adler32.Checksum([]byte(input))
|
||||||
|
return fmt.Sprintf("%d", hash)
|
||||||
|
}
|
||||||
152
vendor/github.com/go-task/slim-sprig/date.go
generated
vendored
Normal file
152
vendor/github.com/go-task/slim-sprig/date.go
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
package sprig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Given a format and a date, format the date string.
|
||||||
|
//
|
||||||
|
// Date can be a `time.Time` or an `int, int32, int64`.
|
||||||
|
// In the later case, it is treated as seconds since UNIX
|
||||||
|
// epoch.
|
||||||
|
func date(fmt string, date interface{}) string {
|
||||||
|
return dateInZone(fmt, date, "Local")
|
||||||
|
}
|
||||||
|
|
||||||
|
func htmlDate(date interface{}) string {
|
||||||
|
return dateInZone("2006-01-02", date, "Local")
|
||||||
|
}
|
||||||
|
|
||||||
|
func htmlDateInZone(date interface{}, zone string) string {
|
||||||
|
return dateInZone("2006-01-02", date, zone)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dateInZone(fmt string, date interface{}, zone string) string {
|
||||||
|
var t time.Time
|
||||||
|
switch date := date.(type) {
|
||||||
|
default:
|
||||||
|
t = time.Now()
|
||||||
|
case time.Time:
|
||||||
|
t = date
|
||||||
|
case *time.Time:
|
||||||
|
t = *date
|
||||||
|
case int64:
|
||||||
|
t = time.Unix(date, 0)
|
||||||
|
case int:
|
||||||
|
t = time.Unix(int64(date), 0)
|
||||||
|
case int32:
|
||||||
|
t = time.Unix(int64(date), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
loc, err := time.LoadLocation(zone)
|
||||||
|
if err != nil {
|
||||||
|
loc, _ = time.LoadLocation("UTC")
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.In(loc).Format(fmt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dateModify(fmt string, date time.Time) time.Time {
|
||||||
|
d, err := time.ParseDuration(fmt)
|
||||||
|
if err != nil {
|
||||||
|
return date
|
||||||
|
}
|
||||||
|
return date.Add(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustDateModify(fmt string, date time.Time) (time.Time, error) {
|
||||||
|
d, err := time.ParseDuration(fmt)
|
||||||
|
if err != nil {
|
||||||
|
return time.Time{}, err
|
||||||
|
}
|
||||||
|
return date.Add(d), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dateAgo(date interface{}) string {
|
||||||
|
var t time.Time
|
||||||
|
|
||||||
|
switch date := date.(type) {
|
||||||
|
default:
|
||||||
|
t = time.Now()
|
||||||
|
case time.Time:
|
||||||
|
t = date
|
||||||
|
case int64:
|
||||||
|
t = time.Unix(date, 0)
|
||||||
|
case int:
|
||||||
|
t = time.Unix(int64(date), 0)
|
||||||
|
}
|
||||||
|
// Drop resolution to seconds
|
||||||
|
duration := time.Since(t).Round(time.Second)
|
||||||
|
return duration.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func duration(sec interface{}) string {
|
||||||
|
var n int64
|
||||||
|
switch value := sec.(type) {
|
||||||
|
default:
|
||||||
|
n = 0
|
||||||
|
case string:
|
||||||
|
n, _ = strconv.ParseInt(value, 10, 64)
|
||||||
|
case int64:
|
||||||
|
n = value
|
||||||
|
}
|
||||||
|
return (time.Duration(n) * time.Second).String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func durationRound(duration interface{}) string {
|
||||||
|
var d time.Duration
|
||||||
|
switch duration := duration.(type) {
|
||||||
|
default:
|
||||||
|
d = 0
|
||||||
|
case string:
|
||||||
|
d, _ = time.ParseDuration(duration)
|
||||||
|
case int64:
|
||||||
|
d = time.Duration(duration)
|
||||||
|
case time.Time:
|
||||||
|
d = time.Since(duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
u := uint64(d)
|
||||||
|
neg := d < 0
|
||||||
|
if neg {
|
||||||
|
u = -u
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
year = uint64(time.Hour) * 24 * 365
|
||||||
|
month = uint64(time.Hour) * 24 * 30
|
||||||
|
day = uint64(time.Hour) * 24
|
||||||
|
hour = uint64(time.Hour)
|
||||||
|
minute = uint64(time.Minute)
|
||||||
|
second = uint64(time.Second)
|
||||||
|
)
|
||||||
|
switch {
|
||||||
|
case u > year:
|
||||||
|
return strconv.FormatUint(u/year, 10) + "y"
|
||||||
|
case u > month:
|
||||||
|
return strconv.FormatUint(u/month, 10) + "mo"
|
||||||
|
case u > day:
|
||||||
|
return strconv.FormatUint(u/day, 10) + "d"
|
||||||
|
case u > hour:
|
||||||
|
return strconv.FormatUint(u/hour, 10) + "h"
|
||||||
|
case u > minute:
|
||||||
|
return strconv.FormatUint(u/minute, 10) + "m"
|
||||||
|
case u > second:
|
||||||
|
return strconv.FormatUint(u/second, 10) + "s"
|
||||||
|
}
|
||||||
|
return "0s"
|
||||||
|
}
|
||||||
|
|
||||||
|
func toDate(fmt, str string) time.Time {
|
||||||
|
t, _ := time.ParseInLocation(fmt, str, time.Local)
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustToDate(fmt, str string) (time.Time, error) {
|
||||||
|
return time.ParseInLocation(fmt, str, time.Local)
|
||||||
|
}
|
||||||
|
|
||||||
|
func unixEpoch(date time.Time) string {
|
||||||
|
return strconv.FormatInt(date.Unix(), 10)
|
||||||
|
}
|
||||||
163
vendor/github.com/go-task/slim-sprig/defaults.go
generated
vendored
Normal file
163
vendor/github.com/go-task/slim-sprig/defaults.go
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
package sprig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"math/rand"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
}
|
||||||
|
|
||||||
|
// dfault checks whether `given` is set, and returns default if not set.
|
||||||
|
//
|
||||||
|
// This returns `d` if `given` appears not to be set, and `given` otherwise.
|
||||||
|
//
|
||||||
|
// For numeric types 0 is unset.
|
||||||
|
// For strings, maps, arrays, and slices, len() = 0 is considered unset.
|
||||||
|
// For bool, false is unset.
|
||||||
|
// Structs are never considered unset.
|
||||||
|
//
|
||||||
|
// For everything else, including pointers, a nil value is unset.
|
||||||
|
func dfault(d interface{}, given ...interface{}) interface{} {
|
||||||
|
|
||||||
|
if empty(given) || empty(given[0]) {
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
return given[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty returns true if the given value has the zero value for its type.
|
||||||
|
func empty(given interface{}) bool {
|
||||||
|
g := reflect.ValueOf(given)
|
||||||
|
if !g.IsValid() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basically adapted from text/template.isTrue
|
||||||
|
switch g.Kind() {
|
||||||
|
default:
|
||||||
|
return g.IsNil()
|
||||||
|
case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
|
||||||
|
return g.Len() == 0
|
||||||
|
case reflect.Bool:
|
||||||
|
return !g.Bool()
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
return g.Complex() == 0
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return g.Int() == 0
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return g.Uint() == 0
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return g.Float() == 0
|
||||||
|
case reflect.Struct:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// coalesce returns the first non-empty value.
|
||||||
|
func coalesce(v ...interface{}) interface{} {
|
||||||
|
for _, val := range v {
|
||||||
|
if !empty(val) {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// all returns true if empty(x) is false for all values x in the list.
|
||||||
|
// If the list is empty, return true.
|
||||||
|
func all(v ...interface{}) bool {
|
||||||
|
for _, val := range v {
|
||||||
|
if empty(val) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// any returns true if empty(x) is false for any x in the list.
|
||||||
|
// If the list is empty, return false.
|
||||||
|
func any(v ...interface{}) bool {
|
||||||
|
for _, val := range v {
|
||||||
|
if !empty(val) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// fromJson decodes JSON into a structured value, ignoring errors.
|
||||||
|
func fromJson(v string) interface{} {
|
||||||
|
output, _ := mustFromJson(v)
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
// mustFromJson decodes JSON into a structured value, returning errors.
|
||||||
|
func mustFromJson(v string) (interface{}, error) {
|
||||||
|
var output interface{}
|
||||||
|
err := json.Unmarshal([]byte(v), &output)
|
||||||
|
return output, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// toJson encodes an item into a JSON string
|
||||||
|
func toJson(v interface{}) string {
|
||||||
|
output, _ := json.Marshal(v)
|
||||||
|
return string(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustToJson(v interface{}) (string, error) {
|
||||||
|
output, err := json.Marshal(v)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(output), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// toPrettyJson encodes an item into a pretty (indented) JSON string
|
||||||
|
func toPrettyJson(v interface{}) string {
|
||||||
|
output, _ := json.MarshalIndent(v, "", " ")
|
||||||
|
return string(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustToPrettyJson(v interface{}) (string, error) {
|
||||||
|
output, err := json.MarshalIndent(v, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(output), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// toRawJson encodes an item into a JSON string with no escaping of HTML characters.
|
||||||
|
func toRawJson(v interface{}) string {
|
||||||
|
output, err := mustToRawJson(v)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return string(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
// mustToRawJson encodes an item into a JSON string with no escaping of HTML characters.
|
||||||
|
func mustToRawJson(v interface{}) (string, error) {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
enc := json.NewEncoder(buf)
|
||||||
|
enc.SetEscapeHTML(false)
|
||||||
|
err := enc.Encode(&v)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return strings.TrimSuffix(buf.String(), "\n"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ternary returns the first value if the last value is true, otherwise returns the second value.
|
||||||
|
func ternary(vt interface{}, vf interface{}, v bool) interface{} {
|
||||||
|
if v {
|
||||||
|
return vt
|
||||||
|
}
|
||||||
|
|
||||||
|
return vf
|
||||||
|
}
|
||||||
118
vendor/github.com/go-task/slim-sprig/dict.go
generated
vendored
Normal file
118
vendor/github.com/go-task/slim-sprig/dict.go
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
package sprig
|
||||||
|
|
||||||
|
func get(d map[string]interface{}, key string) interface{} {
|
||||||
|
if val, ok := d[key]; ok {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func set(d map[string]interface{}, key string, value interface{}) map[string]interface{} {
|
||||||
|
d[key] = value
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
func unset(d map[string]interface{}, key string) map[string]interface{} {
|
||||||
|
delete(d, key)
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasKey(d map[string]interface{}, key string) bool {
|
||||||
|
_, ok := d[key]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func pluck(key string, d ...map[string]interface{}) []interface{} {
|
||||||
|
res := []interface{}{}
|
||||||
|
for _, dict := range d {
|
||||||
|
if val, ok := dict[key]; ok {
|
||||||
|
res = append(res, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func keys(dicts ...map[string]interface{}) []string {
|
||||||
|
k := []string{}
|
||||||
|
for _, dict := range dicts {
|
||||||
|
for key := range dict {
|
||||||
|
k = append(k, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return k
|
||||||
|
}
|
||||||
|
|
||||||
|
func pick(dict map[string]interface{}, keys ...string) map[string]interface{} {
|
||||||
|
res := map[string]interface{}{}
|
||||||
|
for _, k := range keys {
|
||||||
|
if v, ok := dict[k]; ok {
|
||||||
|
res[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func omit(dict map[string]interface{}, keys ...string) map[string]interface{} {
|
||||||
|
res := map[string]interface{}{}
|
||||||
|
|
||||||
|
omit := make(map[string]bool, len(keys))
|
||||||
|
for _, k := range keys {
|
||||||
|
omit[k] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range dict {
|
||||||
|
if _, ok := omit[k]; !ok {
|
||||||
|
res[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func dict(v ...interface{}) map[string]interface{} {
|
||||||
|
dict := map[string]interface{}{}
|
||||||
|
lenv := len(v)
|
||||||
|
for i := 0; i < lenv; i += 2 {
|
||||||
|
key := strval(v[i])
|
||||||
|
if i+1 >= lenv {
|
||||||
|
dict[key] = ""
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
dict[key] = v[i+1]
|
||||||
|
}
|
||||||
|
return dict
|
||||||
|
}
|
||||||
|
|
||||||
|
func values(dict map[string]interface{}) []interface{} {
|
||||||
|
values := []interface{}{}
|
||||||
|
for _, value := range dict {
|
||||||
|
values = append(values, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
func dig(ps ...interface{}) (interface{}, error) {
|
||||||
|
if len(ps) < 3 {
|
||||||
|
panic("dig needs at least three arguments")
|
||||||
|
}
|
||||||
|
dict := ps[len(ps)-1].(map[string]interface{})
|
||||||
|
def := ps[len(ps)-2]
|
||||||
|
ks := make([]string, len(ps)-2)
|
||||||
|
for i := 0; i < len(ks); i++ {
|
||||||
|
ks[i] = ps[i].(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
return digFromDict(dict, def, ks)
|
||||||
|
}
|
||||||
|
|
||||||
|
func digFromDict(dict map[string]interface{}, d interface{}, ks []string) (interface{}, error) {
|
||||||
|
k, ns := ks[0], ks[1:len(ks)]
|
||||||
|
step, has := dict[k]
|
||||||
|
if !has {
|
||||||
|
return d, nil
|
||||||
|
}
|
||||||
|
if len(ns) == 0 {
|
||||||
|
return step, nil
|
||||||
|
}
|
||||||
|
return digFromDict(step.(map[string]interface{}), d, ns)
|
||||||
|
}
|
||||||
19
vendor/github.com/go-task/slim-sprig/doc.go
generated
vendored
Normal file
19
vendor/github.com/go-task/slim-sprig/doc.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
Package sprig provides template functions for Go.
|
||||||
|
|
||||||
|
This package contains a number of utility functions for working with data
|
||||||
|
inside of Go `html/template` and `text/template` files.
|
||||||
|
|
||||||
|
To add these functions, use the `template.Funcs()` method:
|
||||||
|
|
||||||
|
t := templates.New("foo").Funcs(sprig.FuncMap())
|
||||||
|
|
||||||
|
Note that you should add the function map before you parse any template files.
|
||||||
|
|
||||||
|
In several cases, Sprig reverses the order of arguments from the way they
|
||||||
|
appear in the standard library. This is to make it easier to pipe
|
||||||
|
arguments into functions.
|
||||||
|
|
||||||
|
See http://masterminds.github.io/sprig/ for more detailed documentation on each of the available functions.
|
||||||
|
*/
|
||||||
|
package sprig
|
||||||
317
vendor/github.com/go-task/slim-sprig/functions.go
generated
vendored
Normal file
317
vendor/github.com/go-task/slim-sprig/functions.go
generated
vendored
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
package sprig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"html/template"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
ttemplate "text/template"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FuncMap produces the function map.
|
||||||
|
//
|
||||||
|
// Use this to pass the functions into the template engine:
|
||||||
|
//
|
||||||
|
// tpl := template.New("foo").Funcs(sprig.FuncMap()))
|
||||||
|
//
|
||||||
|
func FuncMap() template.FuncMap {
|
||||||
|
return HtmlFuncMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HermeticTxtFuncMap returns a 'text/template'.FuncMap with only repeatable functions.
|
||||||
|
func HermeticTxtFuncMap() ttemplate.FuncMap {
|
||||||
|
r := TxtFuncMap()
|
||||||
|
for _, name := range nonhermeticFunctions {
|
||||||
|
delete(r, name)
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// HermeticHtmlFuncMap returns an 'html/template'.Funcmap with only repeatable functions.
|
||||||
|
func HermeticHtmlFuncMap() template.FuncMap {
|
||||||
|
r := HtmlFuncMap()
|
||||||
|
for _, name := range nonhermeticFunctions {
|
||||||
|
delete(r, name)
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// TxtFuncMap returns a 'text/template'.FuncMap
|
||||||
|
func TxtFuncMap() ttemplate.FuncMap {
|
||||||
|
return ttemplate.FuncMap(GenericFuncMap())
|
||||||
|
}
|
||||||
|
|
||||||
|
// HtmlFuncMap returns an 'html/template'.Funcmap
|
||||||
|
func HtmlFuncMap() template.FuncMap {
|
||||||
|
return template.FuncMap(GenericFuncMap())
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenericFuncMap returns a copy of the basic function map as a map[string]interface{}.
|
||||||
|
func GenericFuncMap() map[string]interface{} {
|
||||||
|
gfm := make(map[string]interface{}, len(genericMap))
|
||||||
|
for k, v := range genericMap {
|
||||||
|
gfm[k] = v
|
||||||
|
}
|
||||||
|
return gfm
|
||||||
|
}
|
||||||
|
|
||||||
|
// These functions are not guaranteed to evaluate to the same result for given input, because they
|
||||||
|
// refer to the environment or global state.
|
||||||
|
var nonhermeticFunctions = []string{
|
||||||
|
// Date functions
|
||||||
|
"date",
|
||||||
|
"date_in_zone",
|
||||||
|
"date_modify",
|
||||||
|
"now",
|
||||||
|
"htmlDate",
|
||||||
|
"htmlDateInZone",
|
||||||
|
"dateInZone",
|
||||||
|
"dateModify",
|
||||||
|
|
||||||
|
// Strings
|
||||||
|
"randAlphaNum",
|
||||||
|
"randAlpha",
|
||||||
|
"randAscii",
|
||||||
|
"randNumeric",
|
||||||
|
"randBytes",
|
||||||
|
"uuidv4",
|
||||||
|
|
||||||
|
// OS
|
||||||
|
"env",
|
||||||
|
"expandenv",
|
||||||
|
|
||||||
|
// Network
|
||||||
|
"getHostByName",
|
||||||
|
}
|
||||||
|
|
||||||
|
var genericMap = map[string]interface{}{
|
||||||
|
"hello": func() string { return "Hello!" },
|
||||||
|
|
||||||
|
// Date functions
|
||||||
|
"ago": dateAgo,
|
||||||
|
"date": date,
|
||||||
|
"date_in_zone": dateInZone,
|
||||||
|
"date_modify": dateModify,
|
||||||
|
"dateInZone": dateInZone,
|
||||||
|
"dateModify": dateModify,
|
||||||
|
"duration": duration,
|
||||||
|
"durationRound": durationRound,
|
||||||
|
"htmlDate": htmlDate,
|
||||||
|
"htmlDateInZone": htmlDateInZone,
|
||||||
|
"must_date_modify": mustDateModify,
|
||||||
|
"mustDateModify": mustDateModify,
|
||||||
|
"mustToDate": mustToDate,
|
||||||
|
"now": time.Now,
|
||||||
|
"toDate": toDate,
|
||||||
|
"unixEpoch": unixEpoch,
|
||||||
|
|
||||||
|
// Strings
|
||||||
|
"trunc": trunc,
|
||||||
|
"trim": strings.TrimSpace,
|
||||||
|
"upper": strings.ToUpper,
|
||||||
|
"lower": strings.ToLower,
|
||||||
|
"title": strings.Title,
|
||||||
|
"substr": substring,
|
||||||
|
// Switch order so that "foo" | repeat 5
|
||||||
|
"repeat": func(count int, str string) string { return strings.Repeat(str, count) },
|
||||||
|
// Deprecated: Use trimAll.
|
||||||
|
"trimall": func(a, b string) string { return strings.Trim(b, a) },
|
||||||
|
// Switch order so that "$foo" | trimall "$"
|
||||||
|
"trimAll": func(a, b string) string { return strings.Trim(b, a) },
|
||||||
|
"trimSuffix": func(a, b string) string { return strings.TrimSuffix(b, a) },
|
||||||
|
"trimPrefix": func(a, b string) string { return strings.TrimPrefix(b, a) },
|
||||||
|
// Switch order so that "foobar" | contains "foo"
|
||||||
|
"contains": func(substr string, str string) bool { return strings.Contains(str, substr) },
|
||||||
|
"hasPrefix": func(substr string, str string) bool { return strings.HasPrefix(str, substr) },
|
||||||
|
"hasSuffix": func(substr string, str string) bool { return strings.HasSuffix(str, substr) },
|
||||||
|
"quote": quote,
|
||||||
|
"squote": squote,
|
||||||
|
"cat": cat,
|
||||||
|
"indent": indent,
|
||||||
|
"nindent": nindent,
|
||||||
|
"replace": replace,
|
||||||
|
"plural": plural,
|
||||||
|
"sha1sum": sha1sum,
|
||||||
|
"sha256sum": sha256sum,
|
||||||
|
"adler32sum": adler32sum,
|
||||||
|
"toString": strval,
|
||||||
|
|
||||||
|
// Wrap Atoi to stop errors.
|
||||||
|
"atoi": func(a string) int { i, _ := strconv.Atoi(a); return i },
|
||||||
|
"int64": toInt64,
|
||||||
|
"int": toInt,
|
||||||
|
"float64": toFloat64,
|
||||||
|
"seq": seq,
|
||||||
|
"toDecimal": toDecimal,
|
||||||
|
|
||||||
|
//"gt": func(a, b int) bool {return a > b},
|
||||||
|
//"gte": func(a, b int) bool {return a >= b},
|
||||||
|
//"lt": func(a, b int) bool {return a < b},
|
||||||
|
//"lte": func(a, b int) bool {return a <= b},
|
||||||
|
|
||||||
|
// split "/" foo/bar returns map[int]string{0: foo, 1: bar}
|
||||||
|
"split": split,
|
||||||
|
"splitList": func(sep, orig string) []string { return strings.Split(orig, sep) },
|
||||||
|
// splitn "/" foo/bar/fuu returns map[int]string{0: foo, 1: bar/fuu}
|
||||||
|
"splitn": splitn,
|
||||||
|
"toStrings": strslice,
|
||||||
|
|
||||||
|
"until": until,
|
||||||
|
"untilStep": untilStep,
|
||||||
|
|
||||||
|
// VERY basic arithmetic.
|
||||||
|
"add1": func(i interface{}) int64 { return toInt64(i) + 1 },
|
||||||
|
"add": func(i ...interface{}) int64 {
|
||||||
|
var a int64 = 0
|
||||||
|
for _, b := range i {
|
||||||
|
a += toInt64(b)
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
},
|
||||||
|
"sub": func(a, b interface{}) int64 { return toInt64(a) - toInt64(b) },
|
||||||
|
"div": func(a, b interface{}) int64 { return toInt64(a) / toInt64(b) },
|
||||||
|
"mod": func(a, b interface{}) int64 { return toInt64(a) % toInt64(b) },
|
||||||
|
"mul": func(a interface{}, v ...interface{}) int64 {
|
||||||
|
val := toInt64(a)
|
||||||
|
for _, b := range v {
|
||||||
|
val = val * toInt64(b)
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
"randInt": func(min, max int) int { return rand.Intn(max-min) + min },
|
||||||
|
"biggest": max,
|
||||||
|
"max": max,
|
||||||
|
"min": min,
|
||||||
|
"maxf": maxf,
|
||||||
|
"minf": minf,
|
||||||
|
"ceil": ceil,
|
||||||
|
"floor": floor,
|
||||||
|
"round": round,
|
||||||
|
|
||||||
|
// string slices. Note that we reverse the order b/c that's better
|
||||||
|
// for template processing.
|
||||||
|
"join": join,
|
||||||
|
"sortAlpha": sortAlpha,
|
||||||
|
|
||||||
|
// Defaults
|
||||||
|
"default": dfault,
|
||||||
|
"empty": empty,
|
||||||
|
"coalesce": coalesce,
|
||||||
|
"all": all,
|
||||||
|
"any": any,
|
||||||
|
"compact": compact,
|
||||||
|
"mustCompact": mustCompact,
|
||||||
|
"fromJson": fromJson,
|
||||||
|
"toJson": toJson,
|
||||||
|
"toPrettyJson": toPrettyJson,
|
||||||
|
"toRawJson": toRawJson,
|
||||||
|
"mustFromJson": mustFromJson,
|
||||||
|
"mustToJson": mustToJson,
|
||||||
|
"mustToPrettyJson": mustToPrettyJson,
|
||||||
|
"mustToRawJson": mustToRawJson,
|
||||||
|
"ternary": ternary,
|
||||||
|
|
||||||
|
// Reflection
|
||||||
|
"typeOf": typeOf,
|
||||||
|
"typeIs": typeIs,
|
||||||
|
"typeIsLike": typeIsLike,
|
||||||
|
"kindOf": kindOf,
|
||||||
|
"kindIs": kindIs,
|
||||||
|
"deepEqual": reflect.DeepEqual,
|
||||||
|
|
||||||
|
// OS:
|
||||||
|
"env": os.Getenv,
|
||||||
|
"expandenv": os.ExpandEnv,
|
||||||
|
|
||||||
|
// Network:
|
||||||
|
"getHostByName": getHostByName,
|
||||||
|
|
||||||
|
// Paths:
|
||||||
|
"base": path.Base,
|
||||||
|
"dir": path.Dir,
|
||||||
|
"clean": path.Clean,
|
||||||
|
"ext": path.Ext,
|
||||||
|
"isAbs": path.IsAbs,
|
||||||
|
|
||||||
|
// Filepaths:
|
||||||
|
"osBase": filepath.Base,
|
||||||
|
"osClean": filepath.Clean,
|
||||||
|
"osDir": filepath.Dir,
|
||||||
|
"osExt": filepath.Ext,
|
||||||
|
"osIsAbs": filepath.IsAbs,
|
||||||
|
|
||||||
|
// Encoding:
|
||||||
|
"b64enc": base64encode,
|
||||||
|
"b64dec": base64decode,
|
||||||
|
"b32enc": base32encode,
|
||||||
|
"b32dec": base32decode,
|
||||||
|
|
||||||
|
// Data Structures:
|
||||||
|
"tuple": list, // FIXME: with the addition of append/prepend these are no longer immutable.
|
||||||
|
"list": list,
|
||||||
|
"dict": dict,
|
||||||
|
"get": get,
|
||||||
|
"set": set,
|
||||||
|
"unset": unset,
|
||||||
|
"hasKey": hasKey,
|
||||||
|
"pluck": pluck,
|
||||||
|
"keys": keys,
|
||||||
|
"pick": pick,
|
||||||
|
"omit": omit,
|
||||||
|
"values": values,
|
||||||
|
|
||||||
|
"append": push, "push": push,
|
||||||
|
"mustAppend": mustPush, "mustPush": mustPush,
|
||||||
|
"prepend": prepend,
|
||||||
|
"mustPrepend": mustPrepend,
|
||||||
|
"first": first,
|
||||||
|
"mustFirst": mustFirst,
|
||||||
|
"rest": rest,
|
||||||
|
"mustRest": mustRest,
|
||||||
|
"last": last,
|
||||||
|
"mustLast": mustLast,
|
||||||
|
"initial": initial,
|
||||||
|
"mustInitial": mustInitial,
|
||||||
|
"reverse": reverse,
|
||||||
|
"mustReverse": mustReverse,
|
||||||
|
"uniq": uniq,
|
||||||
|
"mustUniq": mustUniq,
|
||||||
|
"without": without,
|
||||||
|
"mustWithout": mustWithout,
|
||||||
|
"has": has,
|
||||||
|
"mustHas": mustHas,
|
||||||
|
"slice": slice,
|
||||||
|
"mustSlice": mustSlice,
|
||||||
|
"concat": concat,
|
||||||
|
"dig": dig,
|
||||||
|
"chunk": chunk,
|
||||||
|
"mustChunk": mustChunk,
|
||||||
|
|
||||||
|
// Flow Control:
|
||||||
|
"fail": func(msg string) (string, error) { return "", errors.New(msg) },
|
||||||
|
|
||||||
|
// Regex
|
||||||
|
"regexMatch": regexMatch,
|
||||||
|
"mustRegexMatch": mustRegexMatch,
|
||||||
|
"regexFindAll": regexFindAll,
|
||||||
|
"mustRegexFindAll": mustRegexFindAll,
|
||||||
|
"regexFind": regexFind,
|
||||||
|
"mustRegexFind": mustRegexFind,
|
||||||
|
"regexReplaceAll": regexReplaceAll,
|
||||||
|
"mustRegexReplaceAll": mustRegexReplaceAll,
|
||||||
|
"regexReplaceAllLiteral": regexReplaceAllLiteral,
|
||||||
|
"mustRegexReplaceAllLiteral": mustRegexReplaceAllLiteral,
|
||||||
|
"regexSplit": regexSplit,
|
||||||
|
"mustRegexSplit": mustRegexSplit,
|
||||||
|
"regexQuoteMeta": regexQuoteMeta,
|
||||||
|
|
||||||
|
// URLs:
|
||||||
|
"urlParse": urlParse,
|
||||||
|
"urlJoin": urlJoin,
|
||||||
|
}
|
||||||
464
vendor/github.com/go-task/slim-sprig/list.go
generated
vendored
Normal file
464
vendor/github.com/go-task/slim-sprig/list.go
generated
vendored
Normal file
@@ -0,0 +1,464 @@
|
|||||||
|
package sprig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reflection is used in these functions so that slices and arrays of strings,
|
||||||
|
// ints, and other types not implementing []interface{} can be worked with.
|
||||||
|
// For example, this is useful if you need to work on the output of regexs.
|
||||||
|
|
||||||
|
func list(v ...interface{}) []interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func push(list interface{}, v interface{}) []interface{} {
|
||||||
|
l, err := mustPush(list, v)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustPush(list interface{}, v interface{}) ([]interface{}, error) {
|
||||||
|
tp := reflect.TypeOf(list).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(list)
|
||||||
|
|
||||||
|
l := l2.Len()
|
||||||
|
nl := make([]interface{}, l)
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
nl[i] = l2.Index(i).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
return append(nl, v), nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Cannot push on type %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepend(list interface{}, v interface{}) []interface{} {
|
||||||
|
l, err := mustPrepend(list, v)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustPrepend(list interface{}, v interface{}) ([]interface{}, error) {
|
||||||
|
//return append([]interface{}{v}, list...)
|
||||||
|
|
||||||
|
tp := reflect.TypeOf(list).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(list)
|
||||||
|
|
||||||
|
l := l2.Len()
|
||||||
|
nl := make([]interface{}, l)
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
nl[i] = l2.Index(i).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
return append([]interface{}{v}, nl...), nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Cannot prepend on type %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func chunk(size int, list interface{}) [][]interface{} {
|
||||||
|
l, err := mustChunk(size, list)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustChunk(size int, list interface{}) ([][]interface{}, error) {
|
||||||
|
tp := reflect.TypeOf(list).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(list)
|
||||||
|
|
||||||
|
l := l2.Len()
|
||||||
|
|
||||||
|
cs := int(math.Floor(float64(l-1)/float64(size)) + 1)
|
||||||
|
nl := make([][]interface{}, cs)
|
||||||
|
|
||||||
|
for i := 0; i < cs; i++ {
|
||||||
|
clen := size
|
||||||
|
if i == cs-1 {
|
||||||
|
clen = int(math.Floor(math.Mod(float64(l), float64(size))))
|
||||||
|
if clen == 0 {
|
||||||
|
clen = size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nl[i] = make([]interface{}, clen)
|
||||||
|
|
||||||
|
for j := 0; j < clen; j++ {
|
||||||
|
ix := i*size + j
|
||||||
|
nl[i][j] = l2.Index(ix).Interface()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nl, nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Cannot chunk type %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func last(list interface{}) interface{} {
|
||||||
|
l, err := mustLast(list)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustLast(list interface{}) (interface{}, error) {
|
||||||
|
tp := reflect.TypeOf(list).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(list)
|
||||||
|
|
||||||
|
l := l2.Len()
|
||||||
|
if l == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return l2.Index(l - 1).Interface(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Cannot find last on type %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func first(list interface{}) interface{} {
|
||||||
|
l, err := mustFirst(list)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustFirst(list interface{}) (interface{}, error) {
|
||||||
|
tp := reflect.TypeOf(list).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(list)
|
||||||
|
|
||||||
|
l := l2.Len()
|
||||||
|
if l == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return l2.Index(0).Interface(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Cannot find first on type %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rest(list interface{}) []interface{} {
|
||||||
|
l, err := mustRest(list)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustRest(list interface{}) ([]interface{}, error) {
|
||||||
|
tp := reflect.TypeOf(list).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(list)
|
||||||
|
|
||||||
|
l := l2.Len()
|
||||||
|
if l == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
nl := make([]interface{}, l-1)
|
||||||
|
for i := 1; i < l; i++ {
|
||||||
|
nl[i-1] = l2.Index(i).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nl, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Cannot find rest on type %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initial(list interface{}) []interface{} {
|
||||||
|
l, err := mustInitial(list)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustInitial(list interface{}) ([]interface{}, error) {
|
||||||
|
tp := reflect.TypeOf(list).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(list)
|
||||||
|
|
||||||
|
l := l2.Len()
|
||||||
|
if l == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
nl := make([]interface{}, l-1)
|
||||||
|
for i := 0; i < l-1; i++ {
|
||||||
|
nl[i] = l2.Index(i).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nl, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Cannot find initial on type %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sortAlpha(list interface{}) []string {
|
||||||
|
k := reflect.Indirect(reflect.ValueOf(list)).Kind()
|
||||||
|
switch k {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
a := strslice(list)
|
||||||
|
s := sort.StringSlice(a)
|
||||||
|
s.Sort()
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return []string{strval(list)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func reverse(v interface{}) []interface{} {
|
||||||
|
l, err := mustReverse(v)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustReverse(v interface{}) ([]interface{}, error) {
|
||||||
|
tp := reflect.TypeOf(v).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(v)
|
||||||
|
|
||||||
|
l := l2.Len()
|
||||||
|
// We do not sort in place because the incoming array should not be altered.
|
||||||
|
nl := make([]interface{}, l)
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
nl[l-i-1] = l2.Index(i).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nl, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Cannot find reverse on type %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func compact(list interface{}) []interface{} {
|
||||||
|
l, err := mustCompact(list)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustCompact(list interface{}) ([]interface{}, error) {
|
||||||
|
tp := reflect.TypeOf(list).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(list)
|
||||||
|
|
||||||
|
l := l2.Len()
|
||||||
|
nl := []interface{}{}
|
||||||
|
var item interface{}
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
item = l2.Index(i).Interface()
|
||||||
|
if !empty(item) {
|
||||||
|
nl = append(nl, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nl, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Cannot compact on type %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func uniq(list interface{}) []interface{} {
|
||||||
|
l, err := mustUniq(list)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustUniq(list interface{}) ([]interface{}, error) {
|
||||||
|
tp := reflect.TypeOf(list).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(list)
|
||||||
|
|
||||||
|
l := l2.Len()
|
||||||
|
dest := []interface{}{}
|
||||||
|
var item interface{}
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
item = l2.Index(i).Interface()
|
||||||
|
if !inList(dest, item) {
|
||||||
|
dest = append(dest, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Cannot find uniq on type %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func inList(haystack []interface{}, needle interface{}) bool {
|
||||||
|
for _, h := range haystack {
|
||||||
|
if reflect.DeepEqual(needle, h) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func without(list interface{}, omit ...interface{}) []interface{} {
|
||||||
|
l, err := mustWithout(list, omit...)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustWithout(list interface{}, omit ...interface{}) ([]interface{}, error) {
|
||||||
|
tp := reflect.TypeOf(list).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(list)
|
||||||
|
|
||||||
|
l := l2.Len()
|
||||||
|
res := []interface{}{}
|
||||||
|
var item interface{}
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
item = l2.Index(i).Interface()
|
||||||
|
if !inList(omit, item) {
|
||||||
|
res = append(res, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Cannot find without on type %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func has(needle interface{}, haystack interface{}) bool {
|
||||||
|
l, err := mustHas(needle, haystack)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustHas(needle interface{}, haystack interface{}) (bool, error) {
|
||||||
|
if haystack == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
tp := reflect.TypeOf(haystack).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(haystack)
|
||||||
|
var item interface{}
|
||||||
|
l := l2.Len()
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
item = l2.Index(i).Interface()
|
||||||
|
if reflect.DeepEqual(needle, item) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
default:
|
||||||
|
return false, fmt.Errorf("Cannot find has on type %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// $list := [1, 2, 3, 4, 5]
|
||||||
|
// slice $list -> list[0:5] = list[:]
|
||||||
|
// slice $list 0 3 -> list[0:3] = list[:3]
|
||||||
|
// slice $list 3 5 -> list[3:5]
|
||||||
|
// slice $list 3 -> list[3:5] = list[3:]
|
||||||
|
func slice(list interface{}, indices ...interface{}) interface{} {
|
||||||
|
l, err := mustSlice(list, indices...)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustSlice(list interface{}, indices ...interface{}) (interface{}, error) {
|
||||||
|
tp := reflect.TypeOf(list).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(list)
|
||||||
|
|
||||||
|
l := l2.Len()
|
||||||
|
if l == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var start, end int
|
||||||
|
if len(indices) > 0 {
|
||||||
|
start = toInt(indices[0])
|
||||||
|
}
|
||||||
|
if len(indices) < 2 {
|
||||||
|
end = l
|
||||||
|
} else {
|
||||||
|
end = toInt(indices[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
return l2.Slice(start, end).Interface(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("list should be type of slice or array but %s", tp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func concat(lists ...interface{}) interface{} {
|
||||||
|
var res []interface{}
|
||||||
|
for _, list := range lists {
|
||||||
|
tp := reflect.TypeOf(list).Kind()
|
||||||
|
switch tp {
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
l2 := reflect.ValueOf(list)
|
||||||
|
for i := 0; i < l2.Len(); i++ {
|
||||||
|
res = append(res, l2.Index(i).Interface())
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("Cannot concat type %s as list", tp))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
12
vendor/github.com/go-task/slim-sprig/network.go
generated
vendored
Normal file
12
vendor/github.com/go-task/slim-sprig/network.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package sprig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getHostByName(name string) string {
|
||||||
|
addrs, _ := net.LookupHost(name)
|
||||||
|
//TODO: add error handing when release v3 comes out
|
||||||
|
return addrs[rand.Intn(len(addrs))]
|
||||||
|
}
|
||||||
228
vendor/github.com/go-task/slim-sprig/numeric.go
generated
vendored
Normal file
228
vendor/github.com/go-task/slim-sprig/numeric.go
generated
vendored
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
package sprig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// toFloat64 converts 64-bit floats
|
||||||
|
func toFloat64(v interface{}) float64 {
|
||||||
|
if str, ok := v.(string); ok {
|
||||||
|
iv, err := strconv.ParseFloat(str, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return iv
|
||||||
|
}
|
||||||
|
|
||||||
|
val := reflect.Indirect(reflect.ValueOf(v))
|
||||||
|
switch val.Kind() {
|
||||||
|
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||||
|
return float64(val.Int())
|
||||||
|
case reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
||||||
|
return float64(val.Uint())
|
||||||
|
case reflect.Uint, reflect.Uint64:
|
||||||
|
return float64(val.Uint())
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return val.Float()
|
||||||
|
case reflect.Bool:
|
||||||
|
if val.Bool() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toInt(v interface{}) int {
|
||||||
|
//It's not optimal. Bud I don't want duplicate toInt64 code.
|
||||||
|
return int(toInt64(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// toInt64 converts integer types to 64-bit integers
|
||||||
|
func toInt64(v interface{}) int64 {
|
||||||
|
if str, ok := v.(string); ok {
|
||||||
|
iv, err := strconv.ParseInt(str, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return iv
|
||||||
|
}
|
||||||
|
|
||||||
|
val := reflect.Indirect(reflect.ValueOf(v))
|
||||||
|
switch val.Kind() {
|
||||||
|
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||||
|
return val.Int()
|
||||||
|
case reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
||||||
|
return int64(val.Uint())
|
||||||
|
case reflect.Uint, reflect.Uint64:
|
||||||
|
tv := val.Uint()
|
||||||
|
if tv <= math.MaxInt64 {
|
||||||
|
return int64(tv)
|
||||||
|
}
|
||||||
|
// TODO: What is the sensible thing to do here?
|
||||||
|
return math.MaxInt64
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return int64(val.Float())
|
||||||
|
case reflect.Bool:
|
||||||
|
if val.Bool() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func max(a interface{}, i ...interface{}) int64 {
|
||||||
|
aa := toInt64(a)
|
||||||
|
for _, b := range i {
|
||||||
|
bb := toInt64(b)
|
||||||
|
if bb > aa {
|
||||||
|
aa = bb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return aa
|
||||||
|
}
|
||||||
|
|
||||||
|
func maxf(a interface{}, i ...interface{}) float64 {
|
||||||
|
aa := toFloat64(a)
|
||||||
|
for _, b := range i {
|
||||||
|
bb := toFloat64(b)
|
||||||
|
aa = math.Max(aa, bb)
|
||||||
|
}
|
||||||
|
return aa
|
||||||
|
}
|
||||||
|
|
||||||
|
func min(a interface{}, i ...interface{}) int64 {
|
||||||
|
aa := toInt64(a)
|
||||||
|
for _, b := range i {
|
||||||
|
bb := toInt64(b)
|
||||||
|
if bb < aa {
|
||||||
|
aa = bb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return aa
|
||||||
|
}
|
||||||
|
|
||||||
|
func minf(a interface{}, i ...interface{}) float64 {
|
||||||
|
aa := toFloat64(a)
|
||||||
|
for _, b := range i {
|
||||||
|
bb := toFloat64(b)
|
||||||
|
aa = math.Min(aa, bb)
|
||||||
|
}
|
||||||
|
return aa
|
||||||
|
}
|
||||||
|
|
||||||
|
func until(count int) []int {
|
||||||
|
step := 1
|
||||||
|
if count < 0 {
|
||||||
|
step = -1
|
||||||
|
}
|
||||||
|
return untilStep(0, count, step)
|
||||||
|
}
|
||||||
|
|
||||||
|
func untilStep(start, stop, step int) []int {
|
||||||
|
v := []int{}
|
||||||
|
|
||||||
|
if stop < start {
|
||||||
|
if step >= 0 {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
for i := start; i > stop; i += step {
|
||||||
|
v = append(v, i)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
if step <= 0 {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
for i := start; i < stop; i += step {
|
||||||
|
v = append(v, i)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func floor(a interface{}) float64 {
|
||||||
|
aa := toFloat64(a)
|
||||||
|
return math.Floor(aa)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ceil(a interface{}) float64 {
|
||||||
|
aa := toFloat64(a)
|
||||||
|
return math.Ceil(aa)
|
||||||
|
}
|
||||||
|
|
||||||
|
func round(a interface{}, p int, rOpt ...float64) float64 {
|
||||||
|
roundOn := .5
|
||||||
|
if len(rOpt) > 0 {
|
||||||
|
roundOn = rOpt[0]
|
||||||
|
}
|
||||||
|
val := toFloat64(a)
|
||||||
|
places := toFloat64(p)
|
||||||
|
|
||||||
|
var round float64
|
||||||
|
pow := math.Pow(10, places)
|
||||||
|
digit := pow * val
|
||||||
|
_, div := math.Modf(digit)
|
||||||
|
if div >= roundOn {
|
||||||
|
round = math.Ceil(digit)
|
||||||
|
} else {
|
||||||
|
round = math.Floor(digit)
|
||||||
|
}
|
||||||
|
return round / pow
|
||||||
|
}
|
||||||
|
|
||||||
|
// converts unix octal to decimal
|
||||||
|
func toDecimal(v interface{}) int64 {
|
||||||
|
result, err := strconv.ParseInt(fmt.Sprint(v), 8, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func seq(params ...int) string {
|
||||||
|
increment := 1
|
||||||
|
switch len(params) {
|
||||||
|
case 0:
|
||||||
|
return ""
|
||||||
|
case 1:
|
||||||
|
start := 1
|
||||||
|
end := params[0]
|
||||||
|
if end < start {
|
||||||
|
increment = -1
|
||||||
|
}
|
||||||
|
return intArrayToString(untilStep(start, end+increment, increment), " ")
|
||||||
|
case 3:
|
||||||
|
start := params[0]
|
||||||
|
end := params[2]
|
||||||
|
step := params[1]
|
||||||
|
if end < start {
|
||||||
|
increment = -1
|
||||||
|
if step > 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return intArrayToString(untilStep(start, end+increment, step), " ")
|
||||||
|
case 2:
|
||||||
|
start := params[0]
|
||||||
|
end := params[1]
|
||||||
|
step := 1
|
||||||
|
if end < start {
|
||||||
|
step = -1
|
||||||
|
}
|
||||||
|
return intArrayToString(untilStep(start, end+step, step), " ")
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func intArrayToString(slice []int, delimeter string) string {
|
||||||
|
return strings.Trim(strings.Join(strings.Fields(fmt.Sprint(slice)), delimeter), "[]")
|
||||||
|
}
|
||||||
28
vendor/github.com/go-task/slim-sprig/reflect.go
generated
vendored
Normal file
28
vendor/github.com/go-task/slim-sprig/reflect.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package sprig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// typeIs returns true if the src is the type named in target.
|
||||||
|
func typeIs(target string, src interface{}) bool {
|
||||||
|
return target == typeOf(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
func typeIsLike(target string, src interface{}) bool {
|
||||||
|
t := typeOf(src)
|
||||||
|
return target == t || "*"+target == t
|
||||||
|
}
|
||||||
|
|
||||||
|
func typeOf(src interface{}) string {
|
||||||
|
return fmt.Sprintf("%T", src)
|
||||||
|
}
|
||||||
|
|
||||||
|
func kindIs(target string, src interface{}) bool {
|
||||||
|
return target == kindOf(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
func kindOf(src interface{}) string {
|
||||||
|
return reflect.ValueOf(src).Kind().String()
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user