mirror of
https://github.com/1Password/onepassword-operator.git
synced 2025-10-24 00:10:46 +00:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c9801322b | ||
|
|
26ff2408ba | ||
|
|
2dbfc7ecdd | ||
|
|
aaddfd0c79 | ||
|
|
e72705e9fa | ||
|
|
c2d5c835c1 | ||
|
|
e4b945ed56 | ||
|
|
50862a8321 | ||
|
|
c7548af5c3 | ||
|
|
d00fc40e90 | ||
|
|
802e7c5b56 | ||
|
|
63dcaac407 | ||
|
|
fe930fef05 | ||
|
|
702974f750 | ||
|
|
ea8773bfee | ||
|
|
a84b5337ea | ||
|
|
cd1c978d18 | ||
|
|
34b8f9ee3d |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -7,9 +7,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v3
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: ^1.19
|
||||
go-version: ^1.20
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
|
||||
16
.github/workflows/release-pr.yml
vendored
16
.github/workflows/release-pr.yml
vendored
@@ -47,15 +47,16 @@ jobs:
|
||||
|
||||
- name: Parse release 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
|
||||
id: prep_pr
|
||||
run: |
|
||||
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}")
|
||||
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.
|
||||
|
||||
Please check the following before approving:
|
||||
@@ -64,14 +65,9 @@ jobs:
|
||||
---
|
||||
## Release Changelog Preview
|
||||
${LOG_ENTRY}
|
||||
EOF
|
||||
)
|
||||
"
|
||||
|
||||
# Sanitizes multiline strings for action outputs (https://medium.com/agorapulse-stories/23f56447d209)
|
||||
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")"
|
||||
echo "pr_body<<${DELIMITER}${PR_BODY_CONTENT}${DELIMITER}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Create Pull Request via API
|
||||
id: post_pr
|
||||
|
||||
12
CHANGELOG.md
12
CHANGELOG.md
@@ -12,6 +12,18 @@
|
||||
|
||||
---
|
||||
|
||||
[//]: # (START/v1.7.0)
|
||||
# v1.7.0
|
||||
|
||||
## Features
|
||||
* Upgraded operator to version 1.29.0. {#162}
|
||||
* Upgraded Golang version to 1.20. {#161}
|
||||
* Upgraded 1Password Connect version to 1.5.1. {#161}
|
||||
* Added runAsNonRoot and allowPrivalegeEscalation to specs. {#151}
|
||||
* Added code quality improvements. {#146}
|
||||
|
||||
---
|
||||
|
||||
[//]: # (START/v1.6.0)
|
||||
# v1.6.0
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Build the manager binary
|
||||
FROM golang:1.19 as builder
|
||||
FROM golang:1.20 as builder
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
|
||||
|
||||
6
Makefile
6
Makefile
@@ -5,7 +5,7 @@ export MAIN_BRANCH ?= main
|
||||
# To re-generate a bundle for another specific version without changing the standard setup, you can:
|
||||
# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2)
|
||||
# - use environment variables to overwrite this value (e.g export VERSION=0.0.2)
|
||||
VERSION ?= 1.5.0
|
||||
VERSION ?= 1.6.0
|
||||
|
||||
# CHANNELS define the bundle channels used in the bundle.
|
||||
# Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable")
|
||||
@@ -51,7 +51,7 @@ endif
|
||||
# Image URL to use all building/pushing image targets
|
||||
IMG ?= 1password/onepassword-operator:latest
|
||||
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
|
||||
ENVTEST_K8S_VERSION = 1.24.2
|
||||
ENVTEST_K8S_VERSION = 1.26
|
||||
|
||||
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
|
||||
ifeq (,$(shell go env GOBIN))
|
||||
@@ -110,7 +110,7 @@ test: manifests generate fmt vet envtest ## Run tests.
|
||||
##@ Build
|
||||
|
||||
.PHONY: build
|
||||
build: generate fmt vet ## Build manager binary.
|
||||
build: manifests generate fmt vet ## Build manager binary.
|
||||
go build -o bin/manager main.go
|
||||
|
||||
.PHONY: run
|
||||
|
||||
31
README.md
31
README.md
@@ -38,9 +38,9 @@ The 1Password Connect Helm Chart helps to simplify the deployment of 1Password C
|
||||
|
||||
#### Deploy using the Connect Operator
|
||||
|
||||
This guide will provide a quickstart option for deploying a default configuration of 1Password Connect via starting the deploying the 1Password Connect Operator, however it is recommended that you instead deploy your own manifest file if customization of the 1Password Connect deployment is desired.
|
||||
This guide will provide a quickstart option for deploying a default configuration of 1Password Connect via starting the deploying the 1Password Connect Operator, however, it is recommended that you instead deploy your own manifest file if customization of the 1Password Connect deployment is desired.
|
||||
|
||||
Encode the 1password-credentials.json file you generated in the prerequisite steps and save it to a file named op-session:
|
||||
Encode the `1password-credentials.json` file you generated in the prerequisite steps and save it to a file named `op-session`:
|
||||
|
||||
```bash
|
||||
cat 1password-credentials.json | base64 | \
|
||||
@@ -66,13 +66,13 @@ Adding this environment variable will have the operator automatically deploy a d
|
||||
|
||||
**Create Kubernetes Secret for OP_CONNECT_TOKEN**
|
||||
|
||||
"Create a Connect token for the operator and save it as a Kubernetes Secret:
|
||||
Create a Connect token for the operator and save it as a Kubernetes Secret:
|
||||
|
||||
```bash
|
||||
kubectl create secret generic onepassword-token --from-literal=token=<OP_CONNECT_TOKEN>"
|
||||
```
|
||||
|
||||
If you do not have a token for the operator, you can generate a token and save it to kubernetes with the following command:
|
||||
If you do not have a token for the operator, you can generate a token and save it to Kubernetes with the following command:
|
||||
|
||||
```bash
|
||||
kubectl create secret generic onepassword-token --from-literal=token=$(op create connect token <server> op-k8s-operator --vault <vault>)
|
||||
@@ -82,12 +82,12 @@ kubectl create secret generic onepassword-token --from-literal=token=$(op create
|
||||
|
||||
An sample Deployment yaml can be found at `/config/manager/manager.yaml`.
|
||||
|
||||
To further configure the 1Password Kubernetes Operator the Following Environment variables can be set in the operator yaml:
|
||||
To further configure the 1Password Kubernetes Operator the following Environment variables can be set in the operator yaml:
|
||||
|
||||
- **OP_CONNECT_HOST** (required): Specifies the host name within Kubernetes in which to access the 1Password Connect.
|
||||
- **WATCH_NAMESPACE:** (default: watch all namespaces): Comma separated list of what Namespaces to watch for changes.
|
||||
- **POLLING_INTERVAL** (default: 600): The number of seconds the 1Password Kubernetes Operator will wait before checking for updates from 1Password Connect.
|
||||
- **MANAGE_CONNECT** (default: false): If set to true, on deployment of the operator, a default configuration of the OnePassword Connect Service will be deployed to the current namespace.
|
||||
- **OP_CONNECT_HOST** *(required)*: Specifies the host name within Kubernetes in which to access the 1Password Connect.
|
||||
- **WATCH_NAMESPACE:** *(default: watch all namespaces)*: Comma separated list of what Namespaces to watch for changes.
|
||||
- **POLLING_INTERVAL** *(default: 600)*: The number of seconds the 1Password Kubernetes Operator will wait before checking for updates from 1Password Connect.
|
||||
- **MANAGE_CONNECT** *(default: false)*: If set to true, on deployment of the operator, a default configuration of the OnePassword Connect Service will be deployed to the current namespace.
|
||||
- **AUTO_RESTART** (default: false): If set to true, the operator will restart any deployment using a secret from 1Password Connect. This can be overwritten by namespace, deployment, or individual secret. More details on AUTO_RESTART can be found in the ["Configuring Automatic Rolling Restarts of Deployments"](#configuring-automatic-rolling-restarts-of-deployments) section.
|
||||
|
||||
To deploy the operator, simply run the following command:
|
||||
@@ -127,7 +127,7 @@ To test that the Kubernetes Secret check that the following command returns a se
|
||||
kubectl get secret <secret_name>
|
||||
```
|
||||
|
||||
Note: Deleting the `OnePasswordItem` that you've created will automatically delete the created Kubernetes Secret.
|
||||
**Note:** Deleting the `OnePasswordItem` that you've created will automatically delete the created Kubernetes Secret.
|
||||
|
||||
To create a single Kubernetes Secret for a deployment, add the following annotations to the deployment metadata:
|
||||
|
||||
@@ -148,7 +148,7 @@ In case of fields that store files, the file's contents will be used as the valu
|
||||
|
||||
Within an item, if both a field storing a file and a field of another type have the same name, the file field will be ignored and the other field will take precedence.
|
||||
|
||||
Note: Deleting the Deployment that you've created will automatically delete the created Kubernetes Secret only if the deployment is still annotated with `operator.1password.io/item-path` and `operator.1password.io/item-name` and no other deployment is using the secret.
|
||||
**Note:** Deleting the Deployment that you've created will automatically delete the created Kubernetes Secret only if the deployment is still annotated with `operator.1password.io/item-path` and `operator.1password.io/item-name` and no other deployment is using the secret.
|
||||
|
||||
If a 1Password Item that is linked to a Kubernetes Secret is updated within the POLLING_INTERVAL the associated Kubernetes Secret will be updated. However, if you do not want a specific secret to be updated you can add the tag `operator.1password.io:ignore-secret` to the item stored in 1Password. While this tag is in place, any updates made to an item will not trigger an update to the associated secret in Kubernetes.
|
||||
|
||||
@@ -170,9 +170,12 @@ Titles and field names that include white space and other characters that are no
|
||||
|
||||
If a 1Password Item that is linked to a Kubernetes Secret is updated, any deployments configured to `auto-restart` AND are using that secret will be given a rolling restart the next time 1Password Connect is polled for updates.
|
||||
|
||||
There are many levels of granularity on which to configure auto restarts on deployments: at the operator level, per-namespace, or per-deployment.
|
||||
There are many levels of granularity on which to configure auto restarts on deployments:
|
||||
- Operator level
|
||||
- Per-namespace
|
||||
- Per-deployment
|
||||
|
||||
**On the operator**: This method allows for managing auto restarts on all deployments within the namespaces watched by operator. Auto restarts can be enabled by setting the environemnt variable `AUTO_RESTART` to true. If the value is not set, the operator will default this value to false.
|
||||
**Operator Level**: This method allows for managing auto restarts on all deployments within the namespaces watched by operator. Auto restarts can be enabled by setting the environment variable `AUTO_RESTART` to true. If the value is not set, the operator will default this value to false.
|
||||
|
||||
**Per Namespace**: This method allows for managing auto restarts on all deployments within a namespace. Auto restarts can by managed by setting the annotation `operator.1password.io/auto-restart` to either `true` or `false` on the desired namespace. An example of this is shown below:
|
||||
|
||||
@@ -258,7 +261,7 @@ make undeploy
|
||||
This project aims to follow the Kubernetes [Operator pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/)
|
||||
|
||||
It uses [Controllers](https://kubernetes.io/docs/concepts/architecture/controller/)
|
||||
which provides a reconcile function responsible for synchronizing resources untile the desired state is reached on the cluster
|
||||
which provides a reconcile function responsible for synchronizing resources until the desired state is reached on the cluster
|
||||
|
||||
### Test It Out
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ spec:
|
||||
app: onepassword-connect
|
||||
version: "1.0.0"
|
||||
spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
volumes:
|
||||
- name: shared-data
|
||||
emptyDir: {}
|
||||
@@ -32,6 +34,8 @@ spec:
|
||||
containers:
|
||||
- name: connect-api
|
||||
image: 1password/connect-api:latest
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
resources:
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
@@ -49,6 +53,8 @@ spec:
|
||||
name: shared-data
|
||||
- name: connect-sync
|
||||
image: 1password/connect-sync:latest
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
resources:
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
|
||||
@@ -8,6 +8,8 @@ metadata:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
containers:
|
||||
- name: kube-rbac-proxy
|
||||
securityContext:
|
||||
@@ -15,7 +17,7 @@ spec:
|
||||
capabilities:
|
||||
drop:
|
||||
- "ALL"
|
||||
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0
|
||||
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.1
|
||||
args:
|
||||
- "--secure-listen-address=0.0.0.0:8443"
|
||||
- "--upstream=http://127.0.0.1:8080/"
|
||||
|
||||
@@ -6,6 +6,8 @@ metadata:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
containers:
|
||||
- name: manager
|
||||
args:
|
||||
|
||||
@@ -95,12 +95,12 @@ func (r *DeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request)
|
||||
// This is so we can handle cleanup of associated secrets properly
|
||||
if !utils.ContainsString(deployment.ObjectMeta.Finalizers, finalizer) {
|
||||
deployment.ObjectMeta.Finalizers = append(deployment.ObjectMeta.Finalizers, finalizer)
|
||||
if err := r.Update(context.Background(), deployment); err != nil {
|
||||
if err = r.Update(context.Background(), deployment); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
}
|
||||
// Handles creation or updating secrets for deployment if needed
|
||||
if err := r.handleApplyingDeployment(deployment, deployment.Namespace, annotations, req); err != nil {
|
||||
if err = r.handleApplyingDeployment(deployment, deployment.Namespace, annotations, req); err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
@@ -110,10 +110,12 @@ func (r *DeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request)
|
||||
if utils.ContainsString(deployment.ObjectMeta.Finalizers, finalizer) {
|
||||
|
||||
secretName := annotations[op.NameAnnotation]
|
||||
r.cleanupKubernetesSecretForDeployment(secretName, deployment)
|
||||
if err = r.cleanupKubernetesSecretForDeployment(secretName, deployment); err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
// Remove the finalizer from the deployment so deletion of deployment can be completed
|
||||
if err := r.removeOnePasswordFinalizerFromDeployment(deployment); err != nil {
|
||||
if err = r.removeOnePasswordFinalizerFromDeployment(deployment); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
}
|
||||
@@ -144,7 +146,7 @@ func (r *DeploymentReconciler) cleanupKubernetesSecretForDeployment(secretName s
|
||||
|
||||
// Only delete the associated kubernetes secret if it is not being used by other deployments
|
||||
if !multipleDeploymentsUsingSecret {
|
||||
if err := r.Delete(context.Background(), kubernetesSecret); err != nil {
|
||||
if err = r.Delete(context.Background(), kubernetesSecret); err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -95,13 +95,13 @@ func (r *OnePasswordItemReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
||||
// This is so we can handle cleanup of associated secrets properly
|
||||
if !utils.ContainsString(onepassworditem.ObjectMeta.Finalizers, finalizer) {
|
||||
onepassworditem.ObjectMeta.Finalizers = append(onepassworditem.ObjectMeta.Finalizers, finalizer)
|
||||
if err := r.Update(context.Background(), onepassworditem); err != nil {
|
||||
if err = r.Update(context.Background(), onepassworditem); err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
}
|
||||
|
||||
// Handles creation or updating secrets for deployment if needed
|
||||
err := r.handleOnePasswordItem(onepassworditem, req)
|
||||
err = r.handleOnePasswordItem(onepassworditem, req)
|
||||
if updateStatusErr := r.updateStatus(onepassworditem, err); updateStatusErr != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("cannot update status: %s", updateStatusErr)
|
||||
}
|
||||
@@ -116,7 +116,7 @@ func (r *OnePasswordItemReconciler) Reconcile(ctx context.Context, req ctrl.Requ
|
||||
}
|
||||
|
||||
// Remove finalizer now that cleanup is complete
|
||||
if err := r.removeFinalizer(onepassworditem); err != nil {
|
||||
if err = r.removeFinalizer(onepassworditem); err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
}
|
||||
@@ -143,7 +143,6 @@ func (r *OnePasswordItemReconciler) cleanupKubernetesSecret(onePasswordItem *one
|
||||
kubernetesSecret.ObjectMeta.Name = onePasswordItem.Name
|
||||
kubernetesSecret.ObjectMeta.Namespace = onePasswordItem.Namespace
|
||||
|
||||
r.Delete(context.Background(), kubernetesSecret)
|
||||
if err := r.Delete(context.Background(), kubernetesSecret); err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
return err
|
||||
|
||||
82
go.mod
82
go.mod
@@ -1,87 +1,81 @@
|
||||
module github.com/1Password/onepassword-operator
|
||||
|
||||
go 1.18
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/1Password/connect-sdk-go v1.5.0
|
||||
github.com/onsi/ginkgo/v2 v2.1.6
|
||||
github.com/onsi/gomega v1.20.2
|
||||
github.com/stretchr/testify v1.8.0
|
||||
k8s.io/api v0.25.3
|
||||
k8s.io/apimachinery v0.25.3
|
||||
k8s.io/client-go v0.25.3
|
||||
k8s.io/kubectl v0.25.0
|
||||
sigs.k8s.io/controller-runtime v0.13.0
|
||||
github.com/1Password/connect-sdk-go v1.5.1
|
||||
github.com/onsi/ginkgo/v2 v2.9.2
|
||||
github.com/onsi/gomega v1.27.5
|
||||
github.com/stretchr/testify v1.8.2
|
||||
k8s.io/api v0.26.3
|
||||
k8s.io/apimachinery v0.26.3
|
||||
k8s.io/client-go v0.26.3
|
||||
k8s.io/kubectl v0.26.3
|
||||
sigs.k8s.io/controller-runtime v0.14.5
|
||||
)
|
||||
|
||||
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/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/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 v5.6.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-logr/logr 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/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // 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/golang-jwt/jwt/v4 v4.4.2 // 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/go-cmp v0.5.9 // 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/imdario/mergo v0.3.13 // indirect
|
||||
github.com/imdario/mergo v0.3.15 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // 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/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // 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/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
go.uber.org/zap v1.23.0 // indirect
|
||||
golang.org/x/crypto v0.1.0 // indirect
|
||||
golang.org/x/net v0.1.0 // indirect
|
||||
golang.org/x/oauth2 v0.1.0 // indirect
|
||||
golang.org/x/sys v0.1.0 // indirect
|
||||
golang.org/x/term v0.1.0 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
golang.org/x/time v0.1.0 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/oauth2 v0.6.0 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/term v0.6.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.7.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0 // 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/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.25.3 // indirect
|
||||
k8s.io/component-base v0.25.3 // indirect
|
||||
k8s.io/klog/v2 v2.80.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
|
||||
k8s.io/utils v0.0.0-20221012122500-cfd413dd9e85 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.26.3 // indirect
|
||||
k8s.io/component-base v0.26.3 // indirect
|
||||
k8s.io/klog/v2 v2.90.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a // indirect
|
||||
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 // 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/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
||||
535
go.sum
535
go.sum
@@ -1,83 +1,20 @@
|
||||
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.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=
|
||||
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/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/1Password/connect-sdk-go v1.5.1 h1:wb9niRg4BOa+lZJjj1TOX6093VJxuOYtzqUnRpwKnvs=
|
||||
github.com/1Password/connect-sdk-go v1.5.1/go.mod h1:lKGz6DFO6qMchEQ+lDx6f9MzORTxC1HkhUdHnJ24fKs=
|
||||
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/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/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/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/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
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/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
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/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
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/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
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-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
@@ -87,8 +24,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/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/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE=
|
||||
github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE=
|
||||
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.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
@@ -101,62 +38,33 @@ github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
|
||||
github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
|
||||
github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
|
||||
github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
|
||||
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
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/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.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/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A=
|
||||
github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
|
||||
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/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
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-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
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/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/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/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
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.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.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.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=
|
||||
@@ -167,153 +75,95 @@ 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.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
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/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
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/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E=
|
||||
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.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.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.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.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/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
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/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/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/pprof v0.0.0-20230323073829-e72429f035bd h1:r8yyd+DJDmsUhGrRBxH5Pj7KeFK5l+Y3FsgT8keqKtk=
|
||||
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
|
||||
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/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/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
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/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
|
||||
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
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/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/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/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/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.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
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/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/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/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.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/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-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
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/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/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/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo/v2 v2.1.6 h1:Fx2POJZfKRQcM1pH49qSZiYeu319wji004qX+GDovrU=
|
||||
github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
|
||||
github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY=
|
||||
github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
|
||||
github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU=
|
||||
github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
|
||||
github.com/onsi/gomega v1.27.5 h1:T/X6I0RNFw/kTqgfkZPcQ5KU6vCnWNBGdtrIx2dpGeQ=
|
||||
github.com/onsi/gomega v1.27.5/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
|
||||
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/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.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
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/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.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.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_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
|
||||
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
||||
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/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
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/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
|
||||
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
|
||||
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
||||
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
||||
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/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
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/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/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.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.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.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.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/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
|
||||
@@ -321,314 +171,109 @@ 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/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/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.32/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.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.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
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.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||
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.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
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.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
|
||||
go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
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-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-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-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-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-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-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-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/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-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-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-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/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.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.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-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-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-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-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-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-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-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-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-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
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/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
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-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
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/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
|
||||
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
|
||||
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-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-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-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-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-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-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-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-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-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-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.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
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-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
|
||||
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/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
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.3/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.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/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/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
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-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-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-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-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-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-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.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-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-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY=
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
|
||||
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
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/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.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/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-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-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-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-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/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.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.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.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
@@ -640,71 +285,53 @@ 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.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.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
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/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.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
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-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-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/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.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.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/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-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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
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.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.25.3 h1:Q1v5UFfYe87vi5H7NU0p4RXC26PPMT8KOpr1TLQbCMQ=
|
||||
k8s.io/api v0.25.3/go.mod h1:o42gKscFrEVjHdQnyRenACrMtbuJsVdP+WVjqejfzmI=
|
||||
k8s.io/apiextensions-apiserver v0.25.3 h1:bfI4KS31w2f9WM1KLGwnwuVlW3RSRPuIsfNF/3HzR0k=
|
||||
k8s.io/apiextensions-apiserver v0.25.3/go.mod h1:ZJqwpCkxIx9itilmZek7JgfUAM0dnTsA48I4krPqRmo=
|
||||
k8s.io/apimachinery v0.25.3 h1:7o9ium4uyUOM76t6aunP0nZuex7gDf8VGwkR5RcJnQc=
|
||||
k8s.io/apimachinery v0.25.3/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo=
|
||||
k8s.io/client-go v0.25.3 h1:oB4Dyl8d6UbfDHD8Bv8evKylzs3BXzzufLiO27xuPs0=
|
||||
k8s.io/client-go v0.25.3/go.mod h1:t39LPczAIMwycjcXkVc+CB+PZV69jQuNx4um5ORDjQA=
|
||||
k8s.io/component-base v0.25.3 h1:UrsxciGdrCY03ULT1h/S/gXFCOPnLhUVwSyx+hM/zq4=
|
||||
k8s.io/component-base v0.25.3/go.mod h1:WYoS8L+IlTZgU7rhAl5Ctpw0WdMxDfCC5dkxcEFa/TI=
|
||||
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
|
||||
k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4=
|
||||
k8s.io/kubectl v0.25.0 h1:/Wn1cFqo8ik3iee1EvpxYre3bkWsGLXzLQI6uCCAkQc=
|
||||
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/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/controller-runtime v0.13.0 h1:iqa5RNciy7ADWnIc8QxCbOX5FEKVR3uxVxKHRMc2WIQ=
|
||||
sigs.k8s.io/controller-runtime v0.13.0/go.mod h1:Zbz+el8Yg31jubvAEyglRZGdLAjplZl+PgtYNI6WNTI=
|
||||
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=
|
||||
k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU=
|
||||
k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE=
|
||||
k8s.io/apiextensions-apiserver v0.26.3 h1:5PGMm3oEzdB1W/FTMgGIDmm100vn7IaUP5er36dB+YE=
|
||||
k8s.io/apiextensions-apiserver v0.26.3/go.mod h1:jdA5MdjNWGP+njw1EKMZc64xAT5fIhN6VJrElV3sfpQ=
|
||||
k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k=
|
||||
k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=
|
||||
k8s.io/client-go v0.26.3 h1:k1UY+KXfkxV2ScEL3gilKcF7761xkYsSD6BC9szIu8s=
|
||||
k8s.io/client-go v0.26.3/go.mod h1:ZPNu9lm8/dbRIPAgteN30RSXea6vrCpFvq+MateTUuQ=
|
||||
k8s.io/component-base v0.26.3 h1:oC0WMK/ggcbGDTkdcqefI4wIZRYdK3JySx9/HADpV0g=
|
||||
k8s.io/component-base v0.26.3/go.mod h1:5kj1kZYwSC6ZstHJN7oHBqcJC6yyn41eR+Sqa/mQc8E=
|
||||
k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
|
||||
k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a h1:gmovKNur38vgoWfGtP5QOGNOA7ki4n6qNYoFAgMlNvg=
|
||||
k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY=
|
||||
k8s.io/kubectl v0.26.3 h1:bZ5SgFyeEXw6XTc1Qji0iNdtqAC76lmeIIQULg2wNXM=
|
||||
k8s.io/kubectl v0.26.3/go.mod h1:02+gv7Qn4dupzN3fi/9OvqqdW+uG/4Zi56vc4Zmsp1g=
|
||||
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 h1:xMMXJlJbsU8w3V5N2FLDQ8YgU8s1EoULdbQBcAeNJkY=
|
||||
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/controller-runtime v0.14.5 h1:6xaWFqzT5KuAQ9ufgUaj1G/+C4Y1GRkhrxl+BJ9i+5s=
|
||||
sigs.k8s.io/controller-runtime v0.14.5/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/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/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
|
||||
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
|
||||
}
|
||||
9
vendor/github.com/1Password/connect-sdk-go/connect/client.go
generated
vendored
9
vendor/github.com/1Password/connect-sdk-go/connect/client.go
generated
vendored
@@ -845,11 +845,16 @@ func readResponseBody(resp *http.Response, expectedStatusCode int) ([]byte, erro
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != expectedStatusCode {
|
||||
var errResp *onepassword.Error
|
||||
var errResp onepassword.Error
|
||||
if json.Valid(body) {
|
||||
if err := json.Unmarshal(body, &errResp); err != nil {
|
||||
return nil, fmt.Errorf("decoding error response: %s", err)
|
||||
}
|
||||
return nil, errResp
|
||||
} else {
|
||||
errResp.StatusCode = resp.StatusCode
|
||||
errResp.Message = http.StatusText(resp.StatusCode)
|
||||
}
|
||||
return nil, &errResp
|
||||
}
|
||||
return body, nil
|
||||
}
|
||||
|
||||
2
vendor/github.com/1Password/connect-sdk-go/connect/version.go
generated
vendored
2
vendor/github.com/1Password/connect-sdk-go/connect/version.go
generated
vendored
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
// SDKVersion is the latest Semantic Version of the library
|
||||
// Do not rename this variable without changing the regex in the Makefile
|
||||
const SDKVersion = "1.5.0"
|
||||
const SDKVersion = "1.5.1"
|
||||
|
||||
const VersionHeaderKey = "1Password-Connect-Version"
|
||||
|
||||
|
||||
30
vendor/github.com/1Password/connect-sdk-go/onepassword/items.go
generated
vendored
30
vendor/github.com/1Password/connect-sdk-go/onepassword/items.go
generated
vendored
@@ -9,6 +9,10 @@ import (
|
||||
// ItemCategory Represents the template of the Item
|
||||
type ItemCategory string
|
||||
|
||||
type ItemFieldPurpose string
|
||||
|
||||
type ItemFieldType string
|
||||
|
||||
const (
|
||||
Login ItemCategory = "LOGIN"
|
||||
Password ItemCategory = "PASSWORD"
|
||||
@@ -32,6 +36,28 @@ const (
|
||||
MedicalRecord ItemCategory = "MEDICAL_RECORD"
|
||||
SSHKey ItemCategory = "SSH_KEY"
|
||||
Custom ItemCategory = "CUSTOM"
|
||||
|
||||
FieldPurposeUsername ItemFieldPurpose = "USERNAME"
|
||||
FieldPurposePassword ItemFieldPurpose = "PASSWORD"
|
||||
FieldPurposeNotes ItemFieldPurpose = "NOTES"
|
||||
|
||||
FieldTypeAddress ItemFieldType = "ADDRESS"
|
||||
FieldTypeConcealed ItemFieldType = "CONCEALED"
|
||||
FieldTypeCreditCardNumber ItemFieldType = "CREDIT_CARD_NUMBER"
|
||||
FieldTypeCreditCardType ItemFieldType = "CREDIT_CARD_TYPE"
|
||||
FieldTypeDate ItemFieldType = "DATE"
|
||||
FieldTypeEmail ItemFieldType = "EMAIL"
|
||||
FieldTypeGender ItemFieldType = "GENDER"
|
||||
FieldTypeMenu ItemFieldType = "MENU"
|
||||
FieldTypeMonthYear ItemFieldType = "MONTH_YEAR"
|
||||
FieldTypeOTP ItemFieldType = "OTP"
|
||||
FieldTypePhone ItemFieldType = "PHONE"
|
||||
FieldTypeReference ItemFieldType = "REFERENCE"
|
||||
FieldTypeString ItemFieldType = "STRING"
|
||||
FieldTypeURL ItemFieldType = "URL"
|
||||
FieldTypeFile ItemFieldType = "FILE"
|
||||
FieldTypeSSHKey ItemFieldType = "SSH_KEY"
|
||||
FieldTypeUnknown ItemFieldType = "UNKNOWN"
|
||||
)
|
||||
|
||||
// UnmarshalJSON Unmarshall Item Category enum strings to Go string enums
|
||||
@@ -105,8 +131,8 @@ type GeneratorRecipe struct {
|
||||
type ItemField struct {
|
||||
ID string `json:"id"`
|
||||
Section *ItemSection `json:"section,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Purpose string `json:"purpose,omitempty"`
|
||||
Type ItemFieldType `json:"type"`
|
||||
Purpose ItemFieldPurpose `json:"purpose,omitempty"`
|
||||
Label string `json:"label,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
Generate bool `json:"generate,omitempty"`
|
||||
|
||||
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://github.com/cespare/xxhash/actions/workflows/test.yml)
|
||||
|
||||
xxhash is a Go implementation of the 64-bit
|
||||
[xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a
|
||||
xxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a
|
||||
high-quality hashing algorithm that is much faster than anything in the Go
|
||||
standard library.
|
||||
|
||||
@@ -25,8 +24,11 @@ func (*Digest) WriteString(string) (int, error)
|
||||
func (*Digest) Sum64() uint64
|
||||
```
|
||||
|
||||
This implementation provides a fast pure-Go implementation and an even faster
|
||||
assembly implementation for amd64.
|
||||
The package is written with optimized pure Go and also contains even faster
|
||||
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
|
||||
|
||||
@@ -46,18 +48,19 @@ Here are some quick benchmarks comparing the pure-Go and assembly
|
||||
implementations of Sum64.
|
||||
|
||||
| input size | purego | asm |
|
||||
| --- | --- | --- |
|
||||
| 5 B | 979.66 MB/s | 1291.17 MB/s |
|
||||
| 100 B | 7475.26 MB/s | 7973.40 MB/s |
|
||||
| 4 KB | 17573.46 MB/s | 17602.65 MB/s |
|
||||
| 10 MB | 17131.46 MB/s | 17142.16 MB/s |
|
||||
| ---------- | --------- | --------- |
|
||||
| 4 B | 1.3 GB/s | 1.2 GB/s |
|
||||
| 16 B | 2.9 GB/s | 3.5 GB/s |
|
||||
| 100 B | 6.9 GB/s | 8.1 GB/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
|
||||
the following commands under Go 1.11.2:
|
||||
These numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C
|
||||
CPU using the following commands under Go 1.19.2:
|
||||
|
||||
```
|
||||
$ go test -tags purego -benchtime 10s -bench '/xxhash,direct,bytes'
|
||||
$ go test -benchtime 10s -bench '/xxhash,direct,bytes'
|
||||
benchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$')
|
||||
benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$')
|
||||
```
|
||||
|
||||
## 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
|
||||
)
|
||||
|
||||
// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where
|
||||
// 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
|
||||
// convenience in the Go code in a few places where we need to intentionally
|
||||
// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the
|
||||
// result overflows a uint64).
|
||||
var (
|
||||
prime1v = prime1
|
||||
prime2v = prime2
|
||||
prime3v = prime3
|
||||
prime4v = prime4
|
||||
prime5v = prime5
|
||||
)
|
||||
// Store the primes in an array as well.
|
||||
//
|
||||
// The consts are used when possible in Go code to avoid MOVs but we need a
|
||||
// contiguous array of the assembly code.
|
||||
var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5}
|
||||
|
||||
// Digest implements hash.Hash64.
|
||||
type Digest struct {
|
||||
@@ -50,10 +42,10 @@ func New() *Digest {
|
||||
|
||||
// Reset clears the Digest's state so that it can be reused.
|
||||
func (d *Digest) Reset() {
|
||||
d.v1 = prime1v + prime2
|
||||
d.v1 = primes[0] + prime2
|
||||
d.v2 = prime2
|
||||
d.v3 = 0
|
||||
d.v4 = -prime1v
|
||||
d.v4 = -primes[0]
|
||||
d.total = 0
|
||||
d.n = 0
|
||||
}
|
||||
@@ -69,21 +61,23 @@ func (d *Digest) Write(b []byte) (n int, err error) {
|
||||
n = len(b)
|
||||
d.total += uint64(n)
|
||||
|
||||
memleft := d.mem[d.n&(len(d.mem)-1):]
|
||||
|
||||
if d.n+n < 32 {
|
||||
// This new data doesn't even fill the current block.
|
||||
copy(d.mem[d.n:], b)
|
||||
copy(memleft, b)
|
||||
d.n += n
|
||||
return
|
||||
}
|
||||
|
||||
if d.n > 0 {
|
||||
// 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.v2 = round(d.v2, u64(d.mem[8:16]))
|
||||
d.v3 = round(d.v3, u64(d.mem[16:24]))
|
||||
d.v4 = round(d.v4, u64(d.mem[24:32]))
|
||||
b = b[32-d.n:]
|
||||
b = b[c:]
|
||||
d.n = 0
|
||||
}
|
||||
|
||||
@@ -133,21 +127,20 @@ func (d *Digest) Sum64() uint64 {
|
||||
|
||||
h += d.total
|
||||
|
||||
i, end := 0, d.n
|
||||
for ; i+8 <= end; i += 8 {
|
||||
k1 := round(0, u64(d.mem[i:i+8]))
|
||||
b := d.mem[:d.n&(len(d.mem)-1)]
|
||||
for ; len(b) >= 8; b = b[8:] {
|
||||
k1 := round(0, u64(b[:8]))
|
||||
h ^= k1
|
||||
h = rol27(h)*prime1 + prime4
|
||||
}
|
||||
if i+4 <= end {
|
||||
h ^= uint64(u32(d.mem[i:i+4])) * prime1
|
||||
if len(b) >= 4 {
|
||||
h ^= uint64(u32(b[:4])) * prime1
|
||||
h = rol23(h)*prime2 + prime3
|
||||
i += 4
|
||||
b = b[4:]
|
||||
}
|
||||
for i < end {
|
||||
h ^= uint64(d.mem[i]) * prime5
|
||||
for ; len(b) > 0; b = b[1:] {
|
||||
h ^= uint64(b[0]) * prime5
|
||||
h = rol11(h) * prime1
|
||||
i++
|
||||
}
|
||||
|
||||
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 gc
|
||||
// +build !purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Register allocation:
|
||||
// AX h
|
||||
// SI pointer to advance through b
|
||||
// DX n
|
||||
// BX loop end
|
||||
// R8 v1, k1
|
||||
// R9 v2
|
||||
// R10 v3
|
||||
// R11 v4
|
||||
// R12 tmp
|
||||
// R13 prime1v
|
||||
// R14 prime2v
|
||||
// DI prime4v
|
||||
// Registers:
|
||||
#define h AX
|
||||
#define d AX
|
||||
#define p SI // pointer to advance through b
|
||||
#define n DX
|
||||
#define end BX // loop end
|
||||
#define v1 R8
|
||||
#define v2 R9
|
||||
#define v3 R10
|
||||
#define v4 R11
|
||||
#define x R12
|
||||
#define prime1 R13
|
||||
#define prime2 R14
|
||||
#define prime4 DI
|
||||
|
||||
// round reads from and advances the buffer pointer in SI.
|
||||
// It assumes that R13 has prime1v and R14 has prime2v.
|
||||
#define round(r) \
|
||||
MOVQ (SI), R12 \
|
||||
ADDQ $8, SI \
|
||||
IMULQ R14, R12 \
|
||||
ADDQ R12, r \
|
||||
ROLQ $31, r \
|
||||
IMULQ R13, r
|
||||
#define round(acc, x) \
|
||||
IMULQ prime2, x \
|
||||
ADDQ x, acc \
|
||||
ROLQ $31, acc \
|
||||
IMULQ prime1, acc
|
||||
|
||||
// mergeRound applies a merge round on the two registers acc and val.
|
||||
// It assumes that R13 has prime1v, R14 has prime2v, and DI has prime4v.
|
||||
#define mergeRound(acc, val) \
|
||||
IMULQ R14, val \
|
||||
ROLQ $31, val \
|
||||
IMULQ R13, val \
|
||||
XORQ val, acc \
|
||||
IMULQ R13, acc \
|
||||
ADDQ DI, acc
|
||||
// round0 performs the operation x = round(0, x).
|
||||
#define round0(x) \
|
||||
IMULQ prime2, x \
|
||||
ROLQ $31, x \
|
||||
IMULQ prime1, x
|
||||
|
||||
// mergeRound applies a merge round on the two registers acc and x.
|
||||
// It assumes that prime1, prime2, and prime4 have been loaded.
|
||||
#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
|
||||
TEXT ·Sum64(SB), NOSPLIT, $0-32
|
||||
TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32
|
||||
// Load fixed primes.
|
||||
MOVQ ·prime1v(SB), R13
|
||||
MOVQ ·prime2v(SB), R14
|
||||
MOVQ ·prime4v(SB), DI
|
||||
MOVQ ·primes+0(SB), prime1
|
||||
MOVQ ·primes+8(SB), prime2
|
||||
MOVQ ·primes+24(SB), prime4
|
||||
|
||||
// Load slice.
|
||||
MOVQ b_base+0(FP), SI
|
||||
MOVQ b_len+8(FP), DX
|
||||
LEAQ (SI)(DX*1), BX
|
||||
MOVQ b_base+0(FP), p
|
||||
MOVQ b_len+8(FP), n
|
||||
LEAQ (p)(n*1), end
|
||||
|
||||
// The first loop limit will be len(b)-32.
|
||||
SUBQ $32, BX
|
||||
SUBQ $32, end
|
||||
|
||||
// Check whether we have at least one block.
|
||||
CMPQ DX, $32
|
||||
CMPQ n, $32
|
||||
JLT noBlocks
|
||||
|
||||
// Set up initial state (v1, v2, v3, v4).
|
||||
MOVQ R13, R8
|
||||
ADDQ R14, R8
|
||||
MOVQ R14, R9
|
||||
XORQ R10, R10
|
||||
XORQ R11, R11
|
||||
SUBQ R13, R11
|
||||
MOVQ prime1, v1
|
||||
ADDQ prime2, v1
|
||||
MOVQ prime2, v2
|
||||
XORQ v3, v3
|
||||
XORQ v4, v4
|
||||
SUBQ prime1, v4
|
||||
|
||||
// Loop until SI > BX.
|
||||
blockLoop:
|
||||
round(R8)
|
||||
round(R9)
|
||||
round(R10)
|
||||
round(R11)
|
||||
blockLoop()
|
||||
|
||||
CMPQ SI, BX
|
||||
JLE blockLoop
|
||||
MOVQ v1, h
|
||||
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
|
||||
ROLQ $1, AX
|
||||
MOVQ R9, R12
|
||||
ROLQ $7, R12
|
||||
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)
|
||||
mergeRound(h, v1)
|
||||
mergeRound(h, v2)
|
||||
mergeRound(h, v3)
|
||||
mergeRound(h, v4)
|
||||
|
||||
JMP afterBlocks
|
||||
|
||||
noBlocks:
|
||||
MOVQ ·prime5v(SB), AX
|
||||
MOVQ ·primes+32(SB), h
|
||||
|
||||
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, BX
|
||||
ADDQ $24, end
|
||||
CMPQ p, end
|
||||
JG try4
|
||||
|
||||
CMPQ SI, BX
|
||||
JG fourByte
|
||||
loop8:
|
||||
MOVQ (p), x
|
||||
ADDQ $8, p
|
||||
round0(x)
|
||||
XORQ x, h
|
||||
ROLQ $27, h
|
||||
IMULQ prime1, h
|
||||
ADDQ prime4, h
|
||||
|
||||
wordLoop:
|
||||
// Calculate k1.
|
||||
MOVQ (SI), R8
|
||||
ADDQ $8, SI
|
||||
IMULQ R14, R8
|
||||
ROLQ $31, R8
|
||||
IMULQ R13, R8
|
||||
CMPQ p, end
|
||||
JLE loop8
|
||||
|
||||
XORQ R8, AX
|
||||
ROLQ $27, AX
|
||||
IMULQ R13, AX
|
||||
ADDQ DI, AX
|
||||
try4:
|
||||
ADDQ $4, end
|
||||
CMPQ p, end
|
||||
JG try1
|
||||
|
||||
CMPQ SI, BX
|
||||
JLE wordLoop
|
||||
MOVL (p), x
|
||||
ADDQ $4, p
|
||||
IMULQ prime1, x
|
||||
XORQ x, h
|
||||
|
||||
fourByte:
|
||||
ADDQ $4, BX
|
||||
CMPQ SI, BX
|
||||
JG singles
|
||||
ROLQ $23, h
|
||||
IMULQ prime2, h
|
||||
ADDQ ·primes+16(SB), h
|
||||
|
||||
MOVL (SI), R8
|
||||
ADDQ $4, SI
|
||||
IMULQ R13, R8
|
||||
XORQ R8, AX
|
||||
|
||||
ROLQ $23, AX
|
||||
IMULQ R14, AX
|
||||
ADDQ ·prime3v(SB), AX
|
||||
|
||||
singles:
|
||||
ADDQ $4, BX
|
||||
CMPQ SI, BX
|
||||
try1:
|
||||
ADDQ $4, end
|
||||
CMPQ p, end
|
||||
JGE finalize
|
||||
|
||||
singlesLoop:
|
||||
MOVBQZX (SI), R12
|
||||
ADDQ $1, SI
|
||||
IMULQ ·prime5v(SB), R12
|
||||
XORQ R12, AX
|
||||
loop1:
|
||||
MOVBQZX (p), x
|
||||
ADDQ $1, p
|
||||
IMULQ ·primes+32(SB), x
|
||||
XORQ x, h
|
||||
ROLQ $11, h
|
||||
IMULQ prime1, h
|
||||
|
||||
ROLQ $11, AX
|
||||
IMULQ R13, AX
|
||||
|
||||
CMPQ SI, BX
|
||||
JL singlesLoop
|
||||
CMPQ p, end
|
||||
JL loop1
|
||||
|
||||
finalize:
|
||||
MOVQ AX, R12
|
||||
SHRQ $33, R12
|
||||
XORQ R12, AX
|
||||
IMULQ R14, AX
|
||||
MOVQ AX, R12
|
||||
SHRQ $29, R12
|
||||
XORQ R12, AX
|
||||
IMULQ ·prime3v(SB), AX
|
||||
MOVQ AX, R12
|
||||
SHRQ $32, R12
|
||||
XORQ R12, AX
|
||||
MOVQ h, x
|
||||
SHRQ $33, x
|
||||
XORQ x, h
|
||||
IMULQ prime2, h
|
||||
MOVQ h, x
|
||||
SHRQ $29, x
|
||||
XORQ x, h
|
||||
IMULQ ·primes+16(SB), h
|
||||
MOVQ h, x
|
||||
SHRQ $32, x
|
||||
XORQ x, h
|
||||
|
||||
MOVQ AX, ret+24(FP)
|
||||
MOVQ h, ret+24(FP)
|
||||
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
|
||||
TEXT ·writeBlocks(SB), NOSPLIT, $0-40
|
||||
TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40
|
||||
// Load fixed primes needed for round.
|
||||
MOVQ ·prime1v(SB), R13
|
||||
MOVQ ·prime2v(SB), R14
|
||||
MOVQ ·primes+0(SB), prime1
|
||||
MOVQ ·primes+8(SB), prime2
|
||||
|
||||
// Load slice.
|
||||
MOVQ b_base+8(FP), SI
|
||||
MOVQ b_len+16(FP), DX
|
||||
LEAQ (SI)(DX*1), BX
|
||||
SUBQ $32, BX
|
||||
MOVQ b_base+8(FP), p
|
||||
MOVQ b_len+16(FP), n
|
||||
LEAQ (p)(n*1), end
|
||||
SUBQ $32, end
|
||||
|
||||
// Load vN from d.
|
||||
MOVQ d+0(FP), AX
|
||||
MOVQ 0(AX), R8 // v1
|
||||
MOVQ 8(AX), R9 // v2
|
||||
MOVQ 16(AX), R10 // v3
|
||||
MOVQ 24(AX), R11 // v4
|
||||
MOVQ s+0(FP), d
|
||||
MOVQ 0(d), v1
|
||||
MOVQ 8(d), v2
|
||||
MOVQ 16(d), v3
|
||||
MOVQ 24(d), v4
|
||||
|
||||
// We don't need to check the loop condition here; this function is
|
||||
// always called with at least one block of data to process.
|
||||
blockLoop:
|
||||
round(R8)
|
||||
round(R9)
|
||||
round(R10)
|
||||
round(R11)
|
||||
|
||||
CMPQ SI, BX
|
||||
JLE blockLoop
|
||||
blockLoop()
|
||||
|
||||
// Copy vN back to d.
|
||||
MOVQ R8, 0(AX)
|
||||
MOVQ R9, 8(AX)
|
||||
MOVQ R10, 16(AX)
|
||||
MOVQ R11, 24(AX)
|
||||
MOVQ v1, 0(d)
|
||||
MOVQ v2, 8(d)
|
||||
MOVQ v3, 16(d)
|
||||
MOVQ v4, 24(d)
|
||||
|
||||
// The number of bytes written is SI minus the old base pointer.
|
||||
SUBQ b_base+8(FP), SI
|
||||
MOVQ SI, ret+32(FP)
|
||||
// The number of bytes written is p minus the old base pointer.
|
||||
SUBQ b_base+8(FP), p
|
||||
MOVQ p, ret+32(FP)
|
||||
|
||||
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 gc
|
||||
// +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
|
||||
|
||||
@@ -14,10 +15,10 @@ func Sum64(b []byte) uint64 {
|
||||
var h uint64
|
||||
|
||||
if n >= 32 {
|
||||
v1 := prime1v + prime2
|
||||
v1 := primes[0] + prime2
|
||||
v2 := prime2
|
||||
v3 := uint64(0)
|
||||
v4 := -prime1v
|
||||
v4 := -primes[0]
|
||||
for len(b) >= 32 {
|
||||
v1 = round(v1, u64(b[0:8:len(b)]))
|
||||
v2 = round(v2, u64(b[8:16:len(b)]))
|
||||
@@ -36,19 +37,18 @@ func Sum64(b []byte) uint64 {
|
||||
|
||||
h += uint64(n)
|
||||
|
||||
i, end := 0, len(b)
|
||||
for ; i+8 <= end; i += 8 {
|
||||
k1 := round(0, u64(b[i:i+8:len(b)]))
|
||||
for ; len(b) >= 8; b = b[8:] {
|
||||
k1 := round(0, u64(b[:8]))
|
||||
h ^= k1
|
||||
h = rol27(h)*prime1 + prime4
|
||||
}
|
||||
if i+4 <= end {
|
||||
h ^= uint64(u32(b[i:i+4:len(b)])) * prime1
|
||||
if len(b) >= 4 {
|
||||
h ^= uint64(u32(b[:4])) * prime1
|
||||
h = rol23(h)*prime2 + prime3
|
||||
i += 4
|
||||
b = b[4:]
|
||||
}
|
||||
for ; i < end; i++ {
|
||||
h ^= uint64(b[i]) * prime5
|
||||
for ; len(b) > 0; b = b[1:] {
|
||||
h ^= uint64(b[0]) * prime5
|
||||
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
|
||||
|
||||
// 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
|
||||
|
||||
// This file encapsulates usage of unsafe.
|
||||
@@ -11,7 +12,7 @@ import (
|
||||
|
||||
// In the future it's possible that compiler optimizations will make these
|
||||
// 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
|
||||
// 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
|
||||
|
||||
## [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)
|
||||
|
||||
## [v3.8.0] - 20221-06-06
|
||||
## [v3.8.0] - 2022-06-06
|
||||
|
||||
- use exact matching of allowed domain entries, issue #489 (#493)
|
||||
- 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
|
||||
- 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 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
|
||||
|
||||
|
||||
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 (
|
||||
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_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
|
||||
|
||||
HEADER_Allow = "Allow"
|
||||
HEADER_Accept = "Accept"
|
||||
HEADER_Origin = "Origin"
|
||||
HEADER_ContentType = "Content-Type"
|
||||
HEADER_ContentDisposition = "Content-Disposition"
|
||||
HEADER_LastModified = "Last-Modified"
|
||||
HEADER_AcceptEncoding = "Accept-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.
|
||||
// Valid values are restful.MIME_JSON and restful.MIME_XML
|
||||
// Example:
|
||||
//
|
||||
// restful.DefaultRequestContentType(restful.MIME_JSON)
|
||||
func DefaultRequestContentType(mime string) {
|
||||
defaultRequestContentType = mime
|
||||
@@ -48,7 +49,7 @@ func (r *Request) PathParameters() map[string]string {
|
||||
|
||||
// QueryParameter returns the (first) Query parameter value by its name
|
||||
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
|
||||
|
||||
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 {
|
||||
return entityAccessRegistry.accessorAt(MIME_XML)
|
||||
}
|
||||
if DefaultResponseMimeType == MIME_ZIP {
|
||||
return entityAccessRegistry.accessorAt(MIME_ZIP)
|
||||
}
|
||||
// Fallback to whatever the route says it can produce.
|
||||
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
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 {
|
||||
return nil
|
||||
}
|
||||
return strings.Split(strings.Trim(path, "/"), "/")
|
||||
return strings.Split(strings.TrimLeft(path, "/"), "/")
|
||||
}
|
||||
|
||||
// for debugging
|
||||
@@ -176,3 +176,5 @@ func (r *Route) String() string {
|
||||
func (r *Route) EnableContentEncoding(enabled bool) {
|
||||
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 (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -46,6 +47,7 @@ type RouteBuilder struct {
|
||||
// Do evaluates each argument with the RouteBuilder itself.
|
||||
// This allows you to follow DRY principles without breaking the fluent programming style.
|
||||
// Example:
|
||||
//
|
||||
// ws.Route(ws.DELETE("/{name}").To(t.deletePerson).Do(Returns200, Returns500))
|
||||
//
|
||||
// func Returns500(b *RouteBuilder) {
|
||||
@@ -351,8 +353,28 @@ func (b *RouteBuilder) Build() Route {
|
||||
return route
|
||||
}
|
||||
|
||||
func concatPath(path1, path2 string) string {
|
||||
return strings.TrimRight(path1, "/") + "/" + strings.TrimLeft(path2, "/")
|
||||
type MergePathStrategyFunc func(rootPath, routePath string) string
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
golint:
|
||||
min-confidence: 0
|
||||
gocyclo:
|
||||
min-complexity: 30
|
||||
maligned:
|
||||
@@ -12,6 +10,8 @@ linters-settings:
|
||||
goconst:
|
||||
min-len: 2
|
||||
min-occurrences: 4
|
||||
paralleltest:
|
||||
ignore-missing: true
|
||||
linters:
|
||||
enable-all: true
|
||||
disable:
|
||||
@@ -39,3 +39,12 @@ linters:
|
||||
- nestif
|
||||
- godot
|
||||
- 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 (
|
||||
defaultHttpPort = ":80"
|
||||
defaultHttpsPort = ":443"
|
||||
defaultHTTPPort = ":80"
|
||||
defaultHTTPSPort = ":443"
|
||||
)
|
||||
|
||||
// Regular expressions used by the normalizations
|
||||
@@ -18,6 +18,7 @@ var rxDupSlashes = regexp.MustCompile(`/{2,}`)
|
||||
// NormalizeURL will normalize the specified URL
|
||||
// This was added to replace a previous call to the no longer maintained purell library:
|
||||
// The call that was used looked like the following:
|
||||
//
|
||||
// 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:
|
||||
@@ -25,11 +26,16 @@ var rxDupSlashes = regexp.MustCompile(`/{2,}`)
|
||||
// - FlagLowercaseHost
|
||||
// - FlagRemoveDefaultPort
|
||||
// - 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) {
|
||||
lowercaseScheme(u)
|
||||
lowercaseHost(u)
|
||||
removeDefaultPort(u)
|
||||
removeDuplicateSlashes(u)
|
||||
|
||||
u.RawPath = ""
|
||||
u.RawFragment = ""
|
||||
}
|
||||
|
||||
func lowercaseScheme(u *url.URL) {
|
||||
@@ -48,7 +54,7 @@ func removeDefaultPort(u *url.URL) {
|
||||
if len(u.Host) > 0 {
|
||||
scheme := strings.ToLower(u.Scheme)
|
||||
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 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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user