mirror of
https://github.com/openshift/installer.git
synced 2026-02-05 15:47:14 +01:00
Revert "Merge pull request #9645 from patrickdillon/azurestack-mark-iii"
This reverts commit63e0c358e0, reversing changes made tod9c19b4517.
This commit is contained in:
@@ -166,5 +166,4 @@ issues:
|
||||
- ^scripts
|
||||
- ^terraform
|
||||
- ^upi
|
||||
- ^pkg/asset/manifests/azure/stack/v1beta1 # local copy of capi azurestack provider fork api
|
||||
uniq-by-line: false
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
module openshift/installer/cluster-api/providers/azurestack
|
||||
|
||||
go 1.22.11
|
||||
|
||||
toolchain go1.24.1
|
||||
|
||||
require sigs.k8s.io/cluster-api-provider-azure v1.19.1
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.19.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets v0.12.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v1.2.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.4.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.3.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcehealth/armresourcehealth v1.3.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/tracing/azotel v0.4.0 // indirect
|
||||
github.com/Azure/azure-service-operator/v2 v2.11.0 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.30 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.24 // indirect
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 // indirect
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2 // indirect
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
|
||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/Azure/msi-dataplane v0.4.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 // indirect
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/asaskevich/govalidator/v11 v11.0.2-0.20250122183457-e11347878e23 // indirect
|
||||
github.com/benbjohnson/clock v1.3.5 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dimchansky/utfbom v1.1.1 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/gobuffalo/flect v1.0.3 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/cel-go v0.22.0 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect
|
||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jellydator/ttlcache/v3 v3.3.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // 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/onsi/gomega v1.36.2 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.62.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/samber/lo v1.47.0 // indirect
|
||||
github.com/spf13/cobra v1.8.1 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/stoewer/go-strcase v1.3.0 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.57.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
go.uber.org/mock v0.5.0 // indirect
|
||||
golang.org/x/crypto v0.33.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac // indirect
|
||||
golang.org/x/mod v0.23.0 // indirect
|
||||
golang.org/x/net v0.35.0 // indirect
|
||||
golang.org/x/oauth2 v0.26.0 // indirect
|
||||
golang.org/x/sync v0.11.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/term v0.29.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
golang.org/x/time v0.8.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect
|
||||
google.golang.org/grpc v1.71.0 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.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/api v0.31.3 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.31.3 // indirect
|
||||
k8s.io/apimachinery v0.31.3 // indirect
|
||||
k8s.io/apiserver v0.31.3 // indirect
|
||||
k8s.io/client-go v0.31.3 // indirect
|
||||
k8s.io/cloud-provider v0.30.2 // indirect
|
||||
k8s.io/cluster-bootstrap v0.31.3 // indirect
|
||||
k8s.io/component-base v0.31.3 // indirect
|
||||
k8s.io/component-helpers v0.30.3 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 // indirect
|
||||
k8s.io/utils v0.0.0-20240821151609-f90d01438635 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect
|
||||
sigs.k8s.io/cloud-provider-azure v1.30.4 // indirect
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azclient v0.0.29 // indirect
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader v0.0.16 // indirect
|
||||
sigs.k8s.io/cluster-api v1.9.5 // indirect
|
||||
sigs.k8s.io/controller-runtime v0.19.6 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
)
|
||||
|
||||
replace sigs.k8s.io/cluster-api-provider-azure => github.com/openshift/cluster-api-provider-azurestack v0.0.0-20250410174346-ae86003b65c7
|
||||
@@ -1,560 +0,0 @@
|
||||
cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4=
|
||||
cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
|
||||
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
|
||||
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 h1:F0gBpfdPLGsw+nsgk6aqqkZS1jiixa5WwFe3fk/T3Ys=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2/go.mod h1:SqINnQ9lVVdRlyC8cd1lCI0SdX4n2paeABd2K8ggfnE=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets v0.12.0 h1:xnO4sFyG8UH2fElBkcqLTOZsAajvKfnSlgBBW8dXYjw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/azsecrets v0.12.0/go.mod h1:XD3DIOOVgBCO03OleB1fHjgktVRFxlT++KwKgIOewdM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 h1:FbH3BbSb4bvGluTesZZ+ttN/MDsnMmQP36OSnDuSXqw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1/go.mod h1:9V2j0jn9jDEkCkv8w/bKTNppX/d0FVA1ud77xCIP4KA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/apimanagement/armapimanagement v1.1.1 h1:jCkNVNpsEevyic4bmjgVjzVA4tMGSJpXNGirf+S+mDI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/apimanagement/armapimanagement v1.1.1/go.mod h1:a0Ug1l73Il7EhrCJEEt2dGjlNjvphppZq5KqJdgnwuw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/appconfiguration/armappconfiguration v1.1.1 h1:iRc20pGuVlc1HwRO2bg0m1tfP9rkPB0K88trl8Fei2w=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/appconfiguration/armappconfiguration v1.1.1/go.mod h1:21Lewei+tg5zp5xmyOxfDY//2tBvWQXee0UoM8xZjr8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 h1:Hp+EScFOu9HeCbeW8WU2yQPJd4gGwhMgKxWe+G6jNzw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0/go.mod h1:/pz8dyNQe+Ey3yBp/XuYz7oqX8YDNWVpPB0hH3XWfbc=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 h1:LkHbJbgF3YyvC53aqYGR+wWQDn2Rdp9AQdGndf9QvY4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0/go.mod h1:QyiQdW4f4/BIfB8ZutZ2s+28RAgfa/pT+zS++ZHyM1I=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v1.2.0 h1:DWlwvVV5r/Wy1561nZ3wrpI1/vDIBRY/Wd1HWaRBZWA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v1.2.0/go.mod h1:E7ltexgRDmeJ0fJWv0D/HLwY2xbDdN+uv+X2uZtOx3w=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0 h1:figxyQZXzZQIcP3njhC68bYUiTw45J8/SsHaLW8Ax0M=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0/go.mod h1:TmlMW4W5OvXOmOyKNnor8nlMMiO1ctIyzmHme/VHsrA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0 h1:0nGmzwBv5ougvzfGPCO2ljFRHvun57KpNrVCMrlk0ns=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0/go.mod h1:gYq8wyDgv6JLhGbAU6gg8amCPgQWRE+aCvrV2gyzdfs=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/cosmos/armcosmos v1.0.0 h1:Fv8iibGn1eSw0lt2V3cTsuokBEnOP+M//n8OiMcCgTM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/cosmos/armcosmos v1.0.0/go.mod h1:Qpe/qN9d5IQ7WPtTXMRCd6+BWTnhi3sxXVys6oJ5Vho=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dataprotection/armdataprotection/v3 v3.1.0 h1:Yj6NV1y8Deg7leXETiM9gJ+peM9DxhLR3GmppUSH+a0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dataprotection/armdataprotection/v3 v3.1.0/go.mod h1:4lNPcTKG4Zgad7aiZBmvLfIMX47eqr5BFzDjC4zggKU=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/eventgrid/armeventgrid v1.0.0 h1:w6b0+FygDpqM7g5cjbeyPoBzgxVHwwt2vCUvTz1oFY8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/eventgrid/armeventgrid v1.0.0/go.mod h1:t8kRpcgm+RdImuJgHG6SfoQ0tpb9LGl7MF1E6u0yeeA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/eventhub/armeventhub v1.3.0 h1:4hGvxD72TluuFIXVr8f4XkKZfqAa7Pj61t0jmQ7+kes=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/eventhub/armeventhub v1.3.0/go.mod h1:TSH7DcFItwAufy0Lz+Ft2cyopExCpxbOxI5SkH4dRNo=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0/go.mod h1:LRr2FzBTQlONPPa5HREE5+RjSCTXl7BwOvYOaWTqCaI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.1.0 h1:2qsIIvxVT+uE6yrNldntJKlLRgxGbZ85kgtz5SNBhMw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v3 v3.1.0/go.mod h1:AW8VEadnhw9xox+VaVd9sP7NjzOAnaZBLRH6Tq3cJ38=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/iothub/armiothub v1.3.0 h1:NZP+oPbAVFy7PhQ4PTD3SuGWbEziNhp7lphGkkN707s=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/iothub/armiothub v1.3.0/go.mod h1:djbLk3ngutFfQ9fSOM29UzywAkcBI1YUsuUnxTQGsqU=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.4.0 h1:HlZMUZW8S4P9oob1nCHxCCKrytxyLc+24nUJGssoEto=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.4.0/go.mod h1:StGsLbuJh06Bd8IBfnAlIFV3fLb+gkczONWf15hpX2E=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/machinelearning/armmachinelearning v1.0.0 h1:KWvCVjnOTKCZAlqED5KPNoN9AfcK2BhUeveLdiwy33Q=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/machinelearning/armmachinelearning v1.0.0/go.mod h1:qNN4I5AKYbXMLriS9XKebBw8EVIQkX6tJzrdtjOoJ4I=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0 h1:pPvTJ1dY0sA35JOeFq6TsY2xj6Z85Yo23Pj4wCCvu4o=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0/go.mod h1:mLfWfj8v3jfWKsL9G4eoBoXVcsqcIUTapmdKy7uGOp0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0 h1:z4YeiSXxnUI+PqB46Yj6MZA3nwb1CcJIkEMDrzUd8Cs=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0/go.mod h1:rko9SzMxcMk0NJsNAxALEGaTYyy79bNRwxgJfrH0Spw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0 h1:QM6sE5k2ZT/vI5BEe0r7mqjsUSnhVBFbOsVkEuaEfiA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0/go.mod h1:243D9iHbcQXoFUtgHJwL7gl2zx1aDuDMjvBZVGr2uW0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0/go.mod h1:Y/HgrePTmGy9HjdSGTqZNa+apUpTVIEVKXJyARP2lrk=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.3.0 h1:yzrctSl9GMIQ5lHu7jc8olOsGjWDCsBpJhWqfGa/YIM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.3.0/go.mod h1:GE4m0rnnfwLGX0Y9A9A25Zx5N/90jneT5ABevqzhuFQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/redis/armredis v1.0.0 h1:nmpTBgRg1HynngFYICRhceC7s5dmbKN9fJ/XQz/UQ2I=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/redis/armredis v1.0.0/go.mod h1:3yjiOtnkVociBTlF7UZrwAGfJrGaOCsvtVS4HzNajxQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcehealth/armresourcehealth v1.3.0 h1:hz+ZQ21PKZ6TBEiVMq8zqWUzA5DGj087lYC8OCm6wuY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcehealth/armresourcehealth v1.3.0/go.mod h1:AN7AudLmrOvJlt7ormR1M5splG0TkZ4xyAqEIMIwTB0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0 h1:Dd+RhdJn0OTtVGaeDLZpcumkIVCtA/3/Fo42+eoYvVM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0/go.mod h1:5kakwfW5CjC9KK+Q4wjXAg+ShuIm2mBMua0ZFj2C8PE=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/search/armsearch v1.3.0 h1:HpCtTs500PzKoBWKBLZVFEG9Zh20f7cAFbWj8D9JWkg=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/search/armsearch v1.3.0/go.mod h1:3uruTckNIGQ4iNsvAs/qrLgWBoS1pA7pCzHFmTFU+LU=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/servicebus/armservicebus v1.2.0 h1:jngSeKBnzC7qIk3rvbWHsLI7eeasEucORHWr2CHX0Yg=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/servicebus/armservicebus v1.2.0/go.mod h1:1YXAxWw6baox+KafeQU2scy21/4IHvqXoIJuCpcvpMQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/signalr/armsignalr v1.2.0 h1:Y8CF7FyuVVDyX5W6Azwjj3PpwUZVbXBOCyQytv/0QEA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/signalr/armsignalr v1.2.0/go.mod h1:tzUx/enAY8RSmQhRq02uVZFeRJxdGYT6BqXwHiHoOcU=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0 h1:PiSrjRPpkQNjrM8H0WwKMnZUdu1RGMtd/LdGKUrOo+c=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0/go.mod h1:oDrbWx4ewMylP7xHivfgixbfGBT6APAwsSoHRKotnIc=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0 h1:UrGzkHueDwAWDdjQxC+QaXHd4tVCkISYE9j7fSSXF8k=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0/go.mod h1:qskvSQeW+cxEE2bcKYyKimB1/KiQ9xpJ99bcHY0BX6c=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/tracing/azotel v0.4.0 h1:RTTsXUJWn0jumeX62Mb153wYXykqnrzYBYDeHp0kiuk=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/tracing/azotel v0.4.0/go.mod h1:k4MMjrPHIEK+umaMGk1GNLgjEybJZ9mHSRDZ+sDFv3Y=
|
||||
github.com/Azure/azure-service-operator/v2 v2.11.0 h1:YOSYBKdBqUMh2uGx1wrf5QTSC76NCLA6O8u9ZktA6Ck=
|
||||
github.com/Azure/azure-service-operator/v2 v2.11.0/go.mod h1:HxzKA61dKVQDusxCMOswxU4zX+vNb91E42jNDZjG6d4=
|
||||
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/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA=
|
||||
github.com/Azure/go-autorest/autorest v0.11.30 h1:iaZ1RGz/ALZtN5eq4Nr1SOFSlf2E4pDI3Tcsl+dZPVE=
|
||||
github.com/Azure/go-autorest/autorest v0.11.30/go.mod h1:t1kpPIOpIVX7annvothKvb0stsrXa37i7b+xpmBW8Fs=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.24 h1:BHZfgGsGwdkHDyZdtQRQk1WeUdW0m2WPAwuHZwUi5i4=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.24/go.mod h1:7T1+g0PYFmACYW5LlG2fcoPiPlFHjClyRGL7dRlP5c8=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 h1:Ov8avRZi2vmrE2JcXw+tu5K/yB41r7xK9GZDiBF7NdM=
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.13/go.mod h1:5BAVfWLWXihP47vYrPuBKKf4cS0bXI+KM9Qx6ETDJYo=
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 h1:w77/uPk80ZET2F+AfQExZyEWtn+0Rk/uw17m9fv5Ajc=
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0=
|
||||
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/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk=
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac=
|
||||
github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E=
|
||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/Azure/msi-dataplane v0.4.0 h1:lofdhX74IgMEvIe6cw8tdwr3zfZkdk77TXetFv0/By8=
|
||||
github.com/Azure/msi-dataplane v0.4.0/go.mod h1:y+euhWbc8/wgVM1hyJLQf4DnByegnwxAcDV0OKNM9+k=
|
||||
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
|
||||
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 h1:H5xDQaE3XowWfhZRUpnfC+rGZMEVoSiji+b+/HFAPU4=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
|
||||
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
|
||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
|
||||
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
|
||||
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
|
||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/asaskevich/govalidator/v11 v11.0.2-0.20250122183457-e11347878e23 h1:I+Cy77zrFmVWIHOZaxiNV4L7w9xuVux9LMqAblGzvdE=
|
||||
github.com/asaskevich/govalidator/v11 v11.0.2-0.20250122183457-e11347878e23/go.mod h1:S7DsXubvw3xBC8rSI+qmzcTNw7xEND0ojHPqglh/whY=
|
||||
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
|
||||
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
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/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0=
|
||||
github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4=
|
||||
github.com/coredns/corefile-migration v1.0.25 h1:/XexFhM8FFlFLTS/zKNEWgIZ8Gl5GaWrHsMarGj/PRQ=
|
||||
github.com/coredns/corefile-migration v1.0.25/go.mod h1:56DPqONc3njpVPsdilEnfijCwNGC3/kTJLl7i7SPavY=
|
||||
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
|
||||
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
|
||||
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU=
|
||||
github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls=
|
||||
github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=
|
||||
github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
||||
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
|
||||
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/gobuffalo/flect v1.0.3 h1:xeWBM2nui+qnVvNM4S3foBhCAL2XgPU+a7FdpelbTq4=
|
||||
github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs=
|
||||
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.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||
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/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g=
|
||||
github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
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/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M=
|
||||
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
|
||||
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
|
||||
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
|
||||
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jellydator/ttlcache/v3 v3.3.0 h1:BdoC9cE81qXfrxeb9eoJi9dWrdhSuwXMAnHTbnBm4Wc=
|
||||
github.com/jellydator/ttlcache/v3 v3.3.0/go.mod h1:bj2/e0l4jRnQdrnSTaGTsh4GSXvMjQcy41i7th0GVGw=
|
||||
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
|
||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
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/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs=
|
||||
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw=
|
||||
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/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4=
|
||||
github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA=
|
||||
github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
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 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/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
|
||||
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
|
||||
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/openshift/cluster-api-provider-azurestack v0.0.0-20250410174346-ae86003b65c7 h1:w8sHCUZw53skAAycXhsUwUSZOTN2sAUSQmXZs+QwpEg=
|
||||
github.com/openshift/cluster-api-provider-azurestack v0.0.0-20250410174346-ae86003b65c7/go.mod h1:g7lz7uqp4uN7w/kVRKQ4GVJUhQXPwJMx994mwkteaSA=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
|
||||
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc=
|
||||
github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
|
||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
|
||||
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
|
||||
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
||||
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
|
||||
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
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/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI=
|
||||
go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE=
|
||||
go.etcd.io/etcd/api/v3 v3.5.17 h1:cQB8eb8bxwuxOilBpMJAEo8fAONyrdXTHUNcMd8yT1w=
|
||||
go.etcd.io/etcd/api/v3 v3.5.17/go.mod h1:d1hvkRuXkts6PmaYk2Vrgqbv7H4ADfAKhyJqHNLJCB4=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.17 h1:XxnDXAWq2pnxqx76ljWwiQ9jylbpC4rvkAeRVOUKKVw=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.17/go.mod h1:4DqK1TKacp/86nJk4FLQqo6Mn2vvQFBmruW3pP14H/w=
|
||||
go.etcd.io/etcd/client/v2 v2.305.13 h1:RWfV1SX5jTU0lbCvpVQe3iPQeAHETWdOTb6pxhd77C8=
|
||||
go.etcd.io/etcd/client/v2 v2.305.13/go.mod h1:iQnL7fepbiomdXMb3om1rHq96htNNGv2sJkEcZGDRRg=
|
||||
go.etcd.io/etcd/client/v3 v3.5.17 h1:o48sINNeWz5+pjy/Z0+HKpj/xSnBkuVhVvXkjEXbqZY=
|
||||
go.etcd.io/etcd/client/v3 v3.5.17/go.mod h1:j2d4eXTHWkT2ClBgnnEPm/Wuu7jsqku41v9DZ3OtjQo=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.13 h1:st9bDWNsKkBNpP4PR1MvM/9NqUPfvYZx/YXegsYEH8M=
|
||||
go.etcd.io/etcd/pkg/v3 v3.5.13/go.mod h1:N+4PLrp7agI/Viy+dUYpX7iRtSPvKq+w8Y14d1vX+m0=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.13 h1:7r/NKAOups1YnKcfro2RvGGo2PTuizF/xh26Z2CTAzA=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.13/go.mod h1:uUFibGLn2Ksm2URMxN1fICGhk8Wu96EfDQyuLhAcAmw=
|
||||
go.etcd.io/etcd/server/v3 v3.5.13 h1:V6KG+yMfMSqWt+lGnhFpP5z5dRUj1BDRJ5k1fQ9DFok=
|
||||
go.etcd.io/etcd/server/v3 v3.5.13/go.mod h1:K/8nbsGupHqmr5MkgaZpLlH1QdX1pcNQLAkODy44XcQ=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.16.0 h1:YhxxmXZ011C0aDZKoNw+juVWAmEfv/0W2XBOv9aHTaA=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.16.0/go.mod h1:grYbBo/5afWlPpdPZYhyn78Bk04hnvxn2+hvxQhKIQM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.57.0 h1:AHh/lAP1BHrY5gBwk8ncc25FXWm/gmmY3BX258z5nuk=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.57.0/go.mod h1:QpFWz1QxqevfjwzYdbMb4Y1NnlJvqSGwyuU0B4iuc9c=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
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.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
||||
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
||||
golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac h1:l5+whBCLH3iH2ZNHYLbAe58bo7yrN4mVcnkHDYz5vvs=
|
||||
golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac/go.mod h1:hH+7mtFmImwwcMvScyxUhjuVHR3HGaDPMn9rMSUUbxo=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
|
||||
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/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-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-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
|
||||
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
|
||||
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
|
||||
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
|
||||
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.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY=
|
||||
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a h1:nwKuGPlUAt+aR+pcrkfFRrTU1BVrSmYyYMxYbUIVHr0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ=
|
||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/dnaeon/go-vcr.v3 v3.2.0 h1:Rltp0Vf+Aq0u4rQXgmXgtgoRDStTnFN83cWgSGSoRzM=
|
||||
gopkg.in/dnaeon/go-vcr.v3 v3.2.0/go.mod h1:2IMOnnlx9I6u9x+YBsM3tAMx6AlOxnJ0pWxQAzZ79Ag=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v2 v2.2.8/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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.31.3 h1:umzm5o8lFbdN/hIXbrK9oRpOproJO62CV1zqxXrLgk8=
|
||||
k8s.io/api v0.31.3/go.mod h1:UJrkIp9pnMOI9K2nlL6vwpxRzzEX5sWgn8kGQe92kCE=
|
||||
k8s.io/apiextensions-apiserver v0.31.3 h1:+GFGj2qFiU7rGCsA5o+p/rul1OQIq6oYpQw4+u+nciE=
|
||||
k8s.io/apiextensions-apiserver v0.31.3/go.mod h1:2DSpFhUZZJmn/cr/RweH1cEVVbzFw9YBu4T+U3mf1e4=
|
||||
k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4=
|
||||
k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
|
||||
k8s.io/apiserver v0.31.3 h1:+1oHTtCB+OheqFEz375D0IlzHZ5VeQKX1KGXnx+TTuY=
|
||||
k8s.io/apiserver v0.31.3/go.mod h1:PrxVbebxrxQPFhJk4powDISIROkNMKHibTg9lTRQ0Qg=
|
||||
k8s.io/client-go v0.31.3 h1:CAlZuM+PH2cm+86LOBemaJI/lQ5linJ6UFxKX/SoG+4=
|
||||
k8s.io/client-go v0.31.3/go.mod h1:2CgjPUTpv3fE5dNygAr2NcM8nhHzXvxB8KL5gYc3kJs=
|
||||
k8s.io/cloud-provider v0.30.2 h1:yov6r02v7sMUNNvzEz51LtL2krn2c1wsC+dy/8BxKQI=
|
||||
k8s.io/cloud-provider v0.30.2/go.mod h1:w69t2dSjDtI9BYK6SEqj6HmMKIojEk08fXRoUzjFN2I=
|
||||
k8s.io/cluster-bootstrap v0.31.3 h1:O1Yxk1bLaxZvmQCXLaJjj5iJD+lVMfJdRUuKgbUHPlA=
|
||||
k8s.io/cluster-bootstrap v0.31.3/go.mod h1:TI6TCsQQB4FfcryWgNO3SLXSKWBqHjx4DfyqSFwixj8=
|
||||
k8s.io/component-base v0.31.3 h1:DMCXXVx546Rfvhj+3cOm2EUxhS+EyztH423j+8sOwhQ=
|
||||
k8s.io/component-base v0.31.3/go.mod h1:xME6BHfUOafRgT0rGVBGl7TuSg8Z9/deT7qq6w7qjIU=
|
||||
k8s.io/component-helpers v0.30.3 h1:KPc8l0eGx9Wg2OcKc58k9ozNcVcOInAi3NGiuS2xJ/c=
|
||||
k8s.io/component-helpers v0.30.3/go.mod h1:VOQ7g3q+YbKWwKeACG2BwPv4ftaN8jXYJ5U3xpzuYAE=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 h1:GKE9U8BH16uynoxQii0auTjmmmuZ3O0LFMN6S0lPPhI=
|
||||
k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA=
|
||||
k8s.io/utils v0.0.0-20240821151609-f90d01438635 h1:2wThSvJoW/Ncn9TmQEYXRnevZXi2duqHWf5OX9S3zjI=
|
||||
k8s.io/utils v0.0.0-20240821151609-f90d01438635/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
|
||||
sigs.k8s.io/cloud-provider-azure v1.30.4 h1:KD9wH7JAEnYNLQnk6tT78RHGc2iIx1F5BnNBtpm3uAI=
|
||||
sigs.k8s.io/cloud-provider-azure v1.30.4/go.mod h1:MAzEM7J+Kg949oUwNdzft7N6SCj81DtEJclMxCXwv3U=
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azclient v0.0.29 h1:qiifAaaBqV3d/EcN9dKJaJI8S9FD/JhBOwrTPp+MBJY=
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azclient v0.0.29/go.mod h1:ZFAt0qF1kR+w8nBVJK56s6CFvLrlosN1i2c+Sxb7LBk=
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader v0.0.16 h1:Fm/Yjv4nXjUtJ90uXKSKwPwaTWYuDFMhDNNOd77PlOg=
|
||||
sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader v0.0.16/go.mod h1:+kl90flu4+WCP6HBGVYbKVQR+5ztDzUNrWJz8rsnvRU=
|
||||
sigs.k8s.io/cluster-api v1.9.5 h1:68164Q201Y5ANVkhyrOZenoMbfL2SEBjVYZs/ihhSro=
|
||||
sigs.k8s.io/cluster-api v1.9.5/go.mod h1:DyqyZ4jRvKGKewDRn1Q4OCHaVjsdTogymbO6mrgHEDI=
|
||||
sigs.k8s.io/controller-runtime v0.19.6 h1:fuq53qTLQ7aJTA7aNsklNnu7eQtSFqJUomOyM+phPLk=
|
||||
sigs.k8s.io/controller-runtime v0.19.6/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4=
|
||||
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.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
@@ -1,5 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "sigs.k8s.io/cluster-api-provider-azure"
|
||||
)
|
||||
@@ -1,2 +0,0 @@
|
||||
7.0.1
|
||||
# Keep this pinned version in parity with cel-go
|
||||
@@ -1,2 +0,0 @@
|
||||
*.pb.go linguist-generated=true
|
||||
*.pb.go -diff -merge
|
||||
@@ -1,2 +0,0 @@
|
||||
bazel-*
|
||||
MODULE.bazel.lock
|
||||
@@ -1,34 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"]) # Apache 2.0
|
||||
|
||||
go_library(
|
||||
name = "expr",
|
||||
srcs = [
|
||||
"checked.pb.go",
|
||||
"eval.pb.go",
|
||||
"explain.pb.go",
|
||||
"syntax.pb.go",
|
||||
"value.pb.go",
|
||||
],
|
||||
importpath = "cel.dev/expr",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"@org_golang_google_genproto_googleapis_rpc//status:go_default_library",
|
||||
"@org_golang_google_protobuf//reflect/protoreflect",
|
||||
"@org_golang_google_protobuf//runtime/protoimpl",
|
||||
"@org_golang_google_protobuf//types/known/anypb",
|
||||
"@org_golang_google_protobuf//types/known/durationpb",
|
||||
"@org_golang_google_protobuf//types/known/emptypb",
|
||||
"@org_golang_google_protobuf//types/known/structpb",
|
||||
"@org_golang_google_protobuf//types/known/timestamppb",
|
||||
],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "go_default_library",
|
||||
actual = ":expr",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
@@ -1,25 +0,0 @@
|
||||
# Contributor Code of Conduct
|
||||
## Version 0.1.1 (adapted from 0.3b-angular)
|
||||
|
||||
As contributors and maintainers of the Common Expression Language
|
||||
(CEL) project, we pledge to respect everyone who contributes by
|
||||
posting issues, updating documentation, submitting pull requests,
|
||||
providing feedback in comments, and any other activities.
|
||||
|
||||
Communication through any of CEL's channels (GitHub, Gitter, IRC,
|
||||
mailing lists, Google+, Twitter, etc.) must be constructive and never
|
||||
resort to personal attacks, trolling, public or private harassment,
|
||||
insults, or other unprofessional conduct.
|
||||
|
||||
We promise to extend courtesy and respect to everyone involved in this
|
||||
project regardless of gender, gender identity, sexual orientation,
|
||||
disability, age, race, ethnicity, religion, or level of experience. We
|
||||
expect anyone contributing to the project to do the same.
|
||||
|
||||
If any member of the community violates this code of conduct, the
|
||||
maintainers of the CEL project may take action, removing issues,
|
||||
comments, and PRs or blocking accounts as deemed appropriate.
|
||||
|
||||
If you are subject to or witness unacceptable behavior, or have any
|
||||
other concerns, please email us at
|
||||
[cel-conduct@google.com](mailto:cel-conduct@google.com).
|
||||
@@ -1,32 +0,0 @@
|
||||
# How to Contribute
|
||||
|
||||
We'd love to accept your patches and contributions to this project. There are a
|
||||
few guidelines you need to follow.
|
||||
|
||||
## Contributor License Agreement
|
||||
|
||||
Contributions to this project must be accompanied by a Contributor License
|
||||
Agreement. You (or your employer) retain the copyright to your contribution,
|
||||
this simply gives us permission to use and redistribute your contributions as
|
||||
part of the project. Head over to <https://cla.developers.google.com/> to see
|
||||
your current agreements on file or to sign a new one.
|
||||
|
||||
You generally only need to submit a CLA once, so if you've already submitted one
|
||||
(even if it was for a different project), you probably don't need to do it
|
||||
again.
|
||||
|
||||
## Code reviews
|
||||
|
||||
All submissions, including submissions by project members, require review. We
|
||||
use GitHub pull requests for this purpose. Consult
|
||||
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
|
||||
information on using pull requests.
|
||||
|
||||
## What to expect from maintainers
|
||||
|
||||
Expect maintainers to respond to new issues or pull requests within a week.
|
||||
For outstanding and ongoing issues and particularly for long-running
|
||||
pull requests, expect the maintainers to review within a week of a
|
||||
contributor asking for a new review. There is no commitment to resolution --
|
||||
merging or closing a pull request, or fixing or closing an issue -- because some
|
||||
issues will require more discussion than others.
|
||||
@@ -1,43 +0,0 @@
|
||||
# Project Governance
|
||||
|
||||
This document defines the governance process for the CEL language. CEL is
|
||||
Google-developed, but openly governed. Major contributors to the CEL
|
||||
specification and its corresponding implementations constitute the CEL
|
||||
Language Council. New members may be added by a unanimous vote of the
|
||||
Council.
|
||||
|
||||
The MAINTAINERS.md file lists the members of the CEL Language Council, and
|
||||
unofficially indicates the "areas of expertise" of each member with respect
|
||||
to the publicly available CEL repos.
|
||||
|
||||
## Code Changes
|
||||
|
||||
Code changes must follow the standard pull request (PR) model documented in the
|
||||
CONTRIBUTING.md for each CEL repo. All fixes and features must be reviewed by a
|
||||
maintainer. The maintainer reserves the right to request that any feature
|
||||
request (FR) or PR be reviewed by the language council.
|
||||
|
||||
## Syntax and Semantic Changes
|
||||
|
||||
Syntactic and semantic changes must be reviewed by the CEL Language Council.
|
||||
Maintainers may also request language council review at their discretion.
|
||||
|
||||
The review process is as follows:
|
||||
|
||||
- Create a Feature Request in the CEL-Spec repo. The feature description will
|
||||
serve as an abstract for the detailed design document.
|
||||
- Co-develop a design document with the Language Council.
|
||||
- Once the proposer gives the design document approval, the document will be
|
||||
linked to the FR in the CEL-Spec repo and opened for comments to members of
|
||||
the cel-lang-discuss@googlegroups.com.
|
||||
- The Language Council will review the design doc at the next council meeting
|
||||
(once every three weeks) and the council decision included in the document.
|
||||
|
||||
If the proposal is approved, the spec will be updated by a maintainer (if
|
||||
applicable) and a rationale will be included in the CEL-Spec wiki to ensure
|
||||
future developers may follow CEL's growth and direction over time.
|
||||
|
||||
Approved proposals may be implemented by the proposer or by the maintainers as
|
||||
the parties see fit. At the discretion of the maintainer, changes from the
|
||||
approved design are permitted during implementation if they improve the user
|
||||
experience and clarity of the feature.
|
||||
@@ -1,202 +0,0 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -1,13 +0,0 @@
|
||||
# CEL Language Council
|
||||
|
||||
| Name | Company | Area of Expertise |
|
||||
|-----------------|--------------|-------------------|
|
||||
| Alfred Fuller | Facebook | cel-cpp, cel-spec |
|
||||
| Jim Larson | Google | cel-go, cel-spec |
|
||||
| Matthais Blume | Google | cel-spec |
|
||||
| Tristan Swadell | Google | cel-go, cel-spec |
|
||||
|
||||
## Emeritus
|
||||
|
||||
* Sanjay Ghemawat (Google)
|
||||
* Wolfgang Grieskamp (Facebook)
|
||||
@@ -1,70 +0,0 @@
|
||||
module(
|
||||
name = "cel-spec",
|
||||
)
|
||||
|
||||
bazel_dep(
|
||||
name = "bazel_skylib",
|
||||
version = "1.7.1",
|
||||
)
|
||||
bazel_dep(
|
||||
name = "gazelle",
|
||||
version = "0.36.0",
|
||||
repo_name = "bazel_gazelle",
|
||||
)
|
||||
bazel_dep(
|
||||
name = "googleapis",
|
||||
version = "0.0.0-20240819-fe8ba054a",
|
||||
repo_name = "com_google_googleapis",
|
||||
)
|
||||
bazel_dep(
|
||||
name = "protobuf",
|
||||
version = "26.0",
|
||||
repo_name = "com_google_protobuf",
|
||||
)
|
||||
bazel_dep(
|
||||
name = "rules_cc",
|
||||
version = "0.0.9",
|
||||
)
|
||||
bazel_dep(
|
||||
name = "rules_go",
|
||||
version = "0.49.0",
|
||||
repo_name = "io_bazel_rules_go",
|
||||
)
|
||||
bazel_dep(
|
||||
name = "rules_java",
|
||||
version = "7.6.5",
|
||||
)
|
||||
bazel_dep(
|
||||
name = "rules_proto",
|
||||
version = "6.0.0",
|
||||
)
|
||||
bazel_dep(
|
||||
name = "rules_python",
|
||||
version = "0.35.0",
|
||||
)
|
||||
|
||||
### PYTHON ###
|
||||
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
|
||||
python.toolchain(
|
||||
ignore_root_user_error = True,
|
||||
python_version = "3.11",
|
||||
)
|
||||
|
||||
switched_rules = use_extension("@com_google_googleapis//:extensions.bzl", "switched_rules")
|
||||
switched_rules.use_languages(
|
||||
cc = True,
|
||||
go = True,
|
||||
java = True,
|
||||
)
|
||||
use_repo(switched_rules, "com_google_googleapis_imports")
|
||||
|
||||
go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk")
|
||||
go_sdk.download(version = "1.21.1")
|
||||
|
||||
go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps")
|
||||
go_deps.from_file(go_mod = "//:go.mod")
|
||||
use_repo(
|
||||
go_deps,
|
||||
"org_golang_google_genproto_googleapis_rpc",
|
||||
"org_golang_google_protobuf",
|
||||
)
|
||||
@@ -1,73 +0,0 @@
|
||||
# Common Expression Language
|
||||
|
||||
The Common Expression Language (CEL) implements common semantics for expression
|
||||
evaluation, enabling different applications to more easily interoperate.
|
||||
|
||||
Key Applications
|
||||
|
||||
* Security policy: organizations have complex infrastructure and need common
|
||||
tooling to reason about the system as a whole
|
||||
* Protocols: expressions are a useful data type and require interoperability
|
||||
across programming languages and platforms.
|
||||
|
||||
|
||||
Guiding philosophy:
|
||||
|
||||
1. Keep it small & fast.
|
||||
* CEL evaluates in linear time, is mutation free, and not Turing-complete.
|
||||
This limitation is a feature of the language design, which allows the
|
||||
implementation to evaluate orders of magnitude faster than equivalently
|
||||
sandboxed JavaScript.
|
||||
2. Make it extensible.
|
||||
* CEL is designed to be embedded in applications, and allows for
|
||||
extensibility via its context which allows for functions and data to be
|
||||
provided by the software that embeds it.
|
||||
3. Developer-friendly.
|
||||
* The language is approachable to developers. The initial spec was based
|
||||
on the experience of developing Firebase Rules and usability testing
|
||||
many prior iterations.
|
||||
* The library itself and accompanying toolings should be easy to adopt by
|
||||
teams that seek to integrate CEL into their platforms.
|
||||
|
||||
The required components of a system that supports CEL are:
|
||||
|
||||
* The textual representation of an expression as written by a developer. It is
|
||||
of similar syntax to expressions in C/C++/Java/JavaScript
|
||||
* A representation of the program's abstract syntax tree (AST).
|
||||
* A compiler library that converts the textual representation to the binary
|
||||
representation. This can be done ahead of time (in the control plane) or
|
||||
just before evaluation (in the data plane).
|
||||
* A context containing one or more typed variables, often protobuf messages.
|
||||
Most use-cases will use `attribute_context.proto`
|
||||
* An evaluator library that takes the binary format in the context and
|
||||
produces a result, usually a Boolean.
|
||||
|
||||
For use cases which require persistence or cross-process communcation, it is
|
||||
highly recommended to serialize the type-checked expression as a protocol
|
||||
buffer. The CEL team will maintains canonical protocol buffers for ASTs and
|
||||
will keep these versions identical and wire-compatible in perpetuity:
|
||||
|
||||
* [CEL canonical](https://github.com/google/cel-spec/tree/master/proto/cel/expr)
|
||||
* [CEL v1alpha1](https://github.com/googleapis/googleapis/tree/master/google/api/expr/v1alpha1)
|
||||
|
||||
|
||||
Example of boolean conditions and object construction:
|
||||
|
||||
``` c
|
||||
// Condition
|
||||
account.balance >= transaction.withdrawal
|
||||
|| (account.overdraftProtection
|
||||
&& account.overdraftLimit >= transaction.withdrawal - account.balance)
|
||||
|
||||
// Object construction
|
||||
common.GeoPoint{ latitude: 10.0, longitude: -5.5 }
|
||||
```
|
||||
|
||||
For more detail, see:
|
||||
|
||||
* [Introduction](doc/intro.md)
|
||||
* [Language Definition](doc/langdef.md)
|
||||
|
||||
Released under the [Apache License](LICENSE).
|
||||
|
||||
Disclaimer: This is not an official Google product.
|
||||
@@ -1,145 +0,0 @@
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "io_bazel_rules_go",
|
||||
sha256 = "099a9fb96a376ccbbb7d291ed4ecbdfd42f6bc822ab77ae6f1b5cb9e914e94fa",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.35.0/rules_go-v0.35.0.zip",
|
||||
"https://github.com/bazelbuild/rules_go/releases/download/v0.35.0/rules_go-v0.35.0.zip",
|
||||
],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "bazel_gazelle",
|
||||
sha256 = "ecba0f04f96b4960a5b250c8e8eeec42281035970aa8852dda73098274d14a1d",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "rules_proto",
|
||||
sha256 = "e017528fd1c91c5a33f15493e3a398181a9e821a804eb7ff5acdd1d2d6c2b18d",
|
||||
strip_prefix = "rules_proto-4.0.0-3.20.0",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0-3.20.0.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
# googleapis as of 09/16/2024
|
||||
http_archive(
|
||||
name = "com_google_googleapis",
|
||||
strip_prefix = "googleapis-4082d5e51e8481f6ccc384cacd896f4e78f19dee",
|
||||
sha256 = "57319889d47578b3c89bf1b3f34888d796a8913d63b32d750a4cd12ed303c4e8",
|
||||
urls = [
|
||||
"https://github.com/googleapis/googleapis/archive/4082d5e51e8481f6ccc384cacd896f4e78f19dee.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
# protobuf
|
||||
http_archive(
|
||||
name = "com_google_protobuf",
|
||||
sha256 = "8242327e5df8c80ba49e4165250b8f79a76bd11765facefaaecfca7747dc8da2",
|
||||
strip_prefix = "protobuf-3.21.5",
|
||||
urls = ["https://github.com/protocolbuffers/protobuf/archive/v3.21.5.zip"],
|
||||
)
|
||||
|
||||
# googletest
|
||||
http_archive(
|
||||
name = "com_google_googletest",
|
||||
urls = ["https://github.com/google/googletest/archive/master.zip"],
|
||||
strip_prefix = "googletest-master",
|
||||
)
|
||||
|
||||
# gflags
|
||||
http_archive(
|
||||
name = "com_github_gflags_gflags",
|
||||
sha256 = "6e16c8bc91b1310a44f3965e616383dbda48f83e8c1eaa2370a215057b00cabe",
|
||||
strip_prefix = "gflags-77592648e3f3be87d6c7123eb81cbad75f9aef5a",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/gflags/gflags/archive/77592648e3f3be87d6c7123eb81cbad75f9aef5a.tar.gz",
|
||||
"https://github.com/gflags/gflags/archive/77592648e3f3be87d6c7123eb81cbad75f9aef5a.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
# glog
|
||||
http_archive(
|
||||
name = "com_google_glog",
|
||||
sha256 = "1ee310e5d0a19b9d584a855000434bb724aa744745d5b8ab1855c85bff8a8e21",
|
||||
strip_prefix = "glog-028d37889a1e80e8a07da1b8945ac706259e5fd8",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/google/glog/archive/028d37889a1e80e8a07da1b8945ac706259e5fd8.tar.gz",
|
||||
"https://github.com/google/glog/archive/028d37889a1e80e8a07da1b8945ac706259e5fd8.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
# absl
|
||||
http_archive(
|
||||
name = "com_google_absl",
|
||||
strip_prefix = "abseil-cpp-master",
|
||||
urls = ["https://github.com/abseil/abseil-cpp/archive/master.zip"],
|
||||
)
|
||||
|
||||
load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
|
||||
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
|
||||
load("@com_google_googleapis//:repository_rules.bzl", "switched_rules_by_language")
|
||||
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
|
||||
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
|
||||
|
||||
switched_rules_by_language(
|
||||
name = "com_google_googleapis_imports",
|
||||
cc = True,
|
||||
)
|
||||
|
||||
# Do *not* call *_dependencies(), etc, yet. See comment at the end.
|
||||
|
||||
# Generated Google APIs protos for Golang
|
||||
# Generated Google APIs protos for Golang 08/26/2024
|
||||
go_repository(
|
||||
name = "org_golang_google_genproto_googleapis_api",
|
||||
build_file_proto_mode = "disable_global",
|
||||
importpath = "google.golang.org/genproto/googleapis/api",
|
||||
sum = "h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw=",
|
||||
version = "v0.0.0-20240826202546-f6391c0de4c7",
|
||||
)
|
||||
|
||||
# Generated Google APIs protos for Golang 08/26/2024
|
||||
go_repository(
|
||||
name = "org_golang_google_genproto_googleapis_rpc",
|
||||
build_file_proto_mode = "disable_global",
|
||||
importpath = "google.golang.org/genproto/googleapis/rpc",
|
||||
sum = "h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs=",
|
||||
version = "v0.0.0-20240826202546-f6391c0de4c7",
|
||||
)
|
||||
|
||||
# gRPC deps
|
||||
go_repository(
|
||||
name = "org_golang_google_grpc",
|
||||
build_file_proto_mode = "disable_global",
|
||||
importpath = "google.golang.org/grpc",
|
||||
tag = "v1.49.0",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "org_golang_x_net",
|
||||
importpath = "golang.org/x/net",
|
||||
sum = "h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=",
|
||||
version = "v0.0.0-20190311183353-d8887717615a",
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "org_golang_x_text",
|
||||
importpath = "golang.org/x/text",
|
||||
sum = "h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=",
|
||||
version = "v0.3.2",
|
||||
)
|
||||
|
||||
# Run the dependencies at the end. These will silently try to import some
|
||||
# of the above repositories but at different versions, so ours must come first.
|
||||
go_rules_dependencies()
|
||||
go_register_toolchains(version = "1.19.1")
|
||||
gazelle_dependencies()
|
||||
rules_proto_dependencies()
|
||||
rules_proto_toolchains()
|
||||
protobuf_deps()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,9 +0,0 @@
|
||||
steps:
|
||||
- name: 'gcr.io/cloud-builders/bazel:7.0.1'
|
||||
entrypoint: bazel
|
||||
args: ['build', '...']
|
||||
id: bazel-build
|
||||
waitFor: ['-']
|
||||
timeout: 15m
|
||||
options:
|
||||
machineType: 'N1_HIGHCPU_32'
|
||||
@@ -1,490 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc v3.21.5
|
||||
// source: cel/expr/eval.proto
|
||||
|
||||
package expr
|
||||
|
||||
import (
|
||||
status "google.golang.org/genproto/googleapis/rpc/status"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type EvalState struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Values []*ExprValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
|
||||
Results []*EvalState_Result `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"`
|
||||
}
|
||||
|
||||
func (x *EvalState) Reset() {
|
||||
*x = EvalState{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_cel_expr_eval_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EvalState) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EvalState) ProtoMessage() {}
|
||||
|
||||
func (x *EvalState) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_cel_expr_eval_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EvalState.ProtoReflect.Descriptor instead.
|
||||
func (*EvalState) Descriptor() ([]byte, []int) {
|
||||
return file_cel_expr_eval_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *EvalState) GetValues() []*ExprValue {
|
||||
if x != nil {
|
||||
return x.Values
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *EvalState) GetResults() []*EvalState_Result {
|
||||
if x != nil {
|
||||
return x.Results
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ExprValue struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Types that are assignable to Kind:
|
||||
//
|
||||
// *ExprValue_Value
|
||||
// *ExprValue_Error
|
||||
// *ExprValue_Unknown
|
||||
Kind isExprValue_Kind `protobuf_oneof:"kind"`
|
||||
}
|
||||
|
||||
func (x *ExprValue) Reset() {
|
||||
*x = ExprValue{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_cel_expr_eval_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ExprValue) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ExprValue) ProtoMessage() {}
|
||||
|
||||
func (x *ExprValue) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_cel_expr_eval_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ExprValue.ProtoReflect.Descriptor instead.
|
||||
func (*ExprValue) Descriptor() ([]byte, []int) {
|
||||
return file_cel_expr_eval_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (m *ExprValue) GetKind() isExprValue_Kind {
|
||||
if m != nil {
|
||||
return m.Kind
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExprValue) GetValue() *Value {
|
||||
if x, ok := x.GetKind().(*ExprValue_Value); ok {
|
||||
return x.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExprValue) GetError() *ErrorSet {
|
||||
if x, ok := x.GetKind().(*ExprValue_Error); ok {
|
||||
return x.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ExprValue) GetUnknown() *UnknownSet {
|
||||
if x, ok := x.GetKind().(*ExprValue_Unknown); ok {
|
||||
return x.Unknown
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isExprValue_Kind interface {
|
||||
isExprValue_Kind()
|
||||
}
|
||||
|
||||
type ExprValue_Value struct {
|
||||
Value *Value `protobuf:"bytes,1,opt,name=value,proto3,oneof"`
|
||||
}
|
||||
|
||||
type ExprValue_Error struct {
|
||||
Error *ErrorSet `protobuf:"bytes,2,opt,name=error,proto3,oneof"`
|
||||
}
|
||||
|
||||
type ExprValue_Unknown struct {
|
||||
Unknown *UnknownSet `protobuf:"bytes,3,opt,name=unknown,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*ExprValue_Value) isExprValue_Kind() {}
|
||||
|
||||
func (*ExprValue_Error) isExprValue_Kind() {}
|
||||
|
||||
func (*ExprValue_Unknown) isExprValue_Kind() {}
|
||||
|
||||
type ErrorSet struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Errors []*status.Status `protobuf:"bytes,1,rep,name=errors,proto3" json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ErrorSet) Reset() {
|
||||
*x = ErrorSet{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_cel_expr_eval_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ErrorSet) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ErrorSet) ProtoMessage() {}
|
||||
|
||||
func (x *ErrorSet) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_cel_expr_eval_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ErrorSet.ProtoReflect.Descriptor instead.
|
||||
func (*ErrorSet) Descriptor() ([]byte, []int) {
|
||||
return file_cel_expr_eval_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ErrorSet) GetErrors() []*status.Status {
|
||||
if x != nil {
|
||||
return x.Errors
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type UnknownSet struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Exprs []int64 `protobuf:"varint,1,rep,packed,name=exprs,proto3" json:"exprs,omitempty"`
|
||||
}
|
||||
|
||||
func (x *UnknownSet) Reset() {
|
||||
*x = UnknownSet{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_cel_expr_eval_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *UnknownSet) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UnknownSet) ProtoMessage() {}
|
||||
|
||||
func (x *UnknownSet) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_cel_expr_eval_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UnknownSet.ProtoReflect.Descriptor instead.
|
||||
func (*UnknownSet) Descriptor() ([]byte, []int) {
|
||||
return file_cel_expr_eval_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *UnknownSet) GetExprs() []int64 {
|
||||
if x != nil {
|
||||
return x.Exprs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type EvalState_Result struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Expr int64 `protobuf:"varint,1,opt,name=expr,proto3" json:"expr,omitempty"`
|
||||
Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (x *EvalState_Result) Reset() {
|
||||
*x = EvalState_Result{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_cel_expr_eval_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EvalState_Result) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EvalState_Result) ProtoMessage() {}
|
||||
|
||||
func (x *EvalState_Result) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_cel_expr_eval_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EvalState_Result.ProtoReflect.Descriptor instead.
|
||||
func (*EvalState_Result) Descriptor() ([]byte, []int) {
|
||||
return file_cel_expr_eval_proto_rawDescGZIP(), []int{0, 0}
|
||||
}
|
||||
|
||||
func (x *EvalState_Result) GetExpr() int64 {
|
||||
if x != nil {
|
||||
return x.Expr
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *EvalState_Result) GetValue() int64 {
|
||||
if x != nil {
|
||||
return x.Value
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_cel_expr_eval_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_cel_expr_eval_proto_rawDesc = []byte{
|
||||
0x0a, 0x13, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x65, 0x76, 0x61, 0x6c, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x1a,
|
||||
0x14, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x72, 0x70,
|
||||
0x63, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa2,
|
||||
0x01, 0x0a, 0x09, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2b, 0x0a, 0x06,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63,
|
||||
0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73,
|
||||
0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x65, 0x6c,
|
||||
0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e,
|
||||
0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a,
|
||||
0x32, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70,
|
||||
0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x14, 0x0a,
|
||||
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x65, 0x72,
|
||||
0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c, 0x2e,
|
||||
0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52,
|
||||
0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x30, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
|
||||
0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78,
|
||||
0x70, 0x72, 0x2e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52,
|
||||
0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64,
|
||||
0x22, 0x36, 0x0a, 0x08, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x12, 0x2a, 0x0a, 0x06,
|
||||
0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67,
|
||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x22, 0x0a, 0x0a, 0x55, 0x6e, 0x6b, 0x6e,
|
||||
0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x70, 0x72, 0x73, 0x18,
|
||||
0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x05, 0x65, 0x78, 0x70, 0x72, 0x73, 0x42, 0x2c, 0x0a, 0x0c,
|
||||
0x64, 0x65, 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x09, 0x45, 0x76,
|
||||
0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64,
|
||||
0x65, 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_cel_expr_eval_proto_rawDescOnce sync.Once
|
||||
file_cel_expr_eval_proto_rawDescData = file_cel_expr_eval_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_cel_expr_eval_proto_rawDescGZIP() []byte {
|
||||
file_cel_expr_eval_proto_rawDescOnce.Do(func() {
|
||||
file_cel_expr_eval_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_eval_proto_rawDescData)
|
||||
})
|
||||
return file_cel_expr_eval_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_cel_expr_eval_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_cel_expr_eval_proto_goTypes = []interface{}{
|
||||
(*EvalState)(nil), // 0: cel.expr.EvalState
|
||||
(*ExprValue)(nil), // 1: cel.expr.ExprValue
|
||||
(*ErrorSet)(nil), // 2: cel.expr.ErrorSet
|
||||
(*UnknownSet)(nil), // 3: cel.expr.UnknownSet
|
||||
(*EvalState_Result)(nil), // 4: cel.expr.EvalState.Result
|
||||
(*Value)(nil), // 5: cel.expr.Value
|
||||
(*status.Status)(nil), // 6: google.rpc.Status
|
||||
}
|
||||
var file_cel_expr_eval_proto_depIdxs = []int32{
|
||||
1, // 0: cel.expr.EvalState.values:type_name -> cel.expr.ExprValue
|
||||
4, // 1: cel.expr.EvalState.results:type_name -> cel.expr.EvalState.Result
|
||||
5, // 2: cel.expr.ExprValue.value:type_name -> cel.expr.Value
|
||||
2, // 3: cel.expr.ExprValue.error:type_name -> cel.expr.ErrorSet
|
||||
3, // 4: cel.expr.ExprValue.unknown:type_name -> cel.expr.UnknownSet
|
||||
6, // 5: cel.expr.ErrorSet.errors:type_name -> google.rpc.Status
|
||||
6, // [6:6] is the sub-list for method output_type
|
||||
6, // [6:6] is the sub-list for method input_type
|
||||
6, // [6:6] is the sub-list for extension type_name
|
||||
6, // [6:6] is the sub-list for extension extendee
|
||||
0, // [0:6] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_cel_expr_eval_proto_init() }
|
||||
func file_cel_expr_eval_proto_init() {
|
||||
if File_cel_expr_eval_proto != nil {
|
||||
return
|
||||
}
|
||||
file_cel_expr_value_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_cel_expr_eval_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EvalState); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_cel_expr_eval_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ExprValue); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_cel_expr_eval_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ErrorSet); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_cel_expr_eval_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*UnknownSet); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_cel_expr_eval_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EvalState_Result); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_cel_expr_eval_proto_msgTypes[1].OneofWrappers = []interface{}{
|
||||
(*ExprValue_Value)(nil),
|
||||
(*ExprValue_Error)(nil),
|
||||
(*ExprValue_Unknown)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_cel_expr_eval_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 5,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_cel_expr_eval_proto_goTypes,
|
||||
DependencyIndexes: file_cel_expr_eval_proto_depIdxs,
|
||||
MessageInfos: file_cel_expr_eval_proto_msgTypes,
|
||||
}.Build()
|
||||
File_cel_expr_eval_proto = out.File
|
||||
file_cel_expr_eval_proto_rawDesc = nil
|
||||
file_cel_expr_eval_proto_goTypes = nil
|
||||
file_cel_expr_eval_proto_depIdxs = nil
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc v3.21.5
|
||||
// source: cel/expr/explain.proto
|
||||
|
||||
package expr
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// Deprecated: Do not use.
|
||||
type Explain struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
|
||||
ExprSteps []*Explain_ExprStep `protobuf:"bytes,2,rep,name=expr_steps,json=exprSteps,proto3" json:"expr_steps,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Explain) Reset() {
|
||||
*x = Explain{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_cel_expr_explain_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Explain) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Explain) ProtoMessage() {}
|
||||
|
||||
func (x *Explain) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_cel_expr_explain_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Explain.ProtoReflect.Descriptor instead.
|
||||
func (*Explain) Descriptor() ([]byte, []int) {
|
||||
return file_cel_expr_explain_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Explain) GetValues() []*Value {
|
||||
if x != nil {
|
||||
return x.Values
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Explain) GetExprSteps() []*Explain_ExprStep {
|
||||
if x != nil {
|
||||
return x.ExprSteps
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Explain_ExprStep struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
ValueIndex int32 `protobuf:"varint,2,opt,name=value_index,json=valueIndex,proto3" json:"value_index,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Explain_ExprStep) Reset() {
|
||||
*x = Explain_ExprStep{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_cel_expr_explain_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Explain_ExprStep) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Explain_ExprStep) ProtoMessage() {}
|
||||
|
||||
func (x *Explain_ExprStep) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_cel_expr_explain_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Explain_ExprStep.ProtoReflect.Descriptor instead.
|
||||
func (*Explain_ExprStep) Descriptor() ([]byte, []int) {
|
||||
return file_cel_expr_explain_proto_rawDescGZIP(), []int{0, 0}
|
||||
}
|
||||
|
||||
func (x *Explain_ExprStep) GetId() int64 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Explain_ExprStep) GetValueIndex() int32 {
|
||||
if x != nil {
|
||||
return x.ValueIndex
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_cel_expr_explain_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_cel_expr_explain_proto_rawDesc = []byte{
|
||||
0x0a, 0x16, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x65, 0x78, 0x70, 0x6c, 0x61,
|
||||
0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78,
|
||||
0x70, 0x72, 0x1a, 0x14, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xae, 0x01, 0x0a, 0x07, 0x45, 0x78, 0x70,
|
||||
0x6c, 0x61, 0x69, 0x6e, 0x12, 0x27, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e,
|
||||
0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x39, 0x0a,
|
||||
0x0a, 0x65, 0x78, 0x70, 0x72, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70,
|
||||
0x6c, 0x61, 0x69, 0x6e, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x53, 0x74, 0x65, 0x70, 0x52, 0x09, 0x65,
|
||||
0x78, 0x70, 0x72, 0x53, 0x74, 0x65, 0x70, 0x73, 0x1a, 0x3b, 0x0a, 0x08, 0x45, 0x78, 0x70, 0x72,
|
||||
0x53, 0x74, 0x65, 0x70, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x69, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x49, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x02, 0x18, 0x01, 0x42, 0x2f, 0x0a, 0x0c, 0x64, 0x65, 0x76,
|
||||
0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0c, 0x45, 0x78, 0x70, 0x6c, 0x61,
|
||||
0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64,
|
||||
0x65, 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_cel_expr_explain_proto_rawDescOnce sync.Once
|
||||
file_cel_expr_explain_proto_rawDescData = file_cel_expr_explain_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_cel_expr_explain_proto_rawDescGZIP() []byte {
|
||||
file_cel_expr_explain_proto_rawDescOnce.Do(func() {
|
||||
file_cel_expr_explain_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_explain_proto_rawDescData)
|
||||
})
|
||||
return file_cel_expr_explain_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_cel_expr_explain_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_cel_expr_explain_proto_goTypes = []interface{}{
|
||||
(*Explain)(nil), // 0: cel.expr.Explain
|
||||
(*Explain_ExprStep)(nil), // 1: cel.expr.Explain.ExprStep
|
||||
(*Value)(nil), // 2: cel.expr.Value
|
||||
}
|
||||
var file_cel_expr_explain_proto_depIdxs = []int32{
|
||||
2, // 0: cel.expr.Explain.values:type_name -> cel.expr.Value
|
||||
1, // 1: cel.expr.Explain.expr_steps:type_name -> cel.expr.Explain.ExprStep
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_cel_expr_explain_proto_init() }
|
||||
func file_cel_expr_explain_proto_init() {
|
||||
if File_cel_expr_explain_proto != nil {
|
||||
return
|
||||
}
|
||||
file_cel_expr_value_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_cel_expr_explain_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Explain); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_cel_expr_explain_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Explain_ExprStep); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_cel_expr_explain_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_cel_expr_explain_proto_goTypes,
|
||||
DependencyIndexes: file_cel_expr_explain_proto_depIdxs,
|
||||
MessageInfos: file_cel_expr_explain_proto_msgTypes,
|
||||
}.Build()
|
||||
File_cel_expr_explain_proto = out.File
|
||||
file_cel_expr_explain_proto_rawDesc = nil
|
||||
file_cel_expr_explain_proto_goTypes = nil
|
||||
file_cel_expr_explain_proto_depIdxs = nil
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
bazel build //proto/cel/expr/conformance/...
|
||||
files=($(bazel aquery 'kind(proto, //proto/cel/expr/conformance/...)' | grep Outputs | grep "[.]pb[.]go" | sed 's/Outputs: \[//' | sed 's/\]//' | tr "," "\n"))
|
||||
for src in ${files[@]};
|
||||
do
|
||||
dst=$(echo $src | sed 's/\(.*\/cel.dev\/expr\/\(.*\)\)/\2/')
|
||||
echo "copying $dst"
|
||||
$(cp $src $dst)
|
||||
done
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
bazel build //proto/cel/expr:all
|
||||
|
||||
rm -vf ./*.pb.go
|
||||
|
||||
files=( $(bazel cquery //proto/cel/expr:expr_go_proto --output=starlark --starlark:expr="'\n'.join([f.path for f in target.output_groups.go_generated_srcs.to_list()])") )
|
||||
for src in "${files[@]}";
|
||||
do
|
||||
cp -v "${src}" ./
|
||||
done
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,653 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc v3.21.5
|
||||
// source: cel/expr/value.proto
|
||||
|
||||
package expr
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Value struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
// Types that are assignable to Kind:
|
||||
//
|
||||
// *Value_NullValue
|
||||
// *Value_BoolValue
|
||||
// *Value_Int64Value
|
||||
// *Value_Uint64Value
|
||||
// *Value_DoubleValue
|
||||
// *Value_StringValue
|
||||
// *Value_BytesValue
|
||||
// *Value_EnumValue
|
||||
// *Value_ObjectValue
|
||||
// *Value_MapValue
|
||||
// *Value_ListValue
|
||||
// *Value_TypeValue
|
||||
Kind isValue_Kind `protobuf_oneof:"kind"`
|
||||
}
|
||||
|
||||
func (x *Value) Reset() {
|
||||
*x = Value{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_cel_expr_value_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Value) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Value) ProtoMessage() {}
|
||||
|
||||
func (x *Value) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_cel_expr_value_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Value.ProtoReflect.Descriptor instead.
|
||||
func (*Value) Descriptor() ([]byte, []int) {
|
||||
return file_cel_expr_value_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (m *Value) GetKind() isValue_Kind {
|
||||
if m != nil {
|
||||
return m.Kind
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Value) GetNullValue() structpb.NullValue {
|
||||
if x, ok := x.GetKind().(*Value_NullValue); ok {
|
||||
return x.NullValue
|
||||
}
|
||||
return structpb.NullValue(0)
|
||||
}
|
||||
|
||||
func (x *Value) GetBoolValue() bool {
|
||||
if x, ok := x.GetKind().(*Value_BoolValue); ok {
|
||||
return x.BoolValue
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Value) GetInt64Value() int64 {
|
||||
if x, ok := x.GetKind().(*Value_Int64Value); ok {
|
||||
return x.Int64Value
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Value) GetUint64Value() uint64 {
|
||||
if x, ok := x.GetKind().(*Value_Uint64Value); ok {
|
||||
return x.Uint64Value
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Value) GetDoubleValue() float64 {
|
||||
if x, ok := x.GetKind().(*Value_DoubleValue); ok {
|
||||
return x.DoubleValue
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Value) GetStringValue() string {
|
||||
if x, ok := x.GetKind().(*Value_StringValue); ok {
|
||||
return x.StringValue
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Value) GetBytesValue() []byte {
|
||||
if x, ok := x.GetKind().(*Value_BytesValue); ok {
|
||||
return x.BytesValue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Value) GetEnumValue() *EnumValue {
|
||||
if x, ok := x.GetKind().(*Value_EnumValue); ok {
|
||||
return x.EnumValue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Value) GetObjectValue() *anypb.Any {
|
||||
if x, ok := x.GetKind().(*Value_ObjectValue); ok {
|
||||
return x.ObjectValue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Value) GetMapValue() *MapValue {
|
||||
if x, ok := x.GetKind().(*Value_MapValue); ok {
|
||||
return x.MapValue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Value) GetListValue() *ListValue {
|
||||
if x, ok := x.GetKind().(*Value_ListValue); ok {
|
||||
return x.ListValue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Value) GetTypeValue() string {
|
||||
if x, ok := x.GetKind().(*Value_TypeValue); ok {
|
||||
return x.TypeValue
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type isValue_Kind interface {
|
||||
isValue_Kind()
|
||||
}
|
||||
|
||||
type Value_NullValue struct {
|
||||
NullValue structpb.NullValue `protobuf:"varint,1,opt,name=null_value,json=nullValue,proto3,enum=google.protobuf.NullValue,oneof"`
|
||||
}
|
||||
|
||||
type Value_BoolValue struct {
|
||||
BoolValue bool `protobuf:"varint,2,opt,name=bool_value,json=boolValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Value_Int64Value struct {
|
||||
Int64Value int64 `protobuf:"varint,3,opt,name=int64_value,json=int64Value,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Value_Uint64Value struct {
|
||||
Uint64Value uint64 `protobuf:"varint,4,opt,name=uint64_value,json=uint64Value,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Value_DoubleValue struct {
|
||||
DoubleValue float64 `protobuf:"fixed64,5,opt,name=double_value,json=doubleValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Value_StringValue struct {
|
||||
StringValue string `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Value_BytesValue struct {
|
||||
BytesValue []byte `protobuf:"bytes,7,opt,name=bytes_value,json=bytesValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Value_EnumValue struct {
|
||||
EnumValue *EnumValue `protobuf:"bytes,9,opt,name=enum_value,json=enumValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Value_ObjectValue struct {
|
||||
ObjectValue *anypb.Any `protobuf:"bytes,10,opt,name=object_value,json=objectValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Value_MapValue struct {
|
||||
MapValue *MapValue `protobuf:"bytes,11,opt,name=map_value,json=mapValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Value_ListValue struct {
|
||||
ListValue *ListValue `protobuf:"bytes,12,opt,name=list_value,json=listValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Value_TypeValue struct {
|
||||
TypeValue string `protobuf:"bytes,15,opt,name=type_value,json=typeValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*Value_NullValue) isValue_Kind() {}
|
||||
|
||||
func (*Value_BoolValue) isValue_Kind() {}
|
||||
|
||||
func (*Value_Int64Value) isValue_Kind() {}
|
||||
|
||||
func (*Value_Uint64Value) isValue_Kind() {}
|
||||
|
||||
func (*Value_DoubleValue) isValue_Kind() {}
|
||||
|
||||
func (*Value_StringValue) isValue_Kind() {}
|
||||
|
||||
func (*Value_BytesValue) isValue_Kind() {}
|
||||
|
||||
func (*Value_EnumValue) isValue_Kind() {}
|
||||
|
||||
func (*Value_ObjectValue) isValue_Kind() {}
|
||||
|
||||
func (*Value_MapValue) isValue_Kind() {}
|
||||
|
||||
func (*Value_ListValue) isValue_Kind() {}
|
||||
|
||||
func (*Value_TypeValue) isValue_Kind() {}
|
||||
|
||||
type EnumValue struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
|
||||
Value int32 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (x *EnumValue) Reset() {
|
||||
*x = EnumValue{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_cel_expr_value_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *EnumValue) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EnumValue) ProtoMessage() {}
|
||||
|
||||
func (x *EnumValue) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_cel_expr_value_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EnumValue.ProtoReflect.Descriptor instead.
|
||||
func (*EnumValue) Descriptor() ([]byte, []int) {
|
||||
return file_cel_expr_value_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *EnumValue) GetType() string {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EnumValue) GetValue() int32 {
|
||||
if x != nil {
|
||||
return x.Value
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ListValue struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ListValue) Reset() {
|
||||
*x = ListValue{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_cel_expr_value_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListValue) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListValue) ProtoMessage() {}
|
||||
|
||||
func (x *ListValue) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_cel_expr_value_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListValue.ProtoReflect.Descriptor instead.
|
||||
func (*ListValue) Descriptor() ([]byte, []int) {
|
||||
return file_cel_expr_value_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ListValue) GetValues() []*Value {
|
||||
if x != nil {
|
||||
return x.Values
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MapValue struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Entries []*MapValue_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"`
|
||||
}
|
||||
|
||||
func (x *MapValue) Reset() {
|
||||
*x = MapValue{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_cel_expr_value_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MapValue) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MapValue) ProtoMessage() {}
|
||||
|
||||
func (x *MapValue) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_cel_expr_value_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use MapValue.ProtoReflect.Descriptor instead.
|
||||
func (*MapValue) Descriptor() ([]byte, []int) {
|
||||
return file_cel_expr_value_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *MapValue) GetEntries() []*MapValue_Entry {
|
||||
if x != nil {
|
||||
return x.Entries
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MapValue_Entry struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Key *Value `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
||||
Value *Value `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (x *MapValue_Entry) Reset() {
|
||||
*x = MapValue_Entry{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_cel_expr_value_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *MapValue_Entry) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*MapValue_Entry) ProtoMessage() {}
|
||||
|
||||
func (x *MapValue_Entry) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_cel_expr_value_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use MapValue_Entry.ProtoReflect.Descriptor instead.
|
||||
func (*MapValue_Entry) Descriptor() ([]byte, []int) {
|
||||
return file_cel_expr_value_proto_rawDescGZIP(), []int{3, 0}
|
||||
}
|
||||
|
||||
func (x *MapValue_Entry) GetKey() *Value {
|
||||
if x != nil {
|
||||
return x.Key
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *MapValue_Entry) GetValue() *Value {
|
||||
if x != nil {
|
||||
return x.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var File_cel_expr_value_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_cel_expr_value_proto_rawDesc = []byte{
|
||||
0x0a, 0x14, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72,
|
||||
0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72,
|
||||
0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9d, 0x04, 0x0a, 0x05, 0x56, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x6e, 0x75, 0x6c, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4e, 0x75, 0x6c, 0x6c, 0x56, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6e, 0x75, 0x6c, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x12, 0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x0b, 0x75, 0x69,
|
||||
0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x64, 0x6f, 0x75,
|
||||
0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x48,
|
||||
0x00, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23,
|
||||
0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x76, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65,
|
||||
0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x65, 0x6c,
|
||||
0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48,
|
||||
0x00, 0x52, 0x09, 0x65, 0x6e, 0x75, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x39, 0x0a, 0x0c,
|
||||
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0a, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x48, 0x00, 0x52, 0x0b, 0x6f, 0x62, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x6d, 0x61, 0x70, 0x5f, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c,
|
||||
0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x48, 0x00,
|
||||
0x52, 0x08, 0x6d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x0a, 0x0a, 0x6c, 0x69,
|
||||
0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13,
|
||||
0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x12, 0x1f, 0x0a, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0f,
|
||||
0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x74, 0x79, 0x70, 0x65, 0x56, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0x35, 0x0a, 0x09, 0x45, 0x6e, 0x75,
|
||||
0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x22, 0x34, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x27, 0x0a,
|
||||
0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e,
|
||||
0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x08, 0x4d, 0x61, 0x70, 0x56, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e,
|
||||
0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07,
|
||||
0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x51, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x12, 0x21, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e,
|
||||
0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x12, 0x25, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x2d, 0x0a, 0x0c, 0x64, 0x65,
|
||||
0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x0a, 0x56, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, 0x65,
|
||||
0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_cel_expr_value_proto_rawDescOnce sync.Once
|
||||
file_cel_expr_value_proto_rawDescData = file_cel_expr_value_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_cel_expr_value_proto_rawDescGZIP() []byte {
|
||||
file_cel_expr_value_proto_rawDescOnce.Do(func() {
|
||||
file_cel_expr_value_proto_rawDescData = protoimpl.X.CompressGZIP(file_cel_expr_value_proto_rawDescData)
|
||||
})
|
||||
return file_cel_expr_value_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_cel_expr_value_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_cel_expr_value_proto_goTypes = []interface{}{
|
||||
(*Value)(nil), // 0: cel.expr.Value
|
||||
(*EnumValue)(nil), // 1: cel.expr.EnumValue
|
||||
(*ListValue)(nil), // 2: cel.expr.ListValue
|
||||
(*MapValue)(nil), // 3: cel.expr.MapValue
|
||||
(*MapValue_Entry)(nil), // 4: cel.expr.MapValue.Entry
|
||||
(structpb.NullValue)(0), // 5: google.protobuf.NullValue
|
||||
(*anypb.Any)(nil), // 6: google.protobuf.Any
|
||||
}
|
||||
var file_cel_expr_value_proto_depIdxs = []int32{
|
||||
5, // 0: cel.expr.Value.null_value:type_name -> google.protobuf.NullValue
|
||||
1, // 1: cel.expr.Value.enum_value:type_name -> cel.expr.EnumValue
|
||||
6, // 2: cel.expr.Value.object_value:type_name -> google.protobuf.Any
|
||||
3, // 3: cel.expr.Value.map_value:type_name -> cel.expr.MapValue
|
||||
2, // 4: cel.expr.Value.list_value:type_name -> cel.expr.ListValue
|
||||
0, // 5: cel.expr.ListValue.values:type_name -> cel.expr.Value
|
||||
4, // 6: cel.expr.MapValue.entries:type_name -> cel.expr.MapValue.Entry
|
||||
0, // 7: cel.expr.MapValue.Entry.key:type_name -> cel.expr.Value
|
||||
0, // 8: cel.expr.MapValue.Entry.value:type_name -> cel.expr.Value
|
||||
9, // [9:9] is the sub-list for method output_type
|
||||
9, // [9:9] is the sub-list for method input_type
|
||||
9, // [9:9] is the sub-list for extension type_name
|
||||
9, // [9:9] is the sub-list for extension extendee
|
||||
0, // [0:9] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_cel_expr_value_proto_init() }
|
||||
func file_cel_expr_value_proto_init() {
|
||||
if File_cel_expr_value_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_cel_expr_value_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Value); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_cel_expr_value_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*EnumValue); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_cel_expr_value_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListValue); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_cel_expr_value_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MapValue); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_cel_expr_value_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MapValue_Entry); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_cel_expr_value_proto_msgTypes[0].OneofWrappers = []interface{}{
|
||||
(*Value_NullValue)(nil),
|
||||
(*Value_BoolValue)(nil),
|
||||
(*Value_Int64Value)(nil),
|
||||
(*Value_Uint64Value)(nil),
|
||||
(*Value_DoubleValue)(nil),
|
||||
(*Value_StringValue)(nil),
|
||||
(*Value_BytesValue)(nil),
|
||||
(*Value_EnumValue)(nil),
|
||||
(*Value_ObjectValue)(nil),
|
||||
(*Value_MapValue)(nil),
|
||||
(*Value_ListValue)(nil),
|
||||
(*Value_TypeValue)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_cel_expr_value_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 5,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_cel_expr_value_proto_goTypes,
|
||||
DependencyIndexes: file_cel_expr_value_proto_depIdxs,
|
||||
MessageInfos: file_cel_expr_value_proto_msgTypes,
|
||||
}.Build()
|
||||
File_cel_expr_value_proto = out.File
|
||||
file_cel_expr_value_proto_rawDesc = nil
|
||||
file_cel_expr_value_proto_goTypes = nil
|
||||
file_cel_expr_value_proto_depIdxs = nil
|
||||
}
|
||||
21
cluster-api/providers/azurestack/vendor/github.com/Azure/azure-sdk-for-go/LICENSE.txt
generated
vendored
21
cluster-api/providers/azurestack/vendor/github.com/Azure/azure-sdk-for-go/LICENSE.txt
generated
vendored
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
29
cluster-api/providers/azurestack/vendor/github.com/Azure/azure-sdk-for-go/NOTICE.txt
generated
vendored
29
cluster-api/providers/azurestack/vendor/github.com/Azure/azure-sdk-for-go/NOTICE.txt
generated
vendored
@@ -1,29 +0,0 @@
|
||||
NOTICES AND INFORMATION
|
||||
Do Not Translate or Localize
|
||||
|
||||
This software incorporates material from third parties. Microsoft makes certain
|
||||
open source code available at https://3rdpartysource.microsoft.com, or you may
|
||||
send a check or money order for US $5.00, including the product name, the open
|
||||
source component name, and version number, to:
|
||||
|
||||
Source Code Compliance Team
|
||||
Microsoft Corporation
|
||||
One Microsoft Way
|
||||
Redmond, WA 98052
|
||||
USA
|
||||
|
||||
Notwithstanding any other terms, you may reverse engineer this software to the
|
||||
extent required to debug changes to any libraries licensed under the GNU Lesser
|
||||
General Public License.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Azure SDK for Go uses third-party libraries or other resources that may be
|
||||
distributed under licenses different than the Azure SDK for Go software.
|
||||
|
||||
In the event that we accidentally failed to list a required notice, please
|
||||
bring it to our attention. Post an issue or email us:
|
||||
|
||||
azgosdkhelp@microsoft.com
|
||||
|
||||
The attached notices are provided for information only.
|
||||
@@ -1,849 +0,0 @@
|
||||
# Release History
|
||||
|
||||
## 1.17.0 (2025-01-07)
|
||||
|
||||
### Features Added
|
||||
|
||||
* Added field `OperationLocationResultPath` to `runtime.NewPollerOptions[T]` for LROs that use the `Operation-Location` pattern.
|
||||
* Support `encoding.TextMarshaler` and `encoding.TextUnmarshaler` interfaces in `arm.ResourceID`.
|
||||
|
||||
## 1.16.0 (2024-10-17)
|
||||
|
||||
### Features Added
|
||||
|
||||
* Added field `Kind` to `runtime.StartSpanOptions` to allow a kind to be set when starting a span.
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* `BearerTokenPolicy` now rewinds request bodies before retrying
|
||||
|
||||
## 1.15.0 (2024-10-14)
|
||||
|
||||
### Features Added
|
||||
|
||||
* `BearerTokenPolicy` handles CAE claims challenges
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* Omit the `ResponseError.RawResponse` field from JSON marshaling so instances can be marshaled.
|
||||
* Fixed an integer overflow in the retry policy.
|
||||
|
||||
### Other Changes
|
||||
|
||||
* Update dependencies.
|
||||
|
||||
## 1.14.0 (2024-08-07)
|
||||
|
||||
### Features Added
|
||||
|
||||
* Added field `Attributes` to `runtime.StartSpanOptions` to simplify creating spans with attributes.
|
||||
|
||||
### Other Changes
|
||||
|
||||
* Include the HTTP verb and URL in `log.EventRetryPolicy` log entries so it's clear which operation is being retried.
|
||||
|
||||
## 1.13.0 (2024-07-16)
|
||||
|
||||
### Features Added
|
||||
|
||||
- Added runtime.NewRequestFromRequest(), allowing for a policy.Request to be created from an existing *http.Request.
|
||||
|
||||
## 1.12.0 (2024-06-06)
|
||||
|
||||
### Features Added
|
||||
|
||||
* Added field `StatusCodes` to `runtime.FetcherForNextLinkOptions` allowing for additional HTTP status codes indicating success.
|
||||
* Added func `NewUUID` to the `runtime` package for generating UUIDs.
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* Fixed an issue that prevented pollers using the `Operation-Location` strategy from unmarshaling the final result in some cases.
|
||||
|
||||
### Other Changes
|
||||
|
||||
* Updated dependencies.
|
||||
|
||||
## 1.11.1 (2024-04-02)
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* Pollers that use the `Location` header won't consider `http.StatusRequestTimeout` a terminal failure.
|
||||
* `runtime.Poller[T].Result` won't consider non-terminal error responses as terminal.
|
||||
|
||||
## 1.11.0 (2024-04-01)
|
||||
|
||||
### Features Added
|
||||
|
||||
* Added `StatusCodes` to `arm/policy.RegistrationOptions` to allow supporting non-standard HTTP status codes during registration.
|
||||
* Added field `InsecureAllowCredentialWithHTTP` to `azcore.ClientOptions` and dependent authentication pipeline policies.
|
||||
* Added type `MultipartContent` to the `streaming` package to support multipart/form payloads with custom Content-Type and file name.
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* `runtime.SetMultipartFormData` won't try to stringify `[]byte` values.
|
||||
* Pollers that use the `Location` header won't consider `http.StatusTooManyRequests` a terminal failure.
|
||||
|
||||
### Other Changes
|
||||
|
||||
* Update dependencies.
|
||||
|
||||
## 1.10.0 (2024-02-29)
|
||||
|
||||
### Features Added
|
||||
|
||||
* Added logging event `log.EventResponseError` that will contain the contents of `ResponseError.Error()` whenever an `azcore.ResponseError` is created.
|
||||
* Added `runtime.NewResponseErrorWithErrorCode` for creating an `azcore.ResponseError` with a caller-supplied error code.
|
||||
* Added type `MatchConditions` for use in conditional requests.
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* Fixed a potential race condition between `NullValue` and `IsNullValue`.
|
||||
* `runtime.EncodeQueryParams` will escape semicolons before calling `url.ParseQuery`.
|
||||
|
||||
### Other Changes
|
||||
|
||||
* Update dependencies.
|
||||
|
||||
## 1.9.2 (2024-02-06)
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* `runtime.MarshalAsByteArray` and `runtime.MarshalAsJSON` will preserve the preexisting value of the `Content-Type` header.
|
||||
|
||||
### Other Changes
|
||||
|
||||
* Update to latest version of `internal`.
|
||||
|
||||
## 1.9.1 (2023-12-11)
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* The `retry-after-ms` and `x-ms-retry-after-ms` headers weren't being checked during retries.
|
||||
|
||||
### Other Changes
|
||||
|
||||
* Update dependencies.
|
||||
|
||||
## 1.9.0 (2023-11-06)
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against previous beta versions of `v1.7.0` and `v1.8.0`
|
||||
* The function `NewTokenCredential` has been removed from the `fake` package. Use a literal `&fake.TokenCredential{}` instead.
|
||||
* The field `TracingNamespace` in `runtime.PipelineOptions` has been replaced by `TracingOptions`.
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* Fixed an issue that could cause some allowed HTTP header values to not show up in logs.
|
||||
* Include error text instead of error type in traces when the transport returns an error.
|
||||
* Fixed an issue that could cause an HTTP/2 request to hang when the TCP connection becomes unresponsive.
|
||||
* Block key and SAS authentication for non TLS protected endpoints.
|
||||
* Passing a `nil` credential value will no longer cause a panic. Instead, the authentication is skipped.
|
||||
* Calling `Error` on a zero-value `azcore.ResponseError` will no longer panic.
|
||||
* Fixed an issue in `fake.PagerResponder[T]` that would cause a trailing error to be omitted when iterating over pages.
|
||||
* Context values created by `azcore` will no longer flow across disjoint HTTP requests.
|
||||
|
||||
### Other Changes
|
||||
|
||||
* Skip generating trace info for no-op tracers.
|
||||
* The `clientName` paramater in client constructors has been renamed to `moduleName`.
|
||||
|
||||
## 1.9.0-beta.1 (2023-10-05)
|
||||
|
||||
### Other Changes
|
||||
|
||||
* The beta features for tracing and fakes have been reinstated.
|
||||
|
||||
## 1.8.0 (2023-10-05)
|
||||
|
||||
### Features Added
|
||||
|
||||
* This includes the following features from `v1.8.0-beta.N` releases.
|
||||
* Claims and CAE for authentication.
|
||||
* New `messaging` package.
|
||||
* Various helpers in the `runtime` package.
|
||||
* Deprecation of `runtime.With*` funcs and their replacements in the `policy` package.
|
||||
* Added types `KeyCredential` and `SASCredential` to the `azcore` package.
|
||||
* Includes their respective constructor functions.
|
||||
* Added types `KeyCredentialPolicy` and `SASCredentialPolicy` to the `azcore/runtime` package.
|
||||
* Includes their respective constructor functions and options types.
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against beta versions of `v1.8.0`
|
||||
* The beta features for tracing and fakes have been omitted for this release.
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* Fixed an issue that could cause some ARM RPs to not be automatically registered.
|
||||
* Block bearer token authentication for non TLS protected endpoints.
|
||||
|
||||
### Other Changes
|
||||
|
||||
* Updated dependencies.
|
||||
|
||||
## 1.8.0-beta.3 (2023-09-07)
|
||||
|
||||
### Features Added
|
||||
|
||||
* Added function `FetcherForNextLink` and `FetcherForNextLinkOptions` to the `runtime` package to centralize creation of `Pager[T].Fetcher` from a next link URL.
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* Suppress creating spans for nested SDK API calls. The HTTP span will be a child of the outer API span.
|
||||
|
||||
### Other Changes
|
||||
|
||||
* The following functions in the `runtime` package are now exposed from the `policy` package, and the `runtime` versions have been deprecated.
|
||||
* `WithCaptureResponse`
|
||||
* `WithHTTPHeader`
|
||||
* `WithRetryOptions`
|
||||
|
||||
## 1.7.2 (2023-09-06)
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* Fix default HTTP transport to work in WASM modules.
|
||||
|
||||
## 1.8.0-beta.2 (2023-08-14)
|
||||
|
||||
### Features Added
|
||||
|
||||
* Added function `SanitizePagerPollerPath` to the `server` package to centralize sanitization and formalize the contract.
|
||||
* Added `TokenRequestOptions.EnableCAE` to indicate whether to request a CAE token.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
> This change affects only code written against beta version `v1.8.0-beta.1`.
|
||||
* `messaging.CloudEvent` deserializes JSON objects as `[]byte`, instead of `json.RawMessage`. See the documentation for CloudEvent.Data for more information.
|
||||
|
||||
> This change affects only code written against beta versions `v1.7.0-beta.2` and `v1.8.0-beta.1`.
|
||||
* Removed parameter from method `Span.End()` and its type `tracing.SpanEndOptions`. This API GA'ed in `v1.2.0` so we cannot change it.
|
||||
|
||||
### Bugs Fixed
|
||||
|
||||
* Propagate any query parameters when constructing a fake poller and/or injecting next links.
|
||||
|
||||
## 1.7.1 (2023-08-14)
|
||||
|
||||
## Bugs Fixed
|
||||
|
||||
* Enable TLS renegotiation in the default transport policy.
|
||||
|
||||
## 1.8.0-beta.1 (2023-07-12)
|
||||
|
||||
### Features Added
|
||||
|
||||
- `messaging/CloudEvent` allows you to serialize/deserialize CloudEvents, as described in the CloudEvents 1.0 specification: [link](https://github.com/cloudevents/spec)
|
||||
|
||||
### Other Changes
|
||||
|
||||
* The beta features for CAE, tracing, and fakes have been reinstated.
|
||||
|
||||
## 1.7.0 (2023-07-12)
|
||||
|
||||
### Features Added
|
||||
* Added method `WithClientName()` to type `azcore.Client` to support shallow cloning of a client with a new name used for tracing.
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against beta versions v1.7.0-beta.1 or v1.7.0-beta.2
|
||||
* The beta features for CAE, tracing, and fakes have been omitted for this release.
|
||||
|
||||
## 1.7.0-beta.2 (2023-06-06)
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against beta version v1.7.0-beta.1
|
||||
* Method `SpanFromContext()` on type `tracing.Tracer` had the `bool` return value removed.
|
||||
* This includes the field `SpanFromContext` in supporting type `tracing.TracerOptions`.
|
||||
* Method `AddError()` has been removed from type `tracing.Span`.
|
||||
* Method `Span.End()` now requires an argument of type `*tracing.SpanEndOptions`.
|
||||
|
||||
## 1.6.1 (2023-06-06)
|
||||
|
||||
### Bugs Fixed
|
||||
* Fixed an issue in `azcore.NewClient()` and `arm.NewClient()` that could cause an incorrect module name to be used in telemetry.
|
||||
|
||||
### Other Changes
|
||||
* This version contains all bug fixes from `v1.7.0-beta.1`
|
||||
|
||||
## 1.7.0-beta.1 (2023-05-24)
|
||||
|
||||
### Features Added
|
||||
* Restored CAE support for ARM clients.
|
||||
* Added supporting features to enable distributed tracing.
|
||||
* Added func `runtime.StartSpan()` for use by SDKs to start spans.
|
||||
* Added method `WithContext()` to `runtime.Request` to support shallow cloning with a new context.
|
||||
* Added field `TracingNamespace` to `runtime.PipelineOptions`.
|
||||
* Added field `Tracer` to `runtime.NewPollerOptions` and `runtime.NewPollerFromResumeTokenOptions` types.
|
||||
* Added field `SpanFromContext` to `tracing.TracerOptions`.
|
||||
* Added methods `Enabled()`, `SetAttributes()`, and `SpanFromContext()` to `tracing.Tracer`.
|
||||
* Added supporting pipeline policies to include HTTP spans when creating clients.
|
||||
* Added package `fake` to support generated fakes packages in SDKs.
|
||||
* The package contains public surface area exposed by fake servers and supporting APIs intended only for use by the fake server implementations.
|
||||
* Added an internal fake poller implementation.
|
||||
|
||||
### Bugs Fixed
|
||||
* Retry policy always clones the underlying `*http.Request` before invoking the next policy.
|
||||
* Added some non-standard error codes to the list of error codes for unregistered resource providers.
|
||||
|
||||
## 1.6.0 (2023-05-04)
|
||||
|
||||
### Features Added
|
||||
* Added support for ARM cross-tenant authentication. Set the `AuxiliaryTenants` field of `arm.ClientOptions` to enable.
|
||||
* Added `TenantID` field to `policy.TokenRequestOptions`.
|
||||
|
||||
## 1.5.0 (2023-04-06)
|
||||
|
||||
### Features Added
|
||||
* Added `ShouldRetry` to `policy.RetryOptions` for finer-grained control over when to retry.
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against a beta version such as v1.5.0-beta.1
|
||||
> These features will return in v1.6.0-beta.1.
|
||||
* Removed `TokenRequestOptions.Claims` and `.TenantID`
|
||||
* Removed ARM client support for CAE and cross-tenant auth.
|
||||
|
||||
### Bugs Fixed
|
||||
* Added non-conformant LRO terminal states `Cancelled` and `Completed`.
|
||||
|
||||
### Other Changes
|
||||
* Updated to latest `internal` module.
|
||||
|
||||
## 1.5.0-beta.1 (2023-03-02)
|
||||
|
||||
### Features Added
|
||||
* This release includes the features added in v1.4.0-beta.1
|
||||
|
||||
## 1.4.0 (2023-03-02)
|
||||
> This release doesn't include features added in v1.4.0-beta.1. They will return in v1.5.0-beta.1.
|
||||
|
||||
### Features Added
|
||||
* Add `Clone()` method for `arm/policy.ClientOptions`.
|
||||
|
||||
### Bugs Fixed
|
||||
* ARM's RP registration policy will no longer swallow unrecognized errors.
|
||||
* Fixed an issue in `runtime.NewPollerFromResumeToken()` when resuming a `Poller` with a custom `PollingHandler`.
|
||||
* Fixed wrong policy copy in `arm/runtime.NewPipeline()`.
|
||||
|
||||
## 1.4.0-beta.1 (2023-02-02)
|
||||
|
||||
### Features Added
|
||||
* Added support for ARM cross-tenant authentication. Set the `AuxiliaryTenants` field of `arm.ClientOptions` to enable.
|
||||
* Added `Claims` and `TenantID` fields to `policy.TokenRequestOptions`.
|
||||
* ARM bearer token policy handles CAE challenges.
|
||||
|
||||
## 1.3.1 (2023-02-02)
|
||||
|
||||
### Other Changes
|
||||
* Update dependencies to latest versions.
|
||||
|
||||
## 1.3.0 (2023-01-06)
|
||||
|
||||
### Features Added
|
||||
* Added `BearerTokenOptions.AuthorizationHandler` to enable extending `runtime.BearerTokenPolicy`
|
||||
with custom authorization logic
|
||||
* Added `Client` types and matching constructors to the `azcore` and `arm` packages. These represent a basic client for HTTP and ARM respectively.
|
||||
|
||||
### Other Changes
|
||||
* Updated `internal` module to latest version.
|
||||
* `policy/Request.SetBody()` allows replacing a request's body with an empty one
|
||||
|
||||
## 1.2.0 (2022-11-04)
|
||||
|
||||
### Features Added
|
||||
* Added `ClientOptions.APIVersion` field, which overrides the default version a client
|
||||
requests of the service, if the client supports this (all ARM clients do).
|
||||
* Added package `tracing` that contains the building blocks for distributed tracing.
|
||||
* Added field `TracingProvider` to type `policy.ClientOptions` that will be used to set the per-client tracing implementation.
|
||||
|
||||
### Bugs Fixed
|
||||
* Fixed an issue in `runtime.SetMultipartFormData` to properly handle slices of `io.ReadSeekCloser`.
|
||||
* Fixed the MaxRetryDelay default to be 60s.
|
||||
* Failure to poll the state of an LRO will now return an `*azcore.ResponseError` for poller types that require this behavior.
|
||||
* Fixed a bug in `runtime.NewPipeline` that would cause pipeline-specified allowed headers and query parameters to be lost.
|
||||
|
||||
### Other Changes
|
||||
* Retain contents of read-only fields when sending requests.
|
||||
|
||||
## 1.1.4 (2022-10-06)
|
||||
|
||||
### Bugs Fixed
|
||||
* Don't retry a request if the `Retry-After` delay is greater than the configured `RetryOptions.MaxRetryDelay`.
|
||||
* `runtime.JoinPaths`: do not unconditionally add a forward slash before the query string
|
||||
|
||||
### Other Changes
|
||||
* Removed logging URL from retry policy as it's redundant.
|
||||
* Retry policy logs when it exits due to a non-retriable status code.
|
||||
|
||||
## 1.1.3 (2022-09-01)
|
||||
|
||||
### Bugs Fixed
|
||||
* Adjusted the initial retry delay to 800ms per the Azure SDK guidelines.
|
||||
|
||||
## 1.1.2 (2022-08-09)
|
||||
|
||||
### Other Changes
|
||||
* Fixed various doc bugs.
|
||||
|
||||
## 1.1.1 (2022-06-30)
|
||||
|
||||
### Bugs Fixed
|
||||
* Avoid polling when a RELO LRO synchronously terminates.
|
||||
|
||||
## 1.1.0 (2022-06-03)
|
||||
|
||||
### Other Changes
|
||||
* The one-second floor for `Frequency` when calling `PollUntilDone()` has been removed when running tests.
|
||||
|
||||
## 1.0.0 (2022-05-12)
|
||||
|
||||
### Features Added
|
||||
* Added interface `runtime.PollingHandler` to support custom poller implementations.
|
||||
* Added field `PollingHandler` of this type to `runtime.NewPollerOptions[T]` and `runtime.NewPollerFromResumeTokenOptions[T]`.
|
||||
|
||||
### Breaking Changes
|
||||
* Renamed `cloud.Configuration.LoginEndpoint` to `.ActiveDirectoryAuthorityHost`
|
||||
* Renamed `cloud.AzurePublicCloud` to `cloud.AzurePublic`
|
||||
* Removed `AuxiliaryTenants` field from `arm/ClientOptions` and `arm/policy/BearerTokenOptions`
|
||||
* Removed `TokenRequestOptions.TenantID`
|
||||
* `Poller[T].PollUntilDone()` now takes an `options *PollUntilDoneOptions` param instead of `freq time.Duration`
|
||||
* Removed `arm/runtime.Poller[T]`, `arm/runtime.NewPoller[T]()` and `arm/runtime.NewPollerFromResumeToken[T]()`
|
||||
* Removed `arm/runtime.FinalStateVia` and related `const` values
|
||||
* Renamed `runtime.PageProcessor` to `runtime.PagingHandler`
|
||||
* The `arm/runtime.ProviderRepsonse` and `arm/runtime.Provider` types are no longer exported.
|
||||
* Renamed `NewRequestIdPolicy()` to `NewRequestIDPolicy()`
|
||||
* `TokenCredential.GetToken` now returns `AccessToken` by value.
|
||||
|
||||
### Bugs Fixed
|
||||
* When per-try timeouts are enabled, only cancel the context after the body has been read and closed.
|
||||
* The `Operation-Location` poller now properly handles `final-state-via` values.
|
||||
* Improvements in `runtime.Poller[T]`
|
||||
* `Poll()` shouldn't cache errors, allowing for additional retries when in a non-terminal state.
|
||||
* `Result()` will cache the terminal result or error but not transient errors, allowing for additional retries.
|
||||
|
||||
### Other Changes
|
||||
* Updated to latest `internal` module and absorbed breaking changes.
|
||||
* Use `temporal.Resource` and deleted copy.
|
||||
* The internal poller implementation has been refactored.
|
||||
* The implementation in `internal/pollers/poller.go` has been merged into `runtime/poller.go` with some slight modification.
|
||||
* The internal poller types had their methods updated to conform to the `runtime.PollingHandler` interface.
|
||||
* The creation of resume tokens has been refactored so that implementers of `runtime.PollingHandler` don't need to know about it.
|
||||
* `NewPipeline()` places policies from `ClientOptions` after policies from `PipelineOptions`
|
||||
* Default User-Agent headers no longer include `azcore` version information
|
||||
|
||||
## 0.23.1 (2022-04-14)
|
||||
|
||||
### Bugs Fixed
|
||||
* Include XML header when marshalling XML content.
|
||||
* Handle XML namespaces when searching for error code.
|
||||
* Handle `odata.error` when searching for error code.
|
||||
|
||||
## 0.23.0 (2022-04-04)
|
||||
|
||||
### Features Added
|
||||
* Added `runtime.Pager[T any]` and `runtime.Poller[T any]` supporting types for central, generic, implementations.
|
||||
* Added `cloud` package with a new API for cloud configuration
|
||||
* Added `FinalStateVia` field to `runtime.NewPollerOptions[T any]` type.
|
||||
|
||||
### Breaking Changes
|
||||
* Removed the `Poller` type-alias to the internal poller implementation.
|
||||
* Added `Ptr[T any]` and `SliceOfPtrs[T any]` in the `to` package and removed all non-generic implementations.
|
||||
* `NullValue` and `IsNullValue` now take a generic type parameter instead of an interface func parameter.
|
||||
* Replaced `arm.Endpoint` with `cloud` API
|
||||
* Removed the `endpoint` parameter from `NewRPRegistrationPolicy()`
|
||||
* `arm/runtime.NewPipeline()` and `.NewRPRegistrationPolicy()` now return an `error`
|
||||
* Refactored `NewPoller` and `NewPollerFromResumeToken` funcs in `arm/runtime` and `runtime` packages.
|
||||
* Removed the `pollerID` parameter as it's no longer required.
|
||||
* Created optional parameter structs and moved optional parameters into them.
|
||||
* Changed `FinalStateVia` field to a `const` type.
|
||||
|
||||
### Other Changes
|
||||
* Converted expiring resource and dependent types to use generics.
|
||||
|
||||
## 0.22.0 (2022-03-03)
|
||||
|
||||
### Features Added
|
||||
* Added header `WWW-Authenticate` to the default allow-list of headers for logging.
|
||||
* Added a pipeline policy that enables the retrieval of HTTP responses from API calls.
|
||||
* Added `runtime.WithCaptureResponse` to enable the policy at the API level (off by default).
|
||||
|
||||
### Breaking Changes
|
||||
* Moved `WithHTTPHeader` and `WithRetryOptions` from the `policy` package to the `runtime` package.
|
||||
|
||||
## 0.21.1 (2022-02-04)
|
||||
|
||||
### Bugs Fixed
|
||||
* Restore response body after reading in `Poller.FinalResponse()`. (#16911)
|
||||
* Fixed bug in `NullValue` that could lead to incorrect comparisons for empty maps/slices (#16969)
|
||||
|
||||
### Other Changes
|
||||
* `BearerTokenPolicy` is more resilient to transient authentication failures. (#16789)
|
||||
|
||||
## 0.21.0 (2022-01-11)
|
||||
|
||||
### Features Added
|
||||
* Added `AllowedHeaders` and `AllowedQueryParams` to `policy.LogOptions` to control which headers and query parameters are written to the logger.
|
||||
* Added `azcore.ResponseError` type which is returned from APIs when a non-success HTTP status code is received.
|
||||
|
||||
### Breaking Changes
|
||||
* Moved `[]policy.Policy` parameters of `arm/runtime.NewPipeline` and `runtime.NewPipeline` into a new struct, `runtime.PipelineOptions`
|
||||
* Renamed `arm/ClientOptions.Host` to `.Endpoint`
|
||||
* Moved `Request.SkipBodyDownload` method to function `runtime.SkipBodyDownload`
|
||||
* Removed `azcore.HTTPResponse` interface type
|
||||
* `arm.NewPoller()` and `runtime.NewPoller()` no longer require an `eu` parameter
|
||||
* `runtime.NewResponseError()` no longer requires an `error` parameter
|
||||
|
||||
## 0.20.0 (2021-10-22)
|
||||
|
||||
### Breaking Changes
|
||||
* Removed `arm.Connection`
|
||||
* Removed `azcore.Credential` and `.NewAnonymousCredential()`
|
||||
* `NewRPRegistrationPolicy` now requires an `azcore.TokenCredential`
|
||||
* `runtime.NewPipeline` has a new signature that simplifies implementing custom authentication
|
||||
* `arm/runtime.RegistrationOptions` embeds `policy.ClientOptions`
|
||||
* Contents in the `log` package have been slightly renamed.
|
||||
* Removed `AuthenticationOptions` in favor of `policy.BearerTokenOptions`
|
||||
* Changed parameters for `NewBearerTokenPolicy()`
|
||||
* Moved policy config options out of `arm/runtime` and into `arm/policy`
|
||||
|
||||
### Features Added
|
||||
* Updating Documentation
|
||||
* Added string typdef `arm.Endpoint` to provide a hint toward expected ARM client endpoints
|
||||
* `azcore.ClientOptions` contains common pipeline configuration settings
|
||||
* Added support for multi-tenant authorization in `arm/runtime`
|
||||
* Require one second minimum when calling `PollUntilDone()`
|
||||
|
||||
### Bug Fixes
|
||||
* Fixed a potential panic when creating the default Transporter.
|
||||
* Close LRO initial response body when creating a poller.
|
||||
* Fixed a panic when recursively cloning structs that contain time.Time.
|
||||
|
||||
## 0.19.0 (2021-08-25)
|
||||
|
||||
### Breaking Changes
|
||||
* Split content out of `azcore` into various packages. The intent is to separate content based on its usage (common, uncommon, SDK authors).
|
||||
* `azcore` has all core functionality.
|
||||
* `log` contains facilities for configuring in-box logging.
|
||||
* `policy` is used for configuring pipeline options and creating custom pipeline policies.
|
||||
* `runtime` contains various helpers used by SDK authors and generated content.
|
||||
* `streaming` has helpers for streaming IO operations.
|
||||
* `NewTelemetryPolicy()` now requires module and version parameters and the `Value` option has been removed.
|
||||
* As a result, the `Request.Telemetry()` method has been removed.
|
||||
* The telemetry policy now includes the SDK prefix `azsdk-go-` so callers no longer need to provide it.
|
||||
* The `*http.Request` in `runtime.Request` is no longer anonymously embedded. Use the `Raw()` method to access it.
|
||||
* The `UserAgent` and `Version` constants have been made internal, `Module` and `Version` respectively.
|
||||
|
||||
### Bug Fixes
|
||||
* Fixed an issue in the retry policy where the request body could be overwritten after a rewind.
|
||||
|
||||
### Other Changes
|
||||
* Moved modules `armcore` and `to` content into `arm` and `to` packages respectively.
|
||||
* The `Pipeline()` method on `armcore.Connection` has been replaced by `NewPipeline()` in `arm.Connection`. It takes module and version parameters used by the telemetry policy.
|
||||
* Poller logic has been consolidated across ARM and core implementations.
|
||||
* This required some changes to the internal interfaces for core pollers.
|
||||
* The core poller types have been improved, including more logging and test coverage.
|
||||
|
||||
## 0.18.1 (2021-08-20)
|
||||
|
||||
### Features Added
|
||||
* Adds an `ETag` type for comparing etags and handling etags on requests
|
||||
* Simplifies the `requestBodyProgess` and `responseBodyProgress` into a single `progress` object
|
||||
|
||||
### Bugs Fixed
|
||||
* `JoinPaths` will preserve query parameters encoded in the `root` url.
|
||||
|
||||
### Other Changes
|
||||
* Bumps dependency on `internal` module to the latest version (v0.7.0)
|
||||
|
||||
## 0.18.0 (2021-07-29)
|
||||
### Features Added
|
||||
* Replaces methods from Logger type with two package methods for interacting with the logging functionality.
|
||||
* `azcore.SetClassifications` replaces `azcore.Logger().SetClassifications`
|
||||
* `azcore.SetListener` replaces `azcore.Logger().SetListener`
|
||||
|
||||
### Breaking Changes
|
||||
* Removes `Logger` type from `azcore`
|
||||
|
||||
|
||||
## 0.17.0 (2021-07-27)
|
||||
### Features Added
|
||||
* Adding TenantID to TokenRequestOptions (https://github.com/Azure/azure-sdk-for-go/pull/14879)
|
||||
* Adding AuxiliaryTenants to AuthenticationOptions (https://github.com/Azure/azure-sdk-for-go/pull/15123)
|
||||
|
||||
### Breaking Changes
|
||||
* Rename `AnonymousCredential` to `NewAnonymousCredential` (https://github.com/Azure/azure-sdk-for-go/pull/15104)
|
||||
* rename `AuthenticationPolicyOptions` to `AuthenticationOptions` (https://github.com/Azure/azure-sdk-for-go/pull/15103)
|
||||
* Make Header constants private (https://github.com/Azure/azure-sdk-for-go/pull/15038)
|
||||
|
||||
|
||||
## 0.16.2 (2021-05-26)
|
||||
### Features Added
|
||||
* Improved support for byte arrays [#14715](https://github.com/Azure/azure-sdk-for-go/pull/14715)
|
||||
|
||||
|
||||
## 0.16.1 (2021-05-19)
|
||||
### Features Added
|
||||
* Add license.txt to azcore module [#14682](https://github.com/Azure/azure-sdk-for-go/pull/14682)
|
||||
|
||||
|
||||
## 0.16.0 (2021-05-07)
|
||||
### Features Added
|
||||
* Remove extra `*` in UnmarshalAsByteArray() [#14642](https://github.com/Azure/azure-sdk-for-go/pull/14642)
|
||||
|
||||
|
||||
## 0.15.1 (2021-05-06)
|
||||
### Features Added
|
||||
* Cache the original request body on Request [#14634](https://github.com/Azure/azure-sdk-for-go/pull/14634)
|
||||
|
||||
|
||||
## 0.15.0 (2021-05-05)
|
||||
### Features Added
|
||||
* Add support for null map and slice
|
||||
* Export `Response.Payload` method
|
||||
|
||||
### Breaking Changes
|
||||
* remove `Response.UnmarshalError` as it's no longer required
|
||||
|
||||
|
||||
## 0.14.5 (2021-04-23)
|
||||
### Features Added
|
||||
* Add `UnmarshalError()` on `azcore.Response`
|
||||
|
||||
|
||||
## 0.14.4 (2021-04-22)
|
||||
### Features Added
|
||||
* Support for basic LRO polling
|
||||
* Added type `LROPoller` and supporting types for basic polling on long running operations.
|
||||
* rename poller param and added doc comment
|
||||
|
||||
### Bugs Fixed
|
||||
* Fixed content type detection bug in logging.
|
||||
|
||||
|
||||
## 0.14.3 (2021-03-29)
|
||||
### Features Added
|
||||
* Add support for multi-part form data
|
||||
* Added method `WriteMultipartFormData()` to Request.
|
||||
|
||||
|
||||
## 0.14.2 (2021-03-17)
|
||||
### Features Added
|
||||
* Add support for encoding JSON null values
|
||||
* Adds `NullValue()` and `IsNullValue()` functions for setting and detecting sentinel values used for encoding a JSON null.
|
||||
* Documentation fixes
|
||||
|
||||
### Bugs Fixed
|
||||
* Fixed improper error wrapping
|
||||
|
||||
|
||||
## 0.14.1 (2021-02-08)
|
||||
### Features Added
|
||||
* Add `Pager` and `Poller` interfaces to azcore
|
||||
|
||||
|
||||
## 0.14.0 (2021-01-12)
|
||||
### Features Added
|
||||
* Accept zero-value options for default values
|
||||
* Specify zero-value options structs to accept default values.
|
||||
* Remove `DefaultXxxOptions()` methods.
|
||||
* Do not silently change TryTimeout on negative values
|
||||
* make per-try timeout opt-in
|
||||
|
||||
|
||||
## 0.13.4 (2020-11-20)
|
||||
### Features Added
|
||||
* Include telemetry string in User Agent
|
||||
|
||||
|
||||
## 0.13.3 (2020-11-20)
|
||||
### Features Added
|
||||
* Updating response body handling on `azcore.Response`
|
||||
|
||||
|
||||
## 0.13.2 (2020-11-13)
|
||||
### Features Added
|
||||
* Remove implementation of stateless policies as first-class functions.
|
||||
|
||||
|
||||
## 0.13.1 (2020-11-05)
|
||||
### Features Added
|
||||
* Add `Telemetry()` method to `azcore.Request()`
|
||||
|
||||
|
||||
## 0.13.0 (2020-10-14)
|
||||
### Features Added
|
||||
* Rename `log` to `logger` to avoid name collision with the log package.
|
||||
* Documentation improvements
|
||||
* Simplified `DefaultHTTPClientTransport()` implementation
|
||||
|
||||
|
||||
## 0.12.1 (2020-10-13)
|
||||
### Features Added
|
||||
* Update `internal` module dependence to `v0.5.0`
|
||||
|
||||
|
||||
## 0.12.0 (2020-10-08)
|
||||
### Features Added
|
||||
* Removed storage specific content
|
||||
* Removed internal content to prevent API clutter
|
||||
* Refactored various policy options to conform with our options pattern
|
||||
|
||||
|
||||
## 0.11.0 (2020-09-22)
|
||||
### Features Added
|
||||
|
||||
* Removed `LogError` and `LogSlowResponse`.
|
||||
* Renamed `options` in `RequestLogOptions`.
|
||||
* Updated `NewRequestLogPolicy()` to follow standard pattern for options.
|
||||
* Refactored `requestLogPolicy.Do()` per above changes.
|
||||
* Cleaned up/added logging in retry policy.
|
||||
* Export `NewResponseError()`
|
||||
* Fix `RequestLogOptions` comment
|
||||
|
||||
|
||||
## 0.10.1 (2020-09-17)
|
||||
### Features Added
|
||||
* Add default console logger
|
||||
* Default console logger writes to stderr. To enable it, set env var `AZURE_SDK_GO_LOGGING` to the value 'all'.
|
||||
* Added `Logger.Writef()` to reduce the need for `ShouldLog()` checks.
|
||||
* Add `LogLongRunningOperation`
|
||||
|
||||
|
||||
## 0.10.0 (2020-09-10)
|
||||
### Features Added
|
||||
* The `request` and `transport` interfaces have been refactored to align with the patterns in the standard library.
|
||||
* `NewRequest()` now uses `http.NewRequestWithContext()` and performs additional validation, it also requires a context parameter.
|
||||
* The `Policy` and `Transport` interfaces have had their context parameter removed as the context is associated with the underlying `http.Request`.
|
||||
* `Pipeline.Do()` will validate the HTTP request before sending it through the pipeline, avoiding retries on a malformed request.
|
||||
* The `Retrier` interface has been replaced with the `NonRetriableError` interface, and the retry policy updated to test for this.
|
||||
* `Request.SetBody()` now requires a content type parameter for setting the request's MIME type.
|
||||
* moved path concatenation into `JoinPaths()` func
|
||||
|
||||
|
||||
## 0.9.6 (2020-08-18)
|
||||
### Features Added
|
||||
* Improvements to body download policy
|
||||
* Always download the response body for error responses, i.e. HTTP status codes >= 400.
|
||||
* Simplify variable declarations
|
||||
|
||||
|
||||
## 0.9.5 (2020-08-11)
|
||||
### Features Added
|
||||
* Set the Content-Length header in `Request.SetBody`
|
||||
|
||||
|
||||
## 0.9.4 (2020-08-03)
|
||||
### Features Added
|
||||
* Fix cancellation of per try timeout
|
||||
* Per try timeout is used to ensure that an HTTP operation doesn't take too long, e.g. that a GET on some URL doesn't take an inordinant amount of time.
|
||||
* Once the HTTP request returns, the per try timeout should be cancelled, not when the response has been read to completion.
|
||||
* Do not drain response body if there are no more retries
|
||||
* Do not retry non-idempotent operations when body download fails
|
||||
|
||||
|
||||
## 0.9.3 (2020-07-28)
|
||||
### Features Added
|
||||
* Add support for custom HTTP request headers
|
||||
* Inserts an internal policy into the pipeline that can extract HTTP header values from the caller's context, adding them to the request.
|
||||
* Use `azcore.WithHTTPHeader` to add HTTP headers to a context.
|
||||
* Remove method specific to Go 1.14
|
||||
|
||||
|
||||
## 0.9.2 (2020-07-28)
|
||||
### Features Added
|
||||
* Omit read-only content from request payloads
|
||||
* If any field in a payload's object graph contains `azure:"ro"`, make a clone of the object graph, omitting all fields with this annotation.
|
||||
* Verify no fields were dropped
|
||||
* Handle embedded struct types
|
||||
* Added test for cloning by value
|
||||
* Add messages to failures
|
||||
|
||||
|
||||
## 0.9.1 (2020-07-22)
|
||||
### Features Added
|
||||
* Updated dependency on internal module to fix race condition.
|
||||
|
||||
|
||||
## 0.9.0 (2020-07-09)
|
||||
### Features Added
|
||||
* Add `HTTPResponse` interface to be used by callers to access the raw HTTP response from an error in the event of an API call failure.
|
||||
* Updated `sdk/internal` dependency to latest version.
|
||||
* Rename package alias
|
||||
|
||||
|
||||
## 0.8.2 (2020-06-29)
|
||||
### Features Added
|
||||
* Added missing documentation comments
|
||||
|
||||
### Bugs Fixed
|
||||
* Fixed a bug in body download policy.
|
||||
|
||||
|
||||
## 0.8.1 (2020-06-26)
|
||||
### Features Added
|
||||
* Miscellaneous clean-up reported by linters
|
||||
|
||||
|
||||
## 0.8.0 (2020-06-01)
|
||||
### Features Added
|
||||
* Differentiate between standard and URL encoding.
|
||||
|
||||
|
||||
## 0.7.1 (2020-05-27)
|
||||
### Features Added
|
||||
* Add support for for base64 encoding and decoding of payloads.
|
||||
|
||||
|
||||
## 0.7.0 (2020-05-12)
|
||||
### Features Added
|
||||
* Change `RetryAfter()` to a function.
|
||||
|
||||
|
||||
## 0.6.0 (2020-04-29)
|
||||
### Features Added
|
||||
* Updating `RetryAfter` to only return the detaion in the RetryAfter header
|
||||
|
||||
|
||||
## 0.5.0 (2020-03-23)
|
||||
### Features Added
|
||||
* Export `TransportFunc`
|
||||
|
||||
### Breaking Changes
|
||||
* Removed `IterationDone`
|
||||
|
||||
|
||||
## 0.4.1 (2020-02-25)
|
||||
### Features Added
|
||||
* Ensure per-try timeout is properly cancelled
|
||||
* Explicitly call cancel the per-try timeout when the response body has been read/closed by the body download policy.
|
||||
* When the response body is returned to the caller for reading/closing, wrap it in a `responseBodyReader` that will cancel the timeout when the body is closed.
|
||||
* `Logger.Should()` will return false if no listener is set.
|
||||
|
||||
|
||||
## 0.4.0 (2020-02-18)
|
||||
### Features Added
|
||||
* Enable custom `RetryOptions` to be specified per API call
|
||||
* Added `WithRetryOptions()` that adds a custom `RetryOptions` to the provided context, allowing custom settings per API call.
|
||||
* Remove 429 from the list of default HTTP status codes for retry.
|
||||
* Change StatusCodesForRetry to a slice so consumers can append to it.
|
||||
* Added support for retry-after in HTTP-date format.
|
||||
* Cleaned up some comments specific to storage.
|
||||
* Remove `Request.SetQueryParam()`
|
||||
* Renamed `MaxTries` to `MaxRetries`
|
||||
|
||||
## 0.3.0 (2020-01-16)
|
||||
### Features Added
|
||||
* Added `DefaultRetryOptions` to create initialized default options.
|
||||
|
||||
### Breaking Changes
|
||||
* Removed `Response.CheckStatusCode()`
|
||||
|
||||
|
||||
## 0.2.0 (2020-01-15)
|
||||
### Features Added
|
||||
* Add support for marshalling and unmarshalling JSON
|
||||
* Removed `Response.Payload` field
|
||||
* Exit early when unmarsahlling if there is no payload
|
||||
|
||||
|
||||
## 0.1.0 (2020-01-10)
|
||||
### Features Added
|
||||
* Initial release
|
||||
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
@@ -1,39 +0,0 @@
|
||||
# Azure Core Client Module for Go
|
||||
|
||||
[](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azcore)
|
||||
[](https://dev.azure.com/azure-sdk/public/_build/latest?definitionId=1843&branchName=main)
|
||||
[](https://img.shields.io/azure-devops/coverage/azure-sdk/public/1843/main)
|
||||
|
||||
The `azcore` module provides a set of common interfaces and types for Go SDK client modules.
|
||||
These modules follow the [Azure SDK Design Guidelines for Go](https://azure.github.io/azure-sdk/golang_introduction.html).
|
||||
|
||||
## Getting started
|
||||
|
||||
This project uses [Go modules](https://github.com/golang/go/wiki/Modules) for versioning and dependency management.
|
||||
|
||||
Typically, you will not need to explicitly install `azcore` as it will be installed as a client module dependency.
|
||||
To add the latest version to your `go.mod` file, execute the following command.
|
||||
|
||||
```bash
|
||||
go get github.com/Azure/azure-sdk-for-go/sdk/azcore
|
||||
```
|
||||
|
||||
General documentation and examples can be found on [pkg.go.dev](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azcore).
|
||||
|
||||
## Contributing
|
||||
This project welcomes contributions and suggestions. Most contributions require
|
||||
you to agree to a Contributor License Agreement (CLA) declaring that you have
|
||||
the right to, and actually do, grant us the rights to use your contribution.
|
||||
For details, visit [https://cla.microsoft.com](https://cla.microsoft.com).
|
||||
|
||||
When you submit a pull request, a CLA-bot will automatically determine whether
|
||||
you need to provide a CLA and decorate the PR appropriately (e.g., label,
|
||||
comment). Simply follow the instructions provided by the bot. You will only
|
||||
need to do this once across all repos using our CLA.
|
||||
|
||||
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.
|
||||
@@ -1,72 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package arm
|
||||
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
armpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy"
|
||||
armruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
|
||||
)
|
||||
|
||||
// ClientOptions contains configuration settings for a client's pipeline.
|
||||
type ClientOptions = armpolicy.ClientOptions
|
||||
|
||||
// Client is a HTTP client for use with ARM endpoints. It consists of an endpoint, pipeline, and tracing provider.
|
||||
type Client struct {
|
||||
ep string
|
||||
pl runtime.Pipeline
|
||||
tr tracing.Tracer
|
||||
}
|
||||
|
||||
// NewClient creates a new Client instance with the provided values.
|
||||
// This client is intended to be used with Azure Resource Manager endpoints.
|
||||
// - moduleName - the fully qualified name of the module where the client is defined; used by the telemetry policy and tracing provider.
|
||||
// - moduleVersion - the semantic version of the module; used by the telemetry policy and tracing provider.
|
||||
// - cred - the TokenCredential used to authenticate the request
|
||||
// - options - optional client configurations; pass nil to accept the default values
|
||||
func NewClient(moduleName, moduleVersion string, cred azcore.TokenCredential, options *ClientOptions) (*Client, error) {
|
||||
if options == nil {
|
||||
options = &ClientOptions{}
|
||||
}
|
||||
|
||||
if !options.Telemetry.Disabled {
|
||||
if err := shared.ValidateModVer(moduleVersion); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
ep := cloud.AzurePublic.Services[cloud.ResourceManager].Endpoint
|
||||
if c, ok := options.Cloud.Services[cloud.ResourceManager]; ok {
|
||||
ep = c.Endpoint
|
||||
}
|
||||
pl, err := armruntime.NewPipeline(moduleName, moduleVersion, cred, runtime.PipelineOptions{}, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tr := options.TracingProvider.NewTracer(moduleName, moduleVersion)
|
||||
return &Client{ep: ep, pl: pl, tr: tr}, nil
|
||||
}
|
||||
|
||||
// Endpoint returns the service's base URL for this client.
|
||||
func (c *Client) Endpoint() string {
|
||||
return c.ep
|
||||
}
|
||||
|
||||
// Pipeline returns the pipeline for this client.
|
||||
func (c *Client) Pipeline() runtime.Pipeline {
|
||||
return c.pl
|
||||
}
|
||||
|
||||
// Tracer returns the tracer for this client.
|
||||
func (c *Client) Tracer() tracing.Tracer {
|
||||
return c.tr
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
||||
// Use of this source code is governed by an MIT
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package arm contains functionality specific to Azure Resource Manager clients.
|
||||
package arm
|
||||
@@ -1,239 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
providersKey = "providers"
|
||||
subscriptionsKey = "subscriptions"
|
||||
resourceGroupsLowerKey = "resourcegroups"
|
||||
locationsKey = "locations"
|
||||
builtInResourceNamespace = "Microsoft.Resources"
|
||||
)
|
||||
|
||||
// RootResourceID defines the tenant as the root parent of all other ResourceID.
|
||||
var RootResourceID = &ResourceID{
|
||||
Parent: nil,
|
||||
ResourceType: TenantResourceType,
|
||||
Name: "",
|
||||
}
|
||||
|
||||
// ResourceID represents a resource ID such as `/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg`.
|
||||
// Don't create this type directly, use ParseResourceID instead.
|
||||
type ResourceID struct {
|
||||
// Parent is the parent ResourceID of this instance.
|
||||
// Can be nil if there is no parent.
|
||||
Parent *ResourceID
|
||||
|
||||
// SubscriptionID is the subscription ID in this resource ID.
|
||||
// The value can be empty if the resource ID does not contain a subscription ID.
|
||||
SubscriptionID string
|
||||
|
||||
// ResourceGroupName is the resource group name in this resource ID.
|
||||
// The value can be empty if the resource ID does not contain a resource group name.
|
||||
ResourceGroupName string
|
||||
|
||||
// Provider represents the provider name in this resource ID.
|
||||
// This is only valid when the resource ID represents a resource provider.
|
||||
// Example: `/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Insights`
|
||||
Provider string
|
||||
|
||||
// Location is the location in this resource ID.
|
||||
// The value can be empty if the resource ID does not contain a location name.
|
||||
Location string
|
||||
|
||||
// ResourceType represents the type of this resource ID.
|
||||
ResourceType ResourceType
|
||||
|
||||
// Name is the resource name of this resource ID.
|
||||
Name string
|
||||
|
||||
isChild bool
|
||||
stringValue string
|
||||
}
|
||||
|
||||
// ParseResourceID parses a string to an instance of ResourceID
|
||||
func ParseResourceID(id string) (*ResourceID, error) {
|
||||
if len(id) == 0 {
|
||||
return nil, fmt.Errorf("invalid resource ID: id cannot be empty")
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(id, "/") {
|
||||
return nil, fmt.Errorf("invalid resource ID: resource id '%s' must start with '/'", id)
|
||||
}
|
||||
|
||||
parts := splitStringAndOmitEmpty(id, "/")
|
||||
|
||||
if len(parts) < 2 {
|
||||
return nil, fmt.Errorf("invalid resource ID: %s", id)
|
||||
}
|
||||
|
||||
if !strings.EqualFold(parts[0], subscriptionsKey) && !strings.EqualFold(parts[0], providersKey) {
|
||||
return nil, fmt.Errorf("invalid resource ID: %s", id)
|
||||
}
|
||||
|
||||
return appendNext(RootResourceID, parts, id)
|
||||
}
|
||||
|
||||
// String returns the string of the ResourceID
|
||||
func (id *ResourceID) String() string {
|
||||
if len(id.stringValue) > 0 {
|
||||
return id.stringValue
|
||||
}
|
||||
|
||||
if id.Parent == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
builder := strings.Builder{}
|
||||
builder.WriteString(id.Parent.String())
|
||||
|
||||
if id.isChild {
|
||||
builder.WriteString(fmt.Sprintf("/%s", id.ResourceType.lastType()))
|
||||
if len(id.Name) > 0 {
|
||||
builder.WriteString(fmt.Sprintf("/%s", id.Name))
|
||||
}
|
||||
} else {
|
||||
builder.WriteString(fmt.Sprintf("/providers/%s/%s/%s", id.ResourceType.Namespace, id.ResourceType.Type, id.Name))
|
||||
}
|
||||
|
||||
id.stringValue = builder.String()
|
||||
|
||||
return id.stringValue
|
||||
}
|
||||
|
||||
// MarshalText returns a textual representation of the ResourceID
|
||||
func (id *ResourceID) MarshalText() ([]byte, error) {
|
||||
return []byte(id.String()), nil
|
||||
}
|
||||
|
||||
// UnmarshalText decodes the textual representation of a ResourceID
|
||||
func (id *ResourceID) UnmarshalText(text []byte) error {
|
||||
newId, err := ParseResourceID(string(text))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*id = *newId
|
||||
return nil
|
||||
}
|
||||
|
||||
func newResourceID(parent *ResourceID, resourceTypeName string, resourceName string) *ResourceID {
|
||||
id := &ResourceID{}
|
||||
id.init(parent, chooseResourceType(resourceTypeName, parent), resourceName, true)
|
||||
return id
|
||||
}
|
||||
|
||||
func newResourceIDWithResourceType(parent *ResourceID, resourceType ResourceType, resourceName string) *ResourceID {
|
||||
id := &ResourceID{}
|
||||
id.init(parent, resourceType, resourceName, true)
|
||||
return id
|
||||
}
|
||||
|
||||
func newResourceIDWithProvider(parent *ResourceID, providerNamespace, resourceTypeName, resourceName string) *ResourceID {
|
||||
id := &ResourceID{}
|
||||
id.init(parent, NewResourceType(providerNamespace, resourceTypeName), resourceName, false)
|
||||
return id
|
||||
}
|
||||
|
||||
func chooseResourceType(resourceTypeName string, parent *ResourceID) ResourceType {
|
||||
if strings.EqualFold(resourceTypeName, resourceGroupsLowerKey) {
|
||||
return ResourceGroupResourceType
|
||||
} else if strings.EqualFold(resourceTypeName, subscriptionsKey) && parent != nil && parent.ResourceType.String() == TenantResourceType.String() {
|
||||
return SubscriptionResourceType
|
||||
}
|
||||
|
||||
return parent.ResourceType.AppendChild(resourceTypeName)
|
||||
}
|
||||
|
||||
func (id *ResourceID) init(parent *ResourceID, resourceType ResourceType, name string, isChild bool) {
|
||||
if parent != nil {
|
||||
id.Provider = parent.Provider
|
||||
id.SubscriptionID = parent.SubscriptionID
|
||||
id.ResourceGroupName = parent.ResourceGroupName
|
||||
id.Location = parent.Location
|
||||
}
|
||||
|
||||
if resourceType.String() == SubscriptionResourceType.String() {
|
||||
id.SubscriptionID = name
|
||||
}
|
||||
|
||||
if resourceType.lastType() == locationsKey {
|
||||
id.Location = name
|
||||
}
|
||||
|
||||
if resourceType.String() == ResourceGroupResourceType.String() {
|
||||
id.ResourceGroupName = name
|
||||
}
|
||||
|
||||
if resourceType.String() == ProviderResourceType.String() {
|
||||
id.Provider = name
|
||||
}
|
||||
|
||||
if parent == nil {
|
||||
id.Parent = RootResourceID
|
||||
} else {
|
||||
id.Parent = parent
|
||||
}
|
||||
id.isChild = isChild
|
||||
id.ResourceType = resourceType
|
||||
id.Name = name
|
||||
}
|
||||
|
||||
func appendNext(parent *ResourceID, parts []string, id string) (*ResourceID, error) {
|
||||
if len(parts) == 0 {
|
||||
return parent, nil
|
||||
}
|
||||
|
||||
if len(parts) == 1 {
|
||||
// subscriptions and resourceGroups are not valid ids without their names
|
||||
if strings.EqualFold(parts[0], subscriptionsKey) || strings.EqualFold(parts[0], resourceGroupsLowerKey) {
|
||||
return nil, fmt.Errorf("invalid resource ID: %s", id)
|
||||
}
|
||||
|
||||
// resourceGroup must contain either child or provider resource type
|
||||
if parent.ResourceType.String() == ResourceGroupResourceType.String() {
|
||||
return nil, fmt.Errorf("invalid resource ID: %s", id)
|
||||
}
|
||||
|
||||
return newResourceID(parent, parts[0], ""), nil
|
||||
}
|
||||
|
||||
if strings.EqualFold(parts[0], providersKey) && (len(parts) == 2 || strings.EqualFold(parts[2], providersKey)) {
|
||||
// provider resource can only be on a tenant or a subscription parent
|
||||
if parent.ResourceType.String() != SubscriptionResourceType.String() && parent.ResourceType.String() != TenantResourceType.String() {
|
||||
return nil, fmt.Errorf("invalid resource ID: %s", id)
|
||||
}
|
||||
|
||||
return appendNext(newResourceIDWithResourceType(parent, ProviderResourceType, parts[1]), parts[2:], id)
|
||||
}
|
||||
|
||||
if len(parts) > 3 && strings.EqualFold(parts[0], providersKey) {
|
||||
return appendNext(newResourceIDWithProvider(parent, parts[1], parts[2], parts[3]), parts[4:], id)
|
||||
}
|
||||
|
||||
if len(parts) > 1 && !strings.EqualFold(parts[0], providersKey) {
|
||||
return appendNext(newResourceID(parent, parts[0], parts[1]), parts[2:], id)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("invalid resource ID: %s", id)
|
||||
}
|
||||
|
||||
func splitStringAndOmitEmpty(v, sep string) []string {
|
||||
r := make([]string, 0)
|
||||
for _, s := range strings.Split(v, sep) {
|
||||
if len(s) == 0 {
|
||||
continue
|
||||
}
|
||||
r = append(r, s)
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SubscriptionResourceType is the ResourceType of a subscription
|
||||
var SubscriptionResourceType = NewResourceType(builtInResourceNamespace, "subscriptions")
|
||||
|
||||
// ResourceGroupResourceType is the ResourceType of a resource group
|
||||
var ResourceGroupResourceType = NewResourceType(builtInResourceNamespace, "resourceGroups")
|
||||
|
||||
// TenantResourceType is the ResourceType of a tenant
|
||||
var TenantResourceType = NewResourceType(builtInResourceNamespace, "tenants")
|
||||
|
||||
// ProviderResourceType is the ResourceType of a provider
|
||||
var ProviderResourceType = NewResourceType(builtInResourceNamespace, "providers")
|
||||
|
||||
// ResourceType represents an Azure resource type, e.g. "Microsoft.Network/virtualNetworks/subnets".
|
||||
// Don't create this type directly, use ParseResourceType or NewResourceType instead.
|
||||
type ResourceType struct {
|
||||
// Namespace is the namespace of the resource type.
|
||||
// e.g. "Microsoft.Network" in resource type "Microsoft.Network/virtualNetworks/subnets"
|
||||
Namespace string
|
||||
|
||||
// Type is the full type name of the resource type.
|
||||
// e.g. "virtualNetworks/subnets" in resource type "Microsoft.Network/virtualNetworks/subnets"
|
||||
Type string
|
||||
|
||||
// Types is the slice of all the sub-types of this resource type.
|
||||
// e.g. ["virtualNetworks", "subnets"] in resource type "Microsoft.Network/virtualNetworks/subnets"
|
||||
Types []string
|
||||
|
||||
stringValue string
|
||||
}
|
||||
|
||||
// String returns the string of the ResourceType
|
||||
func (t ResourceType) String() string {
|
||||
return t.stringValue
|
||||
}
|
||||
|
||||
// IsParentOf returns true when the receiver is the parent resource type of the child.
|
||||
func (t ResourceType) IsParentOf(child ResourceType) bool {
|
||||
if !strings.EqualFold(t.Namespace, child.Namespace) {
|
||||
return false
|
||||
}
|
||||
if len(t.Types) >= len(child.Types) {
|
||||
return false
|
||||
}
|
||||
for i := range t.Types {
|
||||
if !strings.EqualFold(t.Types[i], child.Types[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// AppendChild creates an instance of ResourceType using the receiver as the parent with childType appended to it.
|
||||
func (t ResourceType) AppendChild(childType string) ResourceType {
|
||||
return NewResourceType(t.Namespace, fmt.Sprintf("%s/%s", t.Type, childType))
|
||||
}
|
||||
|
||||
// NewResourceType creates an instance of ResourceType using a provider namespace
|
||||
// such as "Microsoft.Network" and type such as "virtualNetworks/subnets".
|
||||
func NewResourceType(providerNamespace, typeName string) ResourceType {
|
||||
return ResourceType{
|
||||
Namespace: providerNamespace,
|
||||
Type: typeName,
|
||||
Types: splitStringAndOmitEmpty(typeName, "/"),
|
||||
stringValue: fmt.Sprintf("%s/%s", providerNamespace, typeName),
|
||||
}
|
||||
}
|
||||
|
||||
// ParseResourceType parses the ResourceType from a resource type string (e.g. Microsoft.Network/virtualNetworks/subsets)
|
||||
// or a resource identifier string.
|
||||
// e.g. /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/mySubnet)
|
||||
func ParseResourceType(resourceIDOrType string) (ResourceType, error) {
|
||||
// split the path into segments
|
||||
parts := splitStringAndOmitEmpty(resourceIDOrType, "/")
|
||||
|
||||
// There must be at least a namespace and type name
|
||||
if len(parts) < 1 {
|
||||
return ResourceType{}, fmt.Errorf("invalid resource ID or type: %s", resourceIDOrType)
|
||||
}
|
||||
|
||||
// if the type is just subscriptions, it is a built-in type in the Microsoft.Resources namespace
|
||||
if len(parts) == 1 {
|
||||
// Simple resource type
|
||||
return NewResourceType(builtInResourceNamespace, parts[0]), nil
|
||||
} else if strings.Contains(parts[0], ".") {
|
||||
// Handle resource types (Microsoft.Compute/virtualMachines, Microsoft.Network/virtualNetworks/subnets)
|
||||
// it is a full type name
|
||||
return NewResourceType(parts[0], strings.Join(parts[1:], "/")), nil
|
||||
} else {
|
||||
// Check if ResourceID
|
||||
id, err := ParseResourceID(resourceIDOrType)
|
||||
if err != nil {
|
||||
return ResourceType{}, err
|
||||
}
|
||||
return NewResourceType(id.ResourceType.Namespace, id.ResourceType.Type), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (t ResourceType) lastType() string {
|
||||
return t.Types[len(t.Types)-1]
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package policy
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
)
|
||||
|
||||
// BearerTokenOptions configures the bearer token policy's behavior.
|
||||
type BearerTokenOptions struct {
|
||||
// AuxiliaryTenants are additional tenant IDs for authenticating cross-tenant requests.
|
||||
// The policy will add a token from each of these tenants to every request. The
|
||||
// authenticating user or service principal must be a guest in these tenants, and the
|
||||
// policy's credential must support multitenant authentication.
|
||||
AuxiliaryTenants []string
|
||||
|
||||
// InsecureAllowCredentialWithHTTP enables authenticated requests over HTTP.
|
||||
// By default, authenticated requests to an HTTP endpoint are rejected by the client.
|
||||
// WARNING: setting this to true will allow sending the authentication key in clear text. Use with caution.
|
||||
InsecureAllowCredentialWithHTTP bool
|
||||
|
||||
// Scopes contains the list of permission scopes required for the token.
|
||||
Scopes []string
|
||||
}
|
||||
|
||||
// RegistrationOptions configures the registration policy's behavior.
|
||||
// All zero-value fields will be initialized with their default values.
|
||||
type RegistrationOptions struct {
|
||||
policy.ClientOptions
|
||||
|
||||
// MaxAttempts is the total number of times to attempt automatic registration
|
||||
// in the event that an attempt fails.
|
||||
// The default value is 3.
|
||||
// Set to a value less than zero to disable the policy.
|
||||
MaxAttempts int
|
||||
|
||||
// PollingDelay is the amount of time to sleep between polling intervals.
|
||||
// The default value is 15 seconds.
|
||||
// A value less than zero means no delay between polling intervals (not recommended).
|
||||
PollingDelay time.Duration
|
||||
|
||||
// PollingDuration is the amount of time to wait before abandoning polling.
|
||||
// The default valule is 5 minutes.
|
||||
// NOTE: Setting this to a small value might cause the policy to prematurely fail.
|
||||
PollingDuration time.Duration
|
||||
|
||||
// StatusCodes contains the slice of custom HTTP status codes to use instead
|
||||
// of the default http.StatusConflict. This should only be set if a service
|
||||
// returns a non-standard HTTP status code when unregistered.
|
||||
StatusCodes []int
|
||||
}
|
||||
|
||||
// ClientOptions contains configuration settings for a client's pipeline.
|
||||
type ClientOptions struct {
|
||||
policy.ClientOptions
|
||||
|
||||
// AuxiliaryTenants are additional tenant IDs for authenticating cross-tenant requests.
|
||||
// The client will add a token from each of these tenants to every request. The
|
||||
// authenticating user or service principal must be a guest in these tenants, and the
|
||||
// client's credential must support multitenant authentication.
|
||||
AuxiliaryTenants []string
|
||||
|
||||
// DisableRPRegistration disables the auto-RP registration policy. Defaults to false.
|
||||
DisableRPRegistration bool
|
||||
}
|
||||
|
||||
// Clone return a deep copy of the current options.
|
||||
func (o *ClientOptions) Clone() *ClientOptions {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
copiedOptions := *o
|
||||
copiedOptions.Cloud.Services = copyMap(copiedOptions.Cloud.Services)
|
||||
copiedOptions.Logging.AllowedHeaders = copyArray(copiedOptions.Logging.AllowedHeaders)
|
||||
copiedOptions.Logging.AllowedQueryParams = copyArray(copiedOptions.Logging.AllowedQueryParams)
|
||||
copiedOptions.Retry.StatusCodes = copyArray(copiedOptions.Retry.StatusCodes)
|
||||
copiedOptions.PerRetryPolicies = copyArray(copiedOptions.PerRetryPolicies)
|
||||
copiedOptions.PerCallPolicies = copyArray(copiedOptions.PerCallPolicies)
|
||||
return &copiedOptions
|
||||
}
|
||||
|
||||
// copyMap return a new map with all the key value pair in the src map
|
||||
func copyMap[K comparable, V any](src map[K]V) map[K]V {
|
||||
if src == nil {
|
||||
return nil
|
||||
}
|
||||
copiedMap := make(map[K]V)
|
||||
for k, v := range src {
|
||||
copiedMap[k] = v
|
||||
}
|
||||
return copiedMap
|
||||
}
|
||||
|
||||
// copyMap return a new array with all the elements in the src array
|
||||
func copyArray[T any](src []T) []T {
|
||||
if src == nil {
|
||||
return nil
|
||||
}
|
||||
copiedArray := make([]T, len(src))
|
||||
copy(copiedArray, src)
|
||||
return copiedArray
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package arm
|
||||
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource"
|
||||
)
|
||||
|
||||
// RootResourceID defines the tenant as the root parent of all other ResourceID.
|
||||
var RootResourceID = resource.RootResourceID
|
||||
|
||||
// ResourceID represents a resource ID such as `/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg`.
|
||||
// Don't create this type directly, use ParseResourceID instead.
|
||||
type ResourceID = resource.ResourceID
|
||||
|
||||
// ParseResourceID parses a string to an instance of ResourceID
|
||||
func ParseResourceID(id string) (*ResourceID, error) {
|
||||
return resource.ParseResourceID(id)
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package arm
|
||||
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource"
|
||||
)
|
||||
|
||||
// SubscriptionResourceType is the ResourceType of a subscription
|
||||
var SubscriptionResourceType = resource.SubscriptionResourceType
|
||||
|
||||
// ResourceGroupResourceType is the ResourceType of a resource group
|
||||
var ResourceGroupResourceType = resource.ResourceGroupResourceType
|
||||
|
||||
// TenantResourceType is the ResourceType of a tenant
|
||||
var TenantResourceType = resource.TenantResourceType
|
||||
|
||||
// ProviderResourceType is the ResourceType of a provider
|
||||
var ProviderResourceType = resource.ProviderResourceType
|
||||
|
||||
// ResourceType represents an Azure resource type, e.g. "Microsoft.Network/virtualNetworks/subnets".
|
||||
// Don't create this type directly, use ParseResourceType or NewResourceType instead.
|
||||
type ResourceType = resource.ResourceType
|
||||
|
||||
// NewResourceType creates an instance of ResourceType using a provider namespace
|
||||
// such as "Microsoft.Network" and type such as "virtualNetworks/subnets".
|
||||
func NewResourceType(providerNamespace, typeName string) ResourceType {
|
||||
return resource.NewResourceType(providerNamespace, typeName)
|
||||
}
|
||||
|
||||
// ParseResourceType parses the ResourceType from a resource type string (e.g. Microsoft.Network/virtualNetworks/subsets)
|
||||
// or a resource identifier string.
|
||||
// e.g. /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRg/providers/Microsoft.Network/virtualNetworks/vnet/subnets/mySubnet)
|
||||
func ParseResourceType(resourceIDOrType string) (ResourceType, error) {
|
||||
return resource.ParseResourceType(resourceIDOrType)
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
armpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
azpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
azruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
|
||||
)
|
||||
|
||||
// NewPipeline creates a pipeline from connection options. Policies from ClientOptions are
|
||||
// placed after policies from PipelineOptions. The telemetry policy, when enabled, will
|
||||
// use the specified module and version info.
|
||||
func NewPipeline(module, version string, cred azcore.TokenCredential, plOpts azruntime.PipelineOptions, options *armpolicy.ClientOptions) (azruntime.Pipeline, error) {
|
||||
if options == nil {
|
||||
options = &armpolicy.ClientOptions{}
|
||||
}
|
||||
conf, err := getConfiguration(&options.ClientOptions)
|
||||
if err != nil {
|
||||
return azruntime.Pipeline{}, err
|
||||
}
|
||||
authPolicy := NewBearerTokenPolicy(cred, &armpolicy.BearerTokenOptions{
|
||||
AuxiliaryTenants: options.AuxiliaryTenants,
|
||||
InsecureAllowCredentialWithHTTP: options.InsecureAllowCredentialWithHTTP,
|
||||
Scopes: []string{conf.Audience + "/.default"},
|
||||
})
|
||||
// we don't want to modify the underlying array in plOpts.PerRetry
|
||||
perRetry := make([]azpolicy.Policy, len(plOpts.PerRetry), len(plOpts.PerRetry)+1)
|
||||
copy(perRetry, plOpts.PerRetry)
|
||||
perRetry = append(perRetry, authPolicy, exported.PolicyFunc(httpTraceNamespacePolicy))
|
||||
plOpts.PerRetry = perRetry
|
||||
if !options.DisableRPRegistration {
|
||||
regRPOpts := armpolicy.RegistrationOptions{ClientOptions: options.ClientOptions}
|
||||
regPolicy, err := NewRPRegistrationPolicy(cred, ®RPOpts)
|
||||
if err != nil {
|
||||
return azruntime.Pipeline{}, err
|
||||
}
|
||||
// we don't want to modify the underlying array in plOpts.PerCall
|
||||
perCall := make([]azpolicy.Policy, len(plOpts.PerCall), len(plOpts.PerCall)+1)
|
||||
copy(perCall, plOpts.PerCall)
|
||||
perCall = append(perCall, regPolicy)
|
||||
plOpts.PerCall = perCall
|
||||
}
|
||||
if plOpts.APIVersion.Name == "" {
|
||||
plOpts.APIVersion.Name = "api-version"
|
||||
}
|
||||
return azruntime.NewPipeline(module, version, plOpts, &options.ClientOptions), nil
|
||||
}
|
||||
|
||||
func getConfiguration(o *azpolicy.ClientOptions) (cloud.ServiceConfiguration, error) {
|
||||
c := cloud.AzurePublic
|
||||
if !reflect.ValueOf(o.Cloud).IsZero() {
|
||||
c = o.Cloud
|
||||
}
|
||||
if conf, ok := c.Services[cloud.ResourceManager]; ok && conf.Endpoint != "" && conf.Audience != "" {
|
||||
return conf, nil
|
||||
} else {
|
||||
return conf, errors.New("provided Cloud field is missing Azure Resource Manager configuration")
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
armpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
azpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
azruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/temporal"
|
||||
)
|
||||
|
||||
const headerAuxiliaryAuthorization = "x-ms-authorization-auxiliary"
|
||||
|
||||
// acquiringResourceState holds data for an auxiliary token request
|
||||
type acquiringResourceState struct {
|
||||
ctx context.Context
|
||||
p *BearerTokenPolicy
|
||||
tenant string
|
||||
}
|
||||
|
||||
// acquireAuxToken acquires a token from an auxiliary tenant. Only one thread/goroutine at a time ever calls this function.
|
||||
func acquireAuxToken(state acquiringResourceState) (newResource azcore.AccessToken, newExpiration time.Time, err error) {
|
||||
tk, err := state.p.cred.GetToken(state.ctx, azpolicy.TokenRequestOptions{
|
||||
EnableCAE: true,
|
||||
Scopes: state.p.scopes,
|
||||
TenantID: state.tenant,
|
||||
})
|
||||
if err != nil {
|
||||
return azcore.AccessToken{}, time.Time{}, err
|
||||
}
|
||||
return tk, tk.ExpiresOn, nil
|
||||
}
|
||||
|
||||
// BearerTokenPolicy authorizes requests with bearer tokens acquired from a TokenCredential.
|
||||
type BearerTokenPolicy struct {
|
||||
auxResources map[string]*temporal.Resource[azcore.AccessToken, acquiringResourceState]
|
||||
btp *azruntime.BearerTokenPolicy
|
||||
cred azcore.TokenCredential
|
||||
scopes []string
|
||||
}
|
||||
|
||||
// NewBearerTokenPolicy creates a policy object that authorizes requests with bearer tokens.
|
||||
// cred: an azcore.TokenCredential implementation such as a credential object from azidentity
|
||||
// opts: optional settings. Pass nil to accept default values; this is the same as passing a zero-value options.
|
||||
func NewBearerTokenPolicy(cred azcore.TokenCredential, opts *armpolicy.BearerTokenOptions) *BearerTokenPolicy {
|
||||
if opts == nil {
|
||||
opts = &armpolicy.BearerTokenOptions{}
|
||||
}
|
||||
p := &BearerTokenPolicy{cred: cred}
|
||||
p.auxResources = make(map[string]*temporal.Resource[azcore.AccessToken, acquiringResourceState], len(opts.AuxiliaryTenants))
|
||||
for _, t := range opts.AuxiliaryTenants {
|
||||
p.auxResources[t] = temporal.NewResource(acquireAuxToken)
|
||||
}
|
||||
p.scopes = make([]string, len(opts.Scopes))
|
||||
copy(p.scopes, opts.Scopes)
|
||||
p.btp = azruntime.NewBearerTokenPolicy(cred, opts.Scopes, &azpolicy.BearerTokenOptions{
|
||||
InsecureAllowCredentialWithHTTP: opts.InsecureAllowCredentialWithHTTP,
|
||||
AuthorizationHandler: azpolicy.AuthorizationHandler{
|
||||
OnRequest: p.onRequest,
|
||||
},
|
||||
})
|
||||
return p
|
||||
}
|
||||
|
||||
// onRequest authorizes requests with one or more bearer tokens
|
||||
func (b *BearerTokenPolicy) onRequest(req *azpolicy.Request, authNZ func(azpolicy.TokenRequestOptions) error) error {
|
||||
// authorize the request with a token for the primary tenant
|
||||
err := authNZ(azpolicy.TokenRequestOptions{Scopes: b.scopes})
|
||||
if err != nil || len(b.auxResources) == 0 {
|
||||
return err
|
||||
}
|
||||
// add tokens for auxiliary tenants
|
||||
as := acquiringResourceState{
|
||||
ctx: req.Raw().Context(),
|
||||
p: b,
|
||||
}
|
||||
auxTokens := make([]string, 0, len(b.auxResources))
|
||||
for tenant, er := range b.auxResources {
|
||||
as.tenant = tenant
|
||||
auxTk, err := er.Get(as)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
auxTokens = append(auxTokens, fmt.Sprintf("%s%s", shared.BearerTokenPrefix, auxTk.Token))
|
||||
}
|
||||
req.Raw().Header.Set(headerAuxiliaryAuthorization, strings.Join(auxTokens, ", "))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Do authorizes a request with a bearer token
|
||||
func (b *BearerTokenPolicy) Do(req *azpolicy.Request) (*http.Response, error) {
|
||||
return b.btp.Do(req)
|
||||
}
|
||||
@@ -1,322 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource"
|
||||
armpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
azpolicy "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
|
||||
)
|
||||
|
||||
const (
|
||||
// LogRPRegistration entries contain information specific to the automatic registration of an RP.
|
||||
// Entries of this classification are written IFF the policy needs to take any action.
|
||||
LogRPRegistration log.Event = "RPRegistration"
|
||||
)
|
||||
|
||||
// init sets any default values
|
||||
func setDefaults(r *armpolicy.RegistrationOptions) {
|
||||
if r.MaxAttempts == 0 {
|
||||
r.MaxAttempts = 3
|
||||
} else if r.MaxAttempts < 0 {
|
||||
r.MaxAttempts = 0
|
||||
}
|
||||
if r.PollingDelay == 0 {
|
||||
r.PollingDelay = 15 * time.Second
|
||||
} else if r.PollingDelay < 0 {
|
||||
r.PollingDelay = 0
|
||||
}
|
||||
if r.PollingDuration == 0 {
|
||||
r.PollingDuration = 5 * time.Minute
|
||||
}
|
||||
if len(r.StatusCodes) == 0 {
|
||||
r.StatusCodes = []int{http.StatusConflict}
|
||||
}
|
||||
}
|
||||
|
||||
// NewRPRegistrationPolicy creates a policy object configured using the specified options.
|
||||
// The policy controls whether an unregistered resource provider should automatically be
|
||||
// registered. See https://aka.ms/rps-not-found for more information.
|
||||
func NewRPRegistrationPolicy(cred azcore.TokenCredential, o *armpolicy.RegistrationOptions) (azpolicy.Policy, error) {
|
||||
if o == nil {
|
||||
o = &armpolicy.RegistrationOptions{}
|
||||
}
|
||||
conf, err := getConfiguration(&o.ClientOptions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authPolicy := NewBearerTokenPolicy(cred, &armpolicy.BearerTokenOptions{Scopes: []string{conf.Audience + "/.default"}})
|
||||
p := &rpRegistrationPolicy{
|
||||
endpoint: conf.Endpoint,
|
||||
pipeline: runtime.NewPipeline(shared.Module, shared.Version, runtime.PipelineOptions{PerRetry: []azpolicy.Policy{authPolicy}}, &o.ClientOptions),
|
||||
options: *o,
|
||||
}
|
||||
// init the copy
|
||||
setDefaults(&p.options)
|
||||
return p, nil
|
||||
}
|
||||
|
||||
type rpRegistrationPolicy struct {
|
||||
endpoint string
|
||||
pipeline runtime.Pipeline
|
||||
options armpolicy.RegistrationOptions
|
||||
}
|
||||
|
||||
func (r *rpRegistrationPolicy) Do(req *azpolicy.Request) (*http.Response, error) {
|
||||
if r.options.MaxAttempts == 0 {
|
||||
// policy is disabled
|
||||
return req.Next()
|
||||
}
|
||||
const registeredState = "Registered"
|
||||
var rp string
|
||||
var resp *http.Response
|
||||
for attempts := 0; attempts < r.options.MaxAttempts; attempts++ {
|
||||
var err error
|
||||
// make the original request
|
||||
resp, err = req.Next()
|
||||
// getting a 409 is the first indication that the RP might need to be registered, check error response
|
||||
if err != nil || !runtime.HasStatusCode(resp, r.options.StatusCodes...) {
|
||||
return resp, err
|
||||
}
|
||||
var reqErr requestError
|
||||
if err = runtime.UnmarshalAsJSON(resp, &reqErr); err != nil {
|
||||
return resp, err
|
||||
}
|
||||
if reqErr.ServiceError == nil {
|
||||
// missing service error info. just return the response
|
||||
// to the caller so its error unmarshalling will kick in
|
||||
return resp, err
|
||||
}
|
||||
if !isUnregisteredRPCode(reqErr.ServiceError.Code) {
|
||||
// not a 409 due to unregistered RP. just return the response
|
||||
// to the caller so its error unmarshalling will kick in
|
||||
return resp, err
|
||||
}
|
||||
res, err := resource.ParseResourceID(req.Raw().URL.Path)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
rp = res.ResourceType.Namespace
|
||||
logRegistrationExit := func(v any) {
|
||||
log.Writef(LogRPRegistration, "END registration for %s: %v", rp, v)
|
||||
}
|
||||
log.Writef(LogRPRegistration, "BEGIN registration for %s", rp)
|
||||
// create client and make the registration request
|
||||
// we use the scheme and host from the original request
|
||||
rpOps := &providersOperations{
|
||||
p: r.pipeline,
|
||||
u: r.endpoint,
|
||||
subID: res.SubscriptionID,
|
||||
}
|
||||
if _, err = rpOps.Register(&shared.ContextWithDeniedValues{Context: req.Raw().Context()}, rp); err != nil {
|
||||
logRegistrationExit(err)
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// RP was registered, however we need to wait for the registration to complete
|
||||
pollCtx, pollCancel := context.WithTimeout(&shared.ContextWithDeniedValues{Context: req.Raw().Context()}, r.options.PollingDuration)
|
||||
var lastRegState string
|
||||
for {
|
||||
// get the current registration state
|
||||
getResp, err := rpOps.Get(pollCtx, rp)
|
||||
if err != nil {
|
||||
pollCancel()
|
||||
logRegistrationExit(err)
|
||||
return resp, err
|
||||
}
|
||||
if getResp.Provider.RegistrationState != nil && !strings.EqualFold(*getResp.Provider.RegistrationState, lastRegState) {
|
||||
// registration state has changed, or was updated for the first time
|
||||
lastRegState = *getResp.Provider.RegistrationState
|
||||
log.Writef(LogRPRegistration, "registration state is %s", lastRegState)
|
||||
}
|
||||
if strings.EqualFold(lastRegState, registeredState) {
|
||||
// registration complete
|
||||
pollCancel()
|
||||
logRegistrationExit(lastRegState)
|
||||
break
|
||||
}
|
||||
// wait before trying again
|
||||
select {
|
||||
case <-time.After(r.options.PollingDelay):
|
||||
// continue polling
|
||||
case <-pollCtx.Done():
|
||||
pollCancel()
|
||||
logRegistrationExit(pollCtx.Err())
|
||||
return resp, pollCtx.Err()
|
||||
}
|
||||
}
|
||||
// RP was successfully registered, retry the original request
|
||||
err = req.RewindBody()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
// if we get here it means we exceeded the number of attempts
|
||||
return resp, fmt.Errorf("exceeded attempts to register %s", rp)
|
||||
}
|
||||
|
||||
var unregisteredRPCodes = []string{
|
||||
"MissingSubscriptionRegistration",
|
||||
"MissingRegistrationForResourceProvider",
|
||||
"Subscription Not Registered",
|
||||
"SubscriptionNotRegistered",
|
||||
}
|
||||
|
||||
func isUnregisteredRPCode(errorCode string) bool {
|
||||
for _, code := range unregisteredRPCodes {
|
||||
if strings.EqualFold(errorCode, code) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// minimal error definitions to simplify detection
|
||||
type requestError struct {
|
||||
ServiceError *serviceError `json:"error"`
|
||||
}
|
||||
|
||||
type serviceError struct {
|
||||
Code string `json:"code"`
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// the following code was copied from module armresources, providers.go and models.go
|
||||
// only the minimum amount of code was copied to get this working and some edits were made.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type providersOperations struct {
|
||||
p runtime.Pipeline
|
||||
u string
|
||||
subID string
|
||||
}
|
||||
|
||||
// Get - Gets the specified resource provider.
|
||||
func (client *providersOperations) Get(ctx context.Context, resourceProviderNamespace string) (providerResponse, error) {
|
||||
req, err := client.getCreateRequest(ctx, resourceProviderNamespace)
|
||||
if err != nil {
|
||||
return providerResponse{}, err
|
||||
}
|
||||
resp, err := client.p.Do(req)
|
||||
if err != nil {
|
||||
return providerResponse{}, err
|
||||
}
|
||||
result, err := client.getHandleResponse(resp)
|
||||
if err != nil {
|
||||
return providerResponse{}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// getCreateRequest creates the Get request.
|
||||
func (client *providersOperations) getCreateRequest(ctx context.Context, resourceProviderNamespace string) (*azpolicy.Request, error) {
|
||||
urlPath := "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}"
|
||||
urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace))
|
||||
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subID))
|
||||
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.u, urlPath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := req.Raw().URL.Query()
|
||||
query.Set("api-version", "2019-05-01")
|
||||
req.Raw().URL.RawQuery = query.Encode()
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// getHandleResponse handles the Get response.
|
||||
func (client *providersOperations) getHandleResponse(resp *http.Response) (providerResponse, error) {
|
||||
if !runtime.HasStatusCode(resp, http.StatusOK) {
|
||||
return providerResponse{}, exported.NewResponseError(resp)
|
||||
}
|
||||
result := providerResponse{RawResponse: resp}
|
||||
err := runtime.UnmarshalAsJSON(resp, &result.Provider)
|
||||
if err != nil {
|
||||
return providerResponse{}, err
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
// Register - Registers a subscription with a resource provider.
|
||||
func (client *providersOperations) Register(ctx context.Context, resourceProviderNamespace string) (providerResponse, error) {
|
||||
req, err := client.registerCreateRequest(ctx, resourceProviderNamespace)
|
||||
if err != nil {
|
||||
return providerResponse{}, err
|
||||
}
|
||||
resp, err := client.p.Do(req)
|
||||
if err != nil {
|
||||
return providerResponse{}, err
|
||||
}
|
||||
result, err := client.registerHandleResponse(resp)
|
||||
if err != nil {
|
||||
return providerResponse{}, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// registerCreateRequest creates the Register request.
|
||||
func (client *providersOperations) registerCreateRequest(ctx context.Context, resourceProviderNamespace string) (*azpolicy.Request, error) {
|
||||
urlPath := "/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register"
|
||||
urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace))
|
||||
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subID))
|
||||
req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.u, urlPath))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := req.Raw().URL.Query()
|
||||
query.Set("api-version", "2019-05-01")
|
||||
req.Raw().URL.RawQuery = query.Encode()
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// registerHandleResponse handles the Register response.
|
||||
func (client *providersOperations) registerHandleResponse(resp *http.Response) (providerResponse, error) {
|
||||
if !runtime.HasStatusCode(resp, http.StatusOK) {
|
||||
return providerResponse{}, exported.NewResponseError(resp)
|
||||
}
|
||||
result := providerResponse{RawResponse: resp}
|
||||
err := runtime.UnmarshalAsJSON(resp, &result.Provider)
|
||||
if err != nil {
|
||||
return providerResponse{}, err
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
// ProviderResponse is the response envelope for operations that return a Provider type.
|
||||
type providerResponse struct {
|
||||
// Resource provider information.
|
||||
Provider *provider
|
||||
|
||||
// RawResponse contains the underlying HTTP response.
|
||||
RawResponse *http.Response
|
||||
}
|
||||
|
||||
// Provider - Resource provider information.
|
||||
type provider struct {
|
||||
// The provider ID.
|
||||
ID *string `json:"id,omitempty"`
|
||||
|
||||
// The namespace of the resource provider.
|
||||
Namespace *string `json:"namespace,omitempty"`
|
||||
|
||||
// The registration policy of the resource provider.
|
||||
RegistrationPolicy *string `json:"registrationPolicy,omitempty"`
|
||||
|
||||
// The registration state of the resource provider.
|
||||
RegistrationState *string `json:"registrationState,omitempty"`
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/internal/resource"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
|
||||
)
|
||||
|
||||
// httpTraceNamespacePolicy is a policy that adds the az.namespace attribute to the current Span
|
||||
func httpTraceNamespacePolicy(req *policy.Request) (resp *http.Response, err error) {
|
||||
rawTracer := req.Raw().Context().Value(shared.CtxWithTracingTracer{})
|
||||
if tracer, ok := rawTracer.(tracing.Tracer); ok && tracer.Enabled() {
|
||||
rt, err := resource.ParseResourceType(req.Raw().URL.Path)
|
||||
if err == nil {
|
||||
// add the namespace attribute to the current span
|
||||
span := tracer.SpanFromContext(req.Raw().Context())
|
||||
span.SetAttributes(tracing.Attribute{Key: shared.TracingNamespaceAttrName, Value: rt.Namespace})
|
||||
}
|
||||
}
|
||||
return req.Next()
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
//go:build go1.16
|
||||
// +build go1.16
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
|
||||
|
||||
func init() {
|
||||
cloud.AzureChina.Services[cloud.ResourceManager] = cloud.ServiceConfiguration{
|
||||
Audience: "https://management.core.chinacloudapi.cn",
|
||||
Endpoint: "https://management.chinacloudapi.cn",
|
||||
}
|
||||
cloud.AzureGovernment.Services[cloud.ResourceManager] = cloud.ServiceConfiguration{
|
||||
Audience: "https://management.core.usgovcloudapi.net",
|
||||
Endpoint: "https://management.usgovcloudapi.net",
|
||||
}
|
||||
cloud.AzurePublic.Services[cloud.ResourceManager] = cloud.ServiceConfiguration{
|
||||
Audience: "https://management.core.windows.net/",
|
||||
Endpoint: "https://management.azure.com",
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file.
|
||||
trigger:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
- feature/*
|
||||
- hotfix/*
|
||||
- release/*
|
||||
paths:
|
||||
include:
|
||||
- sdk/azcore/
|
||||
- eng/
|
||||
|
||||
pr:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
- feature/*
|
||||
- hotfix/*
|
||||
- release/*
|
||||
paths:
|
||||
include:
|
||||
- sdk/azcore/
|
||||
- eng/
|
||||
|
||||
extends:
|
||||
template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml
|
||||
parameters:
|
||||
ServiceDirectory: azcore
|
||||
@@ -1,44 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package cloud
|
||||
|
||||
var (
|
||||
// AzureChina contains configuration for Azure China.
|
||||
AzureChina = Configuration{
|
||||
ActiveDirectoryAuthorityHost: "https://login.chinacloudapi.cn/", Services: map[ServiceName]ServiceConfiguration{},
|
||||
}
|
||||
// AzureGovernment contains configuration for Azure Government.
|
||||
AzureGovernment = Configuration{
|
||||
ActiveDirectoryAuthorityHost: "https://login.microsoftonline.us/", Services: map[ServiceName]ServiceConfiguration{},
|
||||
}
|
||||
// AzurePublic contains configuration for Azure Public Cloud.
|
||||
AzurePublic = Configuration{
|
||||
ActiveDirectoryAuthorityHost: "https://login.microsoftonline.com/", Services: map[ServiceName]ServiceConfiguration{},
|
||||
}
|
||||
)
|
||||
|
||||
// ServiceName identifies a cloud service.
|
||||
type ServiceName string
|
||||
|
||||
// ResourceManager is a global constant identifying Azure Resource Manager.
|
||||
const ResourceManager ServiceName = "resourceManager"
|
||||
|
||||
// ServiceConfiguration configures a specific cloud service such as Azure Resource Manager.
|
||||
type ServiceConfiguration struct {
|
||||
// Audience is the audience the client will request for its access tokens.
|
||||
Audience string
|
||||
// Endpoint is the service's base URL.
|
||||
Endpoint string
|
||||
}
|
||||
|
||||
// Configuration configures a cloud.
|
||||
type Configuration struct {
|
||||
// ActiveDirectoryAuthorityHost is the base URL of the cloud's Azure Active Directory.
|
||||
ActiveDirectoryAuthorityHost string
|
||||
// Services contains configuration for the cloud's services.
|
||||
Services map[ServiceName]ServiceConfiguration
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
//go:build go1.16
|
||||
// +build go1.16
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
/*
|
||||
Package cloud implements a configuration API for applications deployed to sovereign or private Azure clouds.
|
||||
|
||||
Azure SDK client configuration defaults are appropriate for Azure Public Cloud (sometimes referred to as
|
||||
"Azure Commercial" or simply "Microsoft Azure"). This package enables applications deployed to other
|
||||
Azure Clouds to configure clients appropriately.
|
||||
|
||||
This package contains predefined configuration for well-known sovereign clouds such as Azure Government and
|
||||
Azure China. Azure SDK clients accept this configuration via the Cloud field of azcore.ClientOptions. For
|
||||
example, configuring a credential and ARM client for Azure Government:
|
||||
|
||||
opts := azcore.ClientOptions{Cloud: cloud.AzureGovernment}
|
||||
cred, err := azidentity.NewDefaultAzureCredential(
|
||||
&azidentity.DefaultAzureCredentialOptions{ClientOptions: opts},
|
||||
)
|
||||
handle(err)
|
||||
|
||||
client, err := armsubscription.NewClient(
|
||||
cred, &arm.ClientOptions{ClientOptions: opts},
|
||||
)
|
||||
handle(err)
|
||||
|
||||
Applications deployed to a private cloud such as Azure Stack create a Configuration object with
|
||||
appropriate values:
|
||||
|
||||
c := cloud.Configuration{
|
||||
ActiveDirectoryAuthorityHost: "https://...",
|
||||
Services: map[cloud.ServiceName]cloud.ServiceConfiguration{
|
||||
cloud.ResourceManager: {
|
||||
Audience: "...",
|
||||
Endpoint: "https://...",
|
||||
},
|
||||
},
|
||||
}
|
||||
opts := azcore.ClientOptions{Cloud: c}
|
||||
|
||||
cred, err := azidentity.NewDefaultAzureCredential(
|
||||
&azidentity.DefaultAzureCredentialOptions{ClientOptions: opts},
|
||||
)
|
||||
handle(err)
|
||||
|
||||
client, err := armsubscription.NewClient(
|
||||
cred, &arm.ClientOptions{ClientOptions: opts},
|
||||
)
|
||||
handle(err)
|
||||
*/
|
||||
package cloud
|
||||
173
cluster-api/providers/azurestack/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/core.go
generated
vendored
173
cluster-api/providers/azurestack/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/core.go
generated
vendored
@@ -1,173 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package azcore
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
|
||||
)
|
||||
|
||||
// AccessToken represents an Azure service bearer access token with expiry information.
|
||||
type AccessToken = exported.AccessToken
|
||||
|
||||
// TokenCredential represents a credential capable of providing an OAuth token.
|
||||
type TokenCredential = exported.TokenCredential
|
||||
|
||||
// KeyCredential contains an authentication key used to authenticate to an Azure service.
|
||||
type KeyCredential = exported.KeyCredential
|
||||
|
||||
// NewKeyCredential creates a new instance of [KeyCredential] with the specified values.
|
||||
// - key is the authentication key
|
||||
func NewKeyCredential(key string) *KeyCredential {
|
||||
return exported.NewKeyCredential(key)
|
||||
}
|
||||
|
||||
// SASCredential contains a shared access signature used to authenticate to an Azure service.
|
||||
type SASCredential = exported.SASCredential
|
||||
|
||||
// NewSASCredential creates a new instance of [SASCredential] with the specified values.
|
||||
// - sas is the shared access signature
|
||||
func NewSASCredential(sas string) *SASCredential {
|
||||
return exported.NewSASCredential(sas)
|
||||
}
|
||||
|
||||
// holds sentinel values used to send nulls
|
||||
var nullables map[reflect.Type]any = map[reflect.Type]any{}
|
||||
var nullablesMu sync.RWMutex
|
||||
|
||||
// NullValue is used to send an explicit 'null' within a request.
|
||||
// This is typically used in JSON-MERGE-PATCH operations to delete a value.
|
||||
func NullValue[T any]() T {
|
||||
t := shared.TypeOfT[T]()
|
||||
|
||||
nullablesMu.RLock()
|
||||
v, found := nullables[t]
|
||||
nullablesMu.RUnlock()
|
||||
|
||||
if found {
|
||||
// return the sentinel object
|
||||
return v.(T)
|
||||
}
|
||||
|
||||
// promote to exclusive lock and check again (double-checked locking pattern)
|
||||
nullablesMu.Lock()
|
||||
defer nullablesMu.Unlock()
|
||||
v, found = nullables[t]
|
||||
|
||||
if !found {
|
||||
var o reflect.Value
|
||||
if k := t.Kind(); k == reflect.Map {
|
||||
o = reflect.MakeMap(t)
|
||||
} else if k == reflect.Slice {
|
||||
// empty slices appear to all point to the same data block
|
||||
// which causes comparisons to become ambiguous. so we create
|
||||
// a slice with len/cap of one which ensures a unique address.
|
||||
o = reflect.MakeSlice(t, 1, 1)
|
||||
} else {
|
||||
o = reflect.New(t.Elem())
|
||||
}
|
||||
v = o.Interface()
|
||||
nullables[t] = v
|
||||
}
|
||||
// return the sentinel object
|
||||
return v.(T)
|
||||
}
|
||||
|
||||
// IsNullValue returns true if the field contains a null sentinel value.
|
||||
// This is used by custom marshallers to properly encode a null value.
|
||||
func IsNullValue[T any](v T) bool {
|
||||
// see if our map has a sentinel object for this *T
|
||||
t := reflect.TypeOf(v)
|
||||
nullablesMu.RLock()
|
||||
defer nullablesMu.RUnlock()
|
||||
|
||||
if o, found := nullables[t]; found {
|
||||
o1 := reflect.ValueOf(o)
|
||||
v1 := reflect.ValueOf(v)
|
||||
// we found it; return true if v points to the sentinel object.
|
||||
// NOTE: maps and slices can only be compared to nil, else you get
|
||||
// a runtime panic. so we compare addresses instead.
|
||||
return o1.Pointer() == v1.Pointer()
|
||||
}
|
||||
// no sentinel object for this *t
|
||||
return false
|
||||
}
|
||||
|
||||
// ClientOptions contains optional settings for a client's pipeline.
|
||||
// Instances can be shared across calls to SDK client constructors when uniform configuration is desired.
|
||||
// Zero-value fields will have their specified default values applied during use.
|
||||
type ClientOptions = policy.ClientOptions
|
||||
|
||||
// Client is a basic HTTP client. It consists of a pipeline and tracing provider.
|
||||
type Client struct {
|
||||
pl runtime.Pipeline
|
||||
tr tracing.Tracer
|
||||
|
||||
// cached on the client to support shallow copying with new values
|
||||
tp tracing.Provider
|
||||
modVer string
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewClient creates a new Client instance with the provided values.
|
||||
// - moduleName - the fully qualified name of the module where the client is defined; used by the telemetry policy and tracing provider.
|
||||
// - moduleVersion - the semantic version of the module; used by the telemetry policy and tracing provider.
|
||||
// - plOpts - pipeline configuration options; can be the zero-value
|
||||
// - options - optional client configurations; pass nil to accept the default values
|
||||
func NewClient(moduleName, moduleVersion string, plOpts runtime.PipelineOptions, options *ClientOptions) (*Client, error) {
|
||||
if options == nil {
|
||||
options = &ClientOptions{}
|
||||
}
|
||||
|
||||
if !options.Telemetry.Disabled {
|
||||
if err := shared.ValidateModVer(moduleVersion); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
pl := runtime.NewPipeline(moduleName, moduleVersion, plOpts, options)
|
||||
|
||||
tr := options.TracingProvider.NewTracer(moduleName, moduleVersion)
|
||||
if tr.Enabled() && plOpts.Tracing.Namespace != "" {
|
||||
tr.SetAttributes(tracing.Attribute{Key: shared.TracingNamespaceAttrName, Value: plOpts.Tracing.Namespace})
|
||||
}
|
||||
|
||||
return &Client{
|
||||
pl: pl,
|
||||
tr: tr,
|
||||
tp: options.TracingProvider,
|
||||
modVer: moduleVersion,
|
||||
namespace: plOpts.Tracing.Namespace,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Pipeline returns the pipeline for this client.
|
||||
func (c *Client) Pipeline() runtime.Pipeline {
|
||||
return c.pl
|
||||
}
|
||||
|
||||
// Tracer returns the tracer for this client.
|
||||
func (c *Client) Tracer() tracing.Tracer {
|
||||
return c.tr
|
||||
}
|
||||
|
||||
// WithClientName returns a shallow copy of the Client with its tracing client name changed to clientName.
|
||||
// Note that the values for module name and version will be preserved from the source Client.
|
||||
// - clientName - the fully qualified name of the client ("package.Client"); this is used by the tracing provider when creating spans
|
||||
func (c *Client) WithClientName(clientName string) *Client {
|
||||
tr := c.tp.NewTracer(clientName, c.modVer)
|
||||
if tr.Enabled() && c.namespace != "" {
|
||||
tr.SetAttributes(tracing.Attribute{Key: shared.TracingNamespaceAttrName, Value: c.namespace})
|
||||
}
|
||||
return &Client{pl: c.pl, tr: tr, tp: c.tp, modVer: c.modVer, namespace: c.namespace}
|
||||
}
|
||||
264
cluster-api/providers/azurestack/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/doc.go
generated
vendored
264
cluster-api/providers/azurestack/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/doc.go
generated
vendored
@@ -1,264 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
||||
// Use of this source code is governed by an MIT
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package azcore implements an HTTP request/response middleware pipeline used by Azure SDK clients.
|
||||
|
||||
The middleware consists of three components.
|
||||
|
||||
- One or more Policy instances.
|
||||
- A Transporter instance.
|
||||
- A Pipeline instance that combines the Policy and Transporter instances.
|
||||
|
||||
# Implementing the Policy Interface
|
||||
|
||||
A Policy can be implemented in two ways; as a first-class function for a stateless Policy, or as
|
||||
a method on a type for a stateful Policy. Note that HTTP requests made via the same pipeline share
|
||||
the same Policy instances, so if a Policy mutates its state it MUST be properly synchronized to
|
||||
avoid race conditions.
|
||||
|
||||
A Policy's Do method is called when an HTTP request wants to be sent over the network. The Do method can
|
||||
perform any operation(s) it desires. For example, it can log the outgoing request, mutate the URL, headers,
|
||||
and/or query parameters, inject a failure, etc. Once the Policy has successfully completed its request
|
||||
work, it must call the Next() method on the *policy.Request instance in order to pass the request to the
|
||||
next Policy in the chain.
|
||||
|
||||
When an HTTP response comes back, the Policy then gets a chance to process the response/error. The Policy instance
|
||||
can log the response, retry the operation if it failed due to a transient error or timeout, unmarshal the response
|
||||
body, etc. Once the Policy has successfully completed its response work, it must return the *http.Response
|
||||
and error instances to its caller.
|
||||
|
||||
Template for implementing a stateless Policy:
|
||||
|
||||
type policyFunc func(*policy.Request) (*http.Response, error)
|
||||
|
||||
// Do implements the Policy interface on policyFunc.
|
||||
func (pf policyFunc) Do(req *policy.Request) (*http.Response, error) {
|
||||
return pf(req)
|
||||
}
|
||||
|
||||
func NewMyStatelessPolicy() policy.Policy {
|
||||
return policyFunc(func(req *policy.Request) (*http.Response, error) {
|
||||
// TODO: mutate/process Request here
|
||||
|
||||
// forward Request to next Policy & get Response/error
|
||||
resp, err := req.Next()
|
||||
|
||||
// TODO: mutate/process Response/error here
|
||||
|
||||
// return Response/error to previous Policy
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
|
||||
Template for implementing a stateful Policy:
|
||||
|
||||
type MyStatefulPolicy struct {
|
||||
// TODO: add configuration/setting fields here
|
||||
}
|
||||
|
||||
// TODO: add initialization args to NewMyStatefulPolicy()
|
||||
func NewMyStatefulPolicy() policy.Policy {
|
||||
return &MyStatefulPolicy{
|
||||
// TODO: initialize configuration/setting fields here
|
||||
}
|
||||
}
|
||||
|
||||
func (p *MyStatefulPolicy) Do(req *policy.Request) (resp *http.Response, err error) {
|
||||
// TODO: mutate/process Request here
|
||||
|
||||
// forward Request to next Policy & get Response/error
|
||||
resp, err := req.Next()
|
||||
|
||||
// TODO: mutate/process Response/error here
|
||||
|
||||
// return Response/error to previous Policy
|
||||
return resp, err
|
||||
}
|
||||
|
||||
# Implementing the Transporter Interface
|
||||
|
||||
The Transporter interface is responsible for sending the HTTP request and returning the corresponding
|
||||
HTTP response or error. The Transporter is invoked by the last Policy in the chain. The default Transporter
|
||||
implementation uses a shared http.Client from the standard library.
|
||||
|
||||
The same stateful/stateless rules for Policy implementations apply to Transporter implementations.
|
||||
|
||||
# Using Policy and Transporter Instances Via a Pipeline
|
||||
|
||||
To use the Policy and Transporter instances, an application passes them to the runtime.NewPipeline function.
|
||||
|
||||
func NewPipeline(transport Transporter, policies ...Policy) Pipeline
|
||||
|
||||
The specified Policy instances form a chain and are invoked in the order provided to NewPipeline
|
||||
followed by the Transporter.
|
||||
|
||||
Once the Pipeline has been created, create a runtime.Request instance and pass it to Pipeline's Do method.
|
||||
|
||||
func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*Request, error)
|
||||
|
||||
func (p Pipeline) Do(req *Request) (*http.Request, error)
|
||||
|
||||
The Pipeline.Do method sends the specified Request through the chain of Policy and Transporter
|
||||
instances. The response/error is then sent through the same chain of Policy instances in reverse
|
||||
order. For example, assuming there are Policy types PolicyA, PolicyB, and PolicyC along with
|
||||
TransportA.
|
||||
|
||||
pipeline := NewPipeline(TransportA, PolicyA, PolicyB, PolicyC)
|
||||
|
||||
The flow of Request and Response looks like the following:
|
||||
|
||||
policy.Request -> PolicyA -> PolicyB -> PolicyC -> TransportA -----+
|
||||
|
|
||||
HTTP(S) endpoint
|
||||
|
|
||||
caller <--------- PolicyA <- PolicyB <- PolicyC <- http.Response-+
|
||||
|
||||
# Creating a Request Instance
|
||||
|
||||
The Request instance passed to Pipeline's Do method is a wrapper around an *http.Request. It also
|
||||
contains some internal state and provides various convenience methods. You create a Request instance
|
||||
by calling the runtime.NewRequest function:
|
||||
|
||||
func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*Request, error)
|
||||
|
||||
If the Request should contain a body, call the SetBody method.
|
||||
|
||||
func (req *Request) SetBody(body ReadSeekCloser, contentType string) error
|
||||
|
||||
A seekable stream is required so that upon retry, the retry Policy instance can seek the stream
|
||||
back to the beginning before retrying the network request and re-uploading the body.
|
||||
|
||||
# Sending an Explicit Null
|
||||
|
||||
Operations like JSON-MERGE-PATCH send a JSON null to indicate a value should be deleted.
|
||||
|
||||
{
|
||||
"delete-me": null
|
||||
}
|
||||
|
||||
This requirement conflicts with the SDK's default marshalling that specifies "omitempty" as
|
||||
a means to resolve the ambiguity between a field to be excluded and its zero-value.
|
||||
|
||||
type Widget struct {
|
||||
Name *string `json:",omitempty"`
|
||||
Count *int `json:",omitempty"`
|
||||
}
|
||||
|
||||
In the above example, Name and Count are defined as pointer-to-type to disambiguate between
|
||||
a missing value (nil) and a zero-value (0) which might have semantic differences.
|
||||
|
||||
In a PATCH operation, any fields left as nil are to have their values preserved. When updating
|
||||
a Widget's count, one simply specifies the new value for Count, leaving Name nil.
|
||||
|
||||
To fulfill the requirement for sending a JSON null, the NullValue() function can be used.
|
||||
|
||||
w := Widget{
|
||||
Count: azcore.NullValue[*int](),
|
||||
}
|
||||
|
||||
This sends an explict "null" for Count, indicating that any current value for Count should be deleted.
|
||||
|
||||
# Processing the Response
|
||||
|
||||
When the HTTP response is received, the *http.Response is returned directly. Each Policy instance
|
||||
can inspect/mutate the *http.Response.
|
||||
|
||||
# Built-in Logging
|
||||
|
||||
To enable logging, set environment variable AZURE_SDK_GO_LOGGING to "all" before executing your program.
|
||||
|
||||
By default the logger writes to stderr. This can be customized by calling log.SetListener, providing
|
||||
a callback that writes to the desired location. Any custom logging implementation MUST provide its
|
||||
own synchronization to handle concurrent invocations.
|
||||
|
||||
See the docs for the log package for further details.
|
||||
|
||||
# Pageable Operations
|
||||
|
||||
Pageable operations return potentially large data sets spread over multiple GET requests. The result of
|
||||
each GET is a "page" of data consisting of a slice of items.
|
||||
|
||||
Pageable operations can be identified by their New*Pager naming convention and return type of *runtime.Pager[T].
|
||||
|
||||
func (c *WidgetClient) NewListWidgetsPager(o *Options) *runtime.Pager[PageResponse]
|
||||
|
||||
The call to WidgetClient.NewListWidgetsPager() returns an instance of *runtime.Pager[T] for fetching pages
|
||||
and determining if there are more pages to fetch. No IO calls are made until the NextPage() method is invoked.
|
||||
|
||||
pager := widgetClient.NewListWidgetsPager(nil)
|
||||
for pager.More() {
|
||||
page, err := pager.NextPage(context.TODO())
|
||||
// handle err
|
||||
for _, widget := range page.Values {
|
||||
// process widget
|
||||
}
|
||||
}
|
||||
|
||||
# Long-Running Operations
|
||||
|
||||
Long-running operations (LROs) are operations consisting of an initial request to start the operation followed
|
||||
by polling to determine when the operation has reached a terminal state. An LRO's terminal state is one
|
||||
of the following values.
|
||||
|
||||
- Succeeded - the LRO completed successfully
|
||||
- Failed - the LRO failed to complete
|
||||
- Canceled - the LRO was canceled
|
||||
|
||||
LROs can be identified by their Begin* prefix and their return type of *runtime.Poller[T].
|
||||
|
||||
func (c *WidgetClient) BeginCreateOrUpdate(ctx context.Context, w Widget, o *Options) (*runtime.Poller[Response], error)
|
||||
|
||||
When a call to WidgetClient.BeginCreateOrUpdate() returns a nil error, it means that the LRO has started.
|
||||
It does _not_ mean that the widget has been created or updated (or failed to be created/updated).
|
||||
|
||||
The *runtime.Poller[T] provides APIs for determining the state of the LRO. To wait for the LRO to complete,
|
||||
call the PollUntilDone() method.
|
||||
|
||||
poller, err := widgetClient.BeginCreateOrUpdate(context.TODO(), Widget{}, nil)
|
||||
// handle err
|
||||
result, err := poller.PollUntilDone(context.TODO(), nil)
|
||||
// handle err
|
||||
// use result
|
||||
|
||||
The call to PollUntilDone() will block the current goroutine until the LRO has reached a terminal state or the
|
||||
context is canceled/timed out.
|
||||
|
||||
Note that LROs can take anywhere from several seconds to several minutes. The duration is operation-dependent. Due to
|
||||
this variant behavior, pollers do _not_ have a preconfigured time-out. Use a context with the appropriate cancellation
|
||||
mechanism as required.
|
||||
|
||||
# Resume Tokens
|
||||
|
||||
Pollers provide the ability to serialize their state into a "resume token" which can be used by another process to
|
||||
recreate the poller. This is achieved via the runtime.Poller[T].ResumeToken() method.
|
||||
|
||||
token, err := poller.ResumeToken()
|
||||
// handle error
|
||||
|
||||
Note that a token can only be obtained for a poller that's in a non-terminal state. Also note that any subsequent calls
|
||||
to poller.Poll() might change the poller's state. In this case, a new token should be created.
|
||||
|
||||
After the token has been obtained, it can be used to recreate an instance of the originating poller.
|
||||
|
||||
poller, err := widgetClient.BeginCreateOrUpdate(nil, Widget{}, &Options{
|
||||
ResumeToken: token,
|
||||
})
|
||||
|
||||
When resuming a poller, no IO is performed, and zero-value arguments can be used for everything but the Options.ResumeToken.
|
||||
|
||||
Resume tokens are unique per service client and operation. Attempting to resume a poller for LRO BeginB() with a token from LRO
|
||||
BeginA() will result in an error.
|
||||
|
||||
# Fakes
|
||||
|
||||
The fake package contains types used for constructing in-memory fake servers used in unit tests.
|
||||
This allows writing tests to cover various success/error conditions without the need for connecting to a live service.
|
||||
|
||||
Please see https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/samples/fakes for details and examples on how to use fakes.
|
||||
*/
|
||||
package azcore
|
||||
@@ -1,17 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package azcore
|
||||
|
||||
import "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
|
||||
// ResponseError is returned when a request is made to a service and
|
||||
// the service returns a non-success HTTP status code.
|
||||
// Use errors.As() to access this type in the error chain.
|
||||
//
|
||||
// When marshaling instances, the RawResponse field will be omitted.
|
||||
// However, the contents returned by Error() will be preserved.
|
||||
type ResponseError = exported.ResponseError
|
||||
@@ -1,57 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package azcore
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ETag is a property used for optimistic concurrency during updates
|
||||
// ETag is a validator based on https://tools.ietf.org/html/rfc7232#section-2.3.2
|
||||
// An ETag can be empty ("").
|
||||
type ETag string
|
||||
|
||||
// ETagAny is an ETag that represents everything, the value is "*"
|
||||
const ETagAny ETag = "*"
|
||||
|
||||
// Equals does a strong comparison of two ETags. Equals returns true when both
|
||||
// ETags are not weak and the values of the underlying strings are equal.
|
||||
func (e ETag) Equals(other ETag) bool {
|
||||
return !e.IsWeak() && !other.IsWeak() && e == other
|
||||
}
|
||||
|
||||
// WeakEquals does a weak comparison of two ETags. Two ETags are equivalent if their opaque-tags match
|
||||
// character-by-character, regardless of either or both being tagged as "weak".
|
||||
func (e ETag) WeakEquals(other ETag) bool {
|
||||
getStart := func(e1 ETag) int {
|
||||
if e1.IsWeak() {
|
||||
return 2
|
||||
}
|
||||
return 0
|
||||
}
|
||||
aStart := getStart(e)
|
||||
bStart := getStart(other)
|
||||
|
||||
aVal := e[aStart:]
|
||||
bVal := other[bStart:]
|
||||
|
||||
return aVal == bVal
|
||||
}
|
||||
|
||||
// IsWeak specifies whether the ETag is strong or weak.
|
||||
func (e ETag) IsWeak() bool {
|
||||
return len(e) >= 4 && strings.HasPrefix(string(e), "W/\"") && strings.HasSuffix(string(e), "\"")
|
||||
}
|
||||
|
||||
// MatchConditions specifies HTTP options for conditional requests.
|
||||
type MatchConditions struct {
|
||||
// Optionally limit requests to resources that have a matching ETag.
|
||||
IfMatch *ETag
|
||||
|
||||
// Optionally limit requests to resources that do not match the ETag.
|
||||
IfNoneMatch *ETag
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package exported
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type nopCloser struct {
|
||||
io.ReadSeeker
|
||||
}
|
||||
|
||||
func (n nopCloser) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// NopCloser returns a ReadSeekCloser with a no-op close method wrapping the provided io.ReadSeeker.
|
||||
// Exported as streaming.NopCloser().
|
||||
func NopCloser(rs io.ReadSeeker) io.ReadSeekCloser {
|
||||
return nopCloser{rs}
|
||||
}
|
||||
|
||||
// HasStatusCode returns true if the Response's status code is one of the specified values.
|
||||
// Exported as runtime.HasStatusCode().
|
||||
func HasStatusCode(resp *http.Response, statusCodes ...int) bool {
|
||||
if resp == nil {
|
||||
return false
|
||||
}
|
||||
for _, sc := range statusCodes {
|
||||
if resp.StatusCode == sc {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AccessToken represents an Azure service bearer access token with expiry information.
|
||||
// Exported as azcore.AccessToken.
|
||||
type AccessToken struct {
|
||||
Token string
|
||||
ExpiresOn time.Time
|
||||
}
|
||||
|
||||
// TokenRequestOptions contain specific parameter that may be used by credentials types when attempting to get a token.
|
||||
// Exported as policy.TokenRequestOptions.
|
||||
type TokenRequestOptions struct {
|
||||
// Claims are any additional claims required for the token to satisfy a conditional access policy, such as a
|
||||
// service may return in a claims challenge following an authorization failure. If a service returned the
|
||||
// claims value base64 encoded, it must be decoded before setting this field.
|
||||
Claims string
|
||||
|
||||
// EnableCAE indicates whether to enable Continuous Access Evaluation (CAE) for the requested token. When true,
|
||||
// azidentity credentials request CAE tokens for resource APIs supporting CAE. Clients are responsible for
|
||||
// handling CAE challenges. If a client that doesn't handle CAE challenges receives a CAE token, it may end up
|
||||
// in a loop retrying an API call with a token that has been revoked due to CAE.
|
||||
EnableCAE bool
|
||||
|
||||
// Scopes contains the list of permission scopes required for the token.
|
||||
Scopes []string
|
||||
|
||||
// TenantID identifies the tenant from which to request the token. azidentity credentials authenticate in
|
||||
// their configured default tenants when this field isn't set.
|
||||
TenantID string
|
||||
}
|
||||
|
||||
// TokenCredential represents a credential capable of providing an OAuth token.
|
||||
// Exported as azcore.TokenCredential.
|
||||
type TokenCredential interface {
|
||||
// GetToken requests an access token for the specified set of scopes.
|
||||
GetToken(ctx context.Context, options TokenRequestOptions) (AccessToken, error)
|
||||
}
|
||||
|
||||
// DecodeByteArray will base-64 decode the provided string into v.
|
||||
// Exported as runtime.DecodeByteArray()
|
||||
func DecodeByteArray(s string, v *[]byte, format Base64Encoding) error {
|
||||
if len(s) == 0 {
|
||||
return nil
|
||||
}
|
||||
payload := string(s)
|
||||
if payload[0] == '"' {
|
||||
// remove surrounding quotes
|
||||
payload = payload[1 : len(payload)-1]
|
||||
}
|
||||
switch format {
|
||||
case Base64StdFormat:
|
||||
decoded, err := base64.StdEncoding.DecodeString(payload)
|
||||
if err == nil {
|
||||
*v = decoded
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
case Base64URLFormat:
|
||||
// use raw encoding as URL format should not contain any '=' characters
|
||||
decoded, err := base64.RawURLEncoding.DecodeString(payload)
|
||||
if err == nil {
|
||||
*v = decoded
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
default:
|
||||
return fmt.Errorf("unrecognized byte array format: %d", format)
|
||||
}
|
||||
}
|
||||
|
||||
// KeyCredential contains an authentication key used to authenticate to an Azure service.
|
||||
// Exported as azcore.KeyCredential.
|
||||
type KeyCredential struct {
|
||||
cred *keyCredential
|
||||
}
|
||||
|
||||
// NewKeyCredential creates a new instance of [KeyCredential] with the specified values.
|
||||
// - key is the authentication key
|
||||
func NewKeyCredential(key string) *KeyCredential {
|
||||
return &KeyCredential{cred: newKeyCredential(key)}
|
||||
}
|
||||
|
||||
// Update replaces the existing key with the specified value.
|
||||
func (k *KeyCredential) Update(key string) {
|
||||
k.cred.Update(key)
|
||||
}
|
||||
|
||||
// SASCredential contains a shared access signature used to authenticate to an Azure service.
|
||||
// Exported as azcore.SASCredential.
|
||||
type SASCredential struct {
|
||||
cred *keyCredential
|
||||
}
|
||||
|
||||
// NewSASCredential creates a new instance of [SASCredential] with the specified values.
|
||||
// - sas is the shared access signature
|
||||
func NewSASCredential(sas string) *SASCredential {
|
||||
return &SASCredential{cred: newKeyCredential(sas)}
|
||||
}
|
||||
|
||||
// Update replaces the existing shared access signature with the specified value.
|
||||
func (k *SASCredential) Update(sas string) {
|
||||
k.cred.Update(sas)
|
||||
}
|
||||
|
||||
// KeyCredentialGet returns the key for cred.
|
||||
func KeyCredentialGet(cred *KeyCredential) string {
|
||||
return cred.cred.Get()
|
||||
}
|
||||
|
||||
// SASCredentialGet returns the shared access sig for cred.
|
||||
func SASCredentialGet(cred *SASCredential) string {
|
||||
return cred.cred.Get()
|
||||
}
|
||||
|
||||
type keyCredential struct {
|
||||
key atomic.Value // string
|
||||
}
|
||||
|
||||
func newKeyCredential(key string) *keyCredential {
|
||||
keyCred := keyCredential{}
|
||||
keyCred.key.Store(key)
|
||||
return &keyCred
|
||||
}
|
||||
|
||||
func (k *keyCredential) Get() string {
|
||||
return k.key.Load().(string)
|
||||
}
|
||||
|
||||
func (k *keyCredential) Update(key string) {
|
||||
k.key.Store(key)
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package exported
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Policy represents an extensibility point for the Pipeline that can mutate the specified
|
||||
// Request and react to the received Response.
|
||||
// Exported as policy.Policy.
|
||||
type Policy interface {
|
||||
// Do applies the policy to the specified Request. When implementing a Policy, mutate the
|
||||
// request before calling req.Next() to move on to the next policy, and respond to the result
|
||||
// before returning to the caller.
|
||||
Do(req *Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// Pipeline represents a primitive for sending HTTP requests and receiving responses.
|
||||
// Its behavior can be extended by specifying policies during construction.
|
||||
// Exported as runtime.Pipeline.
|
||||
type Pipeline struct {
|
||||
policies []Policy
|
||||
}
|
||||
|
||||
// Transporter represents an HTTP pipeline transport used to send HTTP requests and receive responses.
|
||||
// Exported as policy.Transporter.
|
||||
type Transporter interface {
|
||||
// Do sends the HTTP request and returns the HTTP response or error.
|
||||
Do(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
// used to adapt a TransportPolicy to a Policy
|
||||
type transportPolicy struct {
|
||||
trans Transporter
|
||||
}
|
||||
|
||||
func (tp transportPolicy) Do(req *Request) (*http.Response, error) {
|
||||
if tp.trans == nil {
|
||||
return nil, errors.New("missing transporter")
|
||||
}
|
||||
resp, err := tp.trans.Do(req.Raw())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if resp == nil {
|
||||
// there was no response and no error (rare but can happen)
|
||||
// this ensures the retry policy will retry the request
|
||||
return nil, errors.New("received nil response")
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// NewPipeline creates a new Pipeline object from the specified Policies.
|
||||
// Not directly exported, but used as part of runtime.NewPipeline().
|
||||
func NewPipeline(transport Transporter, policies ...Policy) Pipeline {
|
||||
// transport policy must always be the last in the slice
|
||||
policies = append(policies, transportPolicy{trans: transport})
|
||||
return Pipeline{
|
||||
policies: policies,
|
||||
}
|
||||
}
|
||||
|
||||
// Do is called for each and every HTTP request. It passes the request through all
|
||||
// the Policy objects (which can transform the Request's URL/query parameters/headers)
|
||||
// and ultimately sends the transformed HTTP request over the network.
|
||||
func (p Pipeline) Do(req *Request) (*http.Response, error) {
|
||||
if req == nil {
|
||||
return nil, errors.New("request cannot be nil")
|
||||
}
|
||||
req.policies = p.policies
|
||||
return req.Next()
|
||||
}
|
||||
@@ -1,260 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package exported
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
)
|
||||
|
||||
// Base64Encoding is usesd to specify which base-64 encoder/decoder to use when
|
||||
// encoding/decoding a slice of bytes to/from a string.
|
||||
// Exported as runtime.Base64Encoding
|
||||
type Base64Encoding int
|
||||
|
||||
const (
|
||||
// Base64StdFormat uses base64.StdEncoding for encoding and decoding payloads.
|
||||
Base64StdFormat Base64Encoding = 0
|
||||
|
||||
// Base64URLFormat uses base64.RawURLEncoding for encoding and decoding payloads.
|
||||
Base64URLFormat Base64Encoding = 1
|
||||
)
|
||||
|
||||
// EncodeByteArray will base-64 encode the byte slice v.
|
||||
// Exported as runtime.EncodeByteArray()
|
||||
func EncodeByteArray(v []byte, format Base64Encoding) string {
|
||||
if format == Base64URLFormat {
|
||||
return base64.RawURLEncoding.EncodeToString(v)
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(v)
|
||||
}
|
||||
|
||||
// Request is an abstraction over the creation of an HTTP request as it passes through the pipeline.
|
||||
// Don't use this type directly, use NewRequest() instead.
|
||||
// Exported as policy.Request.
|
||||
type Request struct {
|
||||
req *http.Request
|
||||
body io.ReadSeekCloser
|
||||
policies []Policy
|
||||
values opValues
|
||||
}
|
||||
|
||||
type opValues map[reflect.Type]any
|
||||
|
||||
// Set adds/changes a value
|
||||
func (ov opValues) set(value any) {
|
||||
ov[reflect.TypeOf(value)] = value
|
||||
}
|
||||
|
||||
// Get looks for a value set by SetValue first
|
||||
func (ov opValues) get(value any) bool {
|
||||
v, ok := ov[reflect.ValueOf(value).Elem().Type()]
|
||||
if ok {
|
||||
reflect.ValueOf(value).Elem().Set(reflect.ValueOf(v))
|
||||
}
|
||||
return ok
|
||||
}
|
||||
|
||||
// NewRequestFromRequest creates a new policy.Request with an existing *http.Request
|
||||
// Exported as runtime.NewRequestFromRequest().
|
||||
func NewRequestFromRequest(req *http.Request) (*Request, error) {
|
||||
policyReq := &Request{req: req}
|
||||
|
||||
if req.Body != nil {
|
||||
// we can avoid a body copy here if the underlying stream is already a
|
||||
// ReadSeekCloser.
|
||||
readSeekCloser, isReadSeekCloser := req.Body.(io.ReadSeekCloser)
|
||||
|
||||
if !isReadSeekCloser {
|
||||
// since this is an already populated http.Request we want to copy
|
||||
// over its body, if it has one.
|
||||
bodyBytes, err := io.ReadAll(req.Body)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := req.Body.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
readSeekCloser = NopCloser(bytes.NewReader(bodyBytes))
|
||||
}
|
||||
|
||||
// SetBody also takes care of updating the http.Request's body
|
||||
// as well, so they should stay in-sync from this point.
|
||||
if err := policyReq.SetBody(readSeekCloser, req.Header.Get("Content-Type")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return policyReq, nil
|
||||
}
|
||||
|
||||
// NewRequest creates a new Request with the specified input.
|
||||
// Exported as runtime.NewRequest().
|
||||
func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*Request, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, httpMethod, endpoint, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if req.URL.Host == "" {
|
||||
return nil, errors.New("no Host in request URL")
|
||||
}
|
||||
if !(req.URL.Scheme == "http" || req.URL.Scheme == "https") {
|
||||
return nil, fmt.Errorf("unsupported protocol scheme %s", req.URL.Scheme)
|
||||
}
|
||||
return &Request{req: req}, nil
|
||||
}
|
||||
|
||||
// Body returns the original body specified when the Request was created.
|
||||
func (req *Request) Body() io.ReadSeekCloser {
|
||||
return req.body
|
||||
}
|
||||
|
||||
// Raw returns the underlying HTTP request.
|
||||
func (req *Request) Raw() *http.Request {
|
||||
return req.req
|
||||
}
|
||||
|
||||
// Next calls the next policy in the pipeline.
|
||||
// If there are no more policies, nil and an error are returned.
|
||||
// This method is intended to be called from pipeline policies.
|
||||
// To send a request through a pipeline call Pipeline.Do().
|
||||
func (req *Request) Next() (*http.Response, error) {
|
||||
if len(req.policies) == 0 {
|
||||
return nil, errors.New("no more policies")
|
||||
}
|
||||
nextPolicy := req.policies[0]
|
||||
nextReq := *req
|
||||
nextReq.policies = nextReq.policies[1:]
|
||||
return nextPolicy.Do(&nextReq)
|
||||
}
|
||||
|
||||
// SetOperationValue adds/changes a mutable key/value associated with a single operation.
|
||||
func (req *Request) SetOperationValue(value any) {
|
||||
if req.values == nil {
|
||||
req.values = opValues{}
|
||||
}
|
||||
req.values.set(value)
|
||||
}
|
||||
|
||||
// OperationValue looks for a value set by SetOperationValue().
|
||||
func (req *Request) OperationValue(value any) bool {
|
||||
if req.values == nil {
|
||||
return false
|
||||
}
|
||||
return req.values.get(value)
|
||||
}
|
||||
|
||||
// SetBody sets the specified ReadSeekCloser as the HTTP request body, and sets Content-Type and Content-Length
|
||||
// accordingly. If the ReadSeekCloser is nil or empty, Content-Length won't be set. If contentType is "",
|
||||
// Content-Type won't be set, and if it was set, will be deleted.
|
||||
// Use streaming.NopCloser to turn an io.ReadSeeker into an io.ReadSeekCloser.
|
||||
func (req *Request) SetBody(body io.ReadSeekCloser, contentType string) error {
|
||||
// clobber the existing Content-Type to preserve behavior
|
||||
return SetBody(req, body, contentType, true)
|
||||
}
|
||||
|
||||
// RewindBody seeks the request's Body stream back to the beginning so it can be resent when retrying an operation.
|
||||
func (req *Request) RewindBody() error {
|
||||
if req.body != nil {
|
||||
// Reset the stream back to the beginning and restore the body
|
||||
_, err := req.body.Seek(0, io.SeekStart)
|
||||
req.req.Body = req.body
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close closes the request body.
|
||||
func (req *Request) Close() error {
|
||||
if req.body == nil {
|
||||
return nil
|
||||
}
|
||||
return req.body.Close()
|
||||
}
|
||||
|
||||
// Clone returns a deep copy of the request with its context changed to ctx.
|
||||
func (req *Request) Clone(ctx context.Context) *Request {
|
||||
r2 := *req
|
||||
r2.req = req.req.Clone(ctx)
|
||||
return &r2
|
||||
}
|
||||
|
||||
// WithContext returns a shallow copy of the request with its context changed to ctx.
|
||||
func (req *Request) WithContext(ctx context.Context) *Request {
|
||||
r2 := new(Request)
|
||||
*r2 = *req
|
||||
r2.req = r2.req.WithContext(ctx)
|
||||
return r2
|
||||
}
|
||||
|
||||
// not exported but dependent on Request
|
||||
|
||||
// PolicyFunc is a type that implements the Policy interface.
|
||||
// Use this type when implementing a stateless policy as a first-class function.
|
||||
type PolicyFunc func(*Request) (*http.Response, error)
|
||||
|
||||
// Do implements the Policy interface on policyFunc.
|
||||
func (pf PolicyFunc) Do(req *Request) (*http.Response, error) {
|
||||
return pf(req)
|
||||
}
|
||||
|
||||
// SetBody sets the specified ReadSeekCloser as the HTTP request body, and sets Content-Type and Content-Length accordingly.
|
||||
// - req is the request to modify
|
||||
// - body is the request body; if nil or empty, Content-Length won't be set
|
||||
// - contentType is the value for the Content-Type header; if empty, Content-Type will be deleted
|
||||
// - clobberContentType when true, will overwrite the existing value of Content-Type with contentType
|
||||
func SetBody(req *Request, body io.ReadSeekCloser, contentType string, clobberContentType bool) error {
|
||||
var err error
|
||||
var size int64
|
||||
if body != nil {
|
||||
size, err = body.Seek(0, io.SeekEnd) // Seek to the end to get the stream's size
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if size == 0 {
|
||||
// treat an empty stream the same as a nil one: assign req a nil body
|
||||
body = nil
|
||||
// RFC 9110 specifies a client shouldn't set Content-Length on a request containing no content
|
||||
// (Del is a no-op when the header has no value)
|
||||
req.req.Header.Del(shared.HeaderContentLength)
|
||||
} else {
|
||||
_, err = body.Seek(0, io.SeekStart)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.req.Header.Set(shared.HeaderContentLength, strconv.FormatInt(size, 10))
|
||||
req.Raw().GetBody = func() (io.ReadCloser, error) {
|
||||
_, err := body.Seek(0, io.SeekStart) // Seek back to the beginning of the stream
|
||||
return body, err
|
||||
}
|
||||
}
|
||||
// keep a copy of the body argument. this is to handle cases
|
||||
// where req.Body is replaced, e.g. httputil.DumpRequest and friends.
|
||||
req.body = body
|
||||
req.req.Body = body
|
||||
req.req.ContentLength = size
|
||||
if contentType == "" {
|
||||
// Del is a no-op when the header has no value
|
||||
req.req.Header.Del(shared.HeaderContentType)
|
||||
} else if req.req.Header.Get(shared.HeaderContentType) == "" || clobberContentType {
|
||||
req.req.Header.Set(shared.HeaderContentType, contentType)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package exported
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/exported"
|
||||
)
|
||||
|
||||
// NewResponseError creates a new *ResponseError from the provided HTTP response.
|
||||
// Exported as runtime.NewResponseError().
|
||||
func NewResponseError(resp *http.Response) error {
|
||||
// prefer the error code in the response header
|
||||
if ec := resp.Header.Get(shared.HeaderXMSErrorCode); ec != "" {
|
||||
return NewResponseErrorWithErrorCode(resp, ec)
|
||||
}
|
||||
|
||||
// if we didn't get x-ms-error-code, check in the response body
|
||||
body, err := exported.Payload(resp, nil)
|
||||
if err != nil {
|
||||
// since we're not returning the ResponseError in this
|
||||
// case we also don't want to write it to the log.
|
||||
return err
|
||||
}
|
||||
|
||||
var errorCode string
|
||||
if len(body) > 0 {
|
||||
if fromJSON := extractErrorCodeJSON(body); fromJSON != "" {
|
||||
errorCode = fromJSON
|
||||
} else if fromXML := extractErrorCodeXML(body); fromXML != "" {
|
||||
errorCode = fromXML
|
||||
}
|
||||
}
|
||||
|
||||
return NewResponseErrorWithErrorCode(resp, errorCode)
|
||||
}
|
||||
|
||||
// NewResponseErrorWithErrorCode creates an *azcore.ResponseError from the provided HTTP response and errorCode.
|
||||
// Exported as runtime.NewResponseErrorWithErrorCode().
|
||||
func NewResponseErrorWithErrorCode(resp *http.Response, errorCode string) error {
|
||||
respErr := &ResponseError{
|
||||
ErrorCode: errorCode,
|
||||
StatusCode: resp.StatusCode,
|
||||
RawResponse: resp,
|
||||
}
|
||||
log.Write(log.EventResponseError, respErr.Error())
|
||||
return respErr
|
||||
}
|
||||
|
||||
func extractErrorCodeJSON(body []byte) string {
|
||||
var rawObj map[string]any
|
||||
if err := json.Unmarshal(body, &rawObj); err != nil {
|
||||
// not a JSON object
|
||||
return ""
|
||||
}
|
||||
|
||||
// check if this is a wrapped error, i.e. { "error": { ... } }
|
||||
// if so then unwrap it
|
||||
if wrapped, ok := rawObj["error"]; ok {
|
||||
unwrapped, ok := wrapped.(map[string]any)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
rawObj = unwrapped
|
||||
} else if wrapped, ok := rawObj["odata.error"]; ok {
|
||||
// check if this a wrapped odata error, i.e. { "odata.error": { ... } }
|
||||
unwrapped, ok := wrapped.(map[string]any)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
rawObj = unwrapped
|
||||
}
|
||||
|
||||
// now check for the error code
|
||||
code, ok := rawObj["code"]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
codeStr, ok := code.(string)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return codeStr
|
||||
}
|
||||
|
||||
func extractErrorCodeXML(body []byte) string {
|
||||
// regular expression is much easier than dealing with the XML parser
|
||||
rx := regexp.MustCompile(`<(?:\w+:)?[c|C]ode>\s*(\w+)\s*<\/(?:\w+:)?[c|C]ode>`)
|
||||
res := rx.FindStringSubmatch(string(body))
|
||||
if len(res) != 2 {
|
||||
return ""
|
||||
}
|
||||
// first submatch is the entire thing, second one is the captured error code
|
||||
return res[1]
|
||||
}
|
||||
|
||||
// ResponseError is returned when a request is made to a service and
|
||||
// the service returns a non-success HTTP status code.
|
||||
// Use errors.As() to access this type in the error chain.
|
||||
// Exported as azcore.ResponseError.
|
||||
type ResponseError struct {
|
||||
// ErrorCode is the error code returned by the resource provider if available.
|
||||
ErrorCode string
|
||||
|
||||
// StatusCode is the HTTP status code as defined in https://pkg.go.dev/net/http#pkg-constants.
|
||||
StatusCode int
|
||||
|
||||
// RawResponse is the underlying HTTP response.
|
||||
RawResponse *http.Response `json:"-"`
|
||||
|
||||
errMsg string
|
||||
}
|
||||
|
||||
// Error implements the error interface for type ResponseError.
|
||||
// Note that the message contents are not contractual and can change over time.
|
||||
func (e *ResponseError) Error() string {
|
||||
if e.errMsg != "" {
|
||||
return e.errMsg
|
||||
}
|
||||
|
||||
const separator = "--------------------------------------------------------------------------------"
|
||||
// write the request method and URL with response status code
|
||||
msg := &bytes.Buffer{}
|
||||
if e.RawResponse != nil {
|
||||
if e.RawResponse.Request != nil {
|
||||
fmt.Fprintf(msg, "%s %s://%s%s\n", e.RawResponse.Request.Method, e.RawResponse.Request.URL.Scheme, e.RawResponse.Request.URL.Host, e.RawResponse.Request.URL.Path)
|
||||
} else {
|
||||
fmt.Fprintln(msg, "Request information not available")
|
||||
}
|
||||
fmt.Fprintln(msg, separator)
|
||||
fmt.Fprintf(msg, "RESPONSE %d: %s\n", e.RawResponse.StatusCode, e.RawResponse.Status)
|
||||
} else {
|
||||
fmt.Fprintln(msg, "Missing RawResponse")
|
||||
fmt.Fprintln(msg, separator)
|
||||
}
|
||||
if e.ErrorCode != "" {
|
||||
fmt.Fprintf(msg, "ERROR CODE: %s\n", e.ErrorCode)
|
||||
} else {
|
||||
fmt.Fprintln(msg, "ERROR CODE UNAVAILABLE")
|
||||
}
|
||||
if e.RawResponse != nil {
|
||||
fmt.Fprintln(msg, separator)
|
||||
body, err := exported.Payload(e.RawResponse, nil)
|
||||
if err != nil {
|
||||
// this really shouldn't fail at this point as the response
|
||||
// body is already cached (it was read in NewResponseError)
|
||||
fmt.Fprintf(msg, "Error reading response body: %v", err)
|
||||
} else if len(body) > 0 {
|
||||
if err := json.Indent(msg, body, "", " "); err != nil {
|
||||
// failed to pretty-print so just dump it verbatim
|
||||
fmt.Fprint(msg, string(body))
|
||||
}
|
||||
// the standard library doesn't have a pretty-printer for XML
|
||||
fmt.Fprintln(msg)
|
||||
} else {
|
||||
fmt.Fprintln(msg, "Response contained no body")
|
||||
}
|
||||
}
|
||||
fmt.Fprintln(msg, separator)
|
||||
|
||||
e.errMsg = msg.String()
|
||||
return e.errMsg
|
||||
}
|
||||
|
||||
// internal type used for marshaling/unmarshaling
|
||||
type responseError struct {
|
||||
ErrorCode string `json:"errorCode"`
|
||||
StatusCode int `json:"statusCode"`
|
||||
ErrorMessage string `json:"errorMessage"`
|
||||
}
|
||||
|
||||
func (e ResponseError) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(responseError{
|
||||
ErrorCode: e.ErrorCode,
|
||||
StatusCode: e.StatusCode,
|
||||
ErrorMessage: e.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
func (e *ResponseError) UnmarshalJSON(data []byte) error {
|
||||
re := responseError{}
|
||||
if err := json.Unmarshal(data, &re); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.ErrorCode = re.ErrorCode
|
||||
e.StatusCode = re.StatusCode
|
||||
e.errMsg = re.ErrorMessage
|
||||
return nil
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
// This is an internal helper package to combine the complete logging APIs.
|
||||
package log
|
||||
|
||||
import (
|
||||
azlog "github.com/Azure/azure-sdk-for-go/sdk/azcore/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
|
||||
)
|
||||
|
||||
type Event = log.Event
|
||||
|
||||
const (
|
||||
EventRequest = azlog.EventRequest
|
||||
EventResponse = azlog.EventResponse
|
||||
EventResponseError = azlog.EventResponseError
|
||||
EventRetryPolicy = azlog.EventRetryPolicy
|
||||
EventLRO = azlog.EventLRO
|
||||
)
|
||||
|
||||
// Write invokes the underlying listener with the specified event and message.
|
||||
// If the event shouldn't be logged or there is no listener then Write does nothing.
|
||||
func Write(cls log.Event, msg string) {
|
||||
log.Write(cls, msg)
|
||||
}
|
||||
|
||||
// Writef invokes the underlying listener with the specified event and formatted message.
|
||||
// If the event shouldn't be logged or there is no listener then Writef does nothing.
|
||||
func Writef(cls log.Event, format string, a ...any) {
|
||||
log.Writef(cls, format, a...)
|
||||
}
|
||||
|
||||
// SetListener will set the Logger to write to the specified listener.
|
||||
func SetListener(lst func(Event, string)) {
|
||||
log.SetListener(lst)
|
||||
}
|
||||
|
||||
// Should returns true if the specified log event should be written to the log.
|
||||
// By default all log events will be logged. Call SetEvents() to limit
|
||||
// the log events for logging.
|
||||
// If no listener has been set this will return false.
|
||||
// Calling this method is useful when the message to log is computationally expensive
|
||||
// and you want to avoid the overhead if its log event is not enabled.
|
||||
func Should(cls log.Event) bool {
|
||||
return log.Should(cls)
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package async
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
||||
)
|
||||
|
||||
// see https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/async-api-reference.md
|
||||
|
||||
// Applicable returns true if the LRO is using Azure-AsyncOperation.
|
||||
func Applicable(resp *http.Response) bool {
|
||||
return resp.Header.Get(shared.HeaderAzureAsync) != ""
|
||||
}
|
||||
|
||||
// CanResume returns true if the token can rehydrate this poller type.
|
||||
func CanResume(token map[string]any) bool {
|
||||
_, ok := token["asyncURL"]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Poller is an LRO poller that uses the Azure-AsyncOperation pattern.
|
||||
type Poller[T any] struct {
|
||||
pl exported.Pipeline
|
||||
|
||||
resp *http.Response
|
||||
|
||||
// The URL from Azure-AsyncOperation header.
|
||||
AsyncURL string `json:"asyncURL"`
|
||||
|
||||
// The URL from Location header.
|
||||
LocURL string `json:"locURL"`
|
||||
|
||||
// The URL from the initial LRO request.
|
||||
OrigURL string `json:"origURL"`
|
||||
|
||||
// The HTTP method from the initial LRO request.
|
||||
Method string `json:"method"`
|
||||
|
||||
// The value of final-state-via from swagger, can be the empty string.
|
||||
FinalState pollers.FinalStateVia `json:"finalState"`
|
||||
|
||||
// The LRO's current state.
|
||||
CurState string `json:"state"`
|
||||
}
|
||||
|
||||
// New creates a new Poller from the provided initial response and final-state type.
|
||||
// Pass nil for response to create an empty Poller for rehydration.
|
||||
func New[T any](pl exported.Pipeline, resp *http.Response, finalState pollers.FinalStateVia) (*Poller[T], error) {
|
||||
if resp == nil {
|
||||
log.Write(log.EventLRO, "Resuming Azure-AsyncOperation poller.")
|
||||
return &Poller[T]{pl: pl}, nil
|
||||
}
|
||||
log.Write(log.EventLRO, "Using Azure-AsyncOperation poller.")
|
||||
asyncURL := resp.Header.Get(shared.HeaderAzureAsync)
|
||||
if asyncURL == "" {
|
||||
return nil, errors.New("response is missing Azure-AsyncOperation header")
|
||||
}
|
||||
if !poller.IsValidURL(asyncURL) {
|
||||
return nil, fmt.Errorf("invalid polling URL %s", asyncURL)
|
||||
}
|
||||
// check for provisioning state. if the operation is a RELO
|
||||
// and terminates synchronously this will prevent extra polling.
|
||||
// it's ok if there's no provisioning state.
|
||||
state, _ := poller.GetProvisioningState(resp)
|
||||
if state == "" {
|
||||
state = poller.StatusInProgress
|
||||
}
|
||||
p := &Poller[T]{
|
||||
pl: pl,
|
||||
resp: resp,
|
||||
AsyncURL: asyncURL,
|
||||
LocURL: resp.Header.Get(shared.HeaderLocation),
|
||||
OrigURL: resp.Request.URL.String(),
|
||||
Method: resp.Request.Method,
|
||||
FinalState: finalState,
|
||||
CurState: state,
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// Done returns true if the LRO is in a terminal state.
|
||||
func (p *Poller[T]) Done() bool {
|
||||
return poller.IsTerminalState(p.CurState)
|
||||
}
|
||||
|
||||
// Poll retrieves the current state of the LRO.
|
||||
func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) {
|
||||
err := pollers.PollHelper(ctx, p.AsyncURL, p.pl, func(resp *http.Response) (string, error) {
|
||||
if !poller.StatusCodeValid(resp) {
|
||||
p.resp = resp
|
||||
return "", exported.NewResponseError(resp)
|
||||
}
|
||||
state, err := poller.GetStatus(resp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if state == "" {
|
||||
return "", errors.New("the response did not contain a status")
|
||||
}
|
||||
p.resp = resp
|
||||
p.CurState = state
|
||||
return p.CurState, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.resp, nil
|
||||
}
|
||||
|
||||
func (p *Poller[T]) Result(ctx context.Context, out *T) error {
|
||||
if p.resp.StatusCode == http.StatusNoContent {
|
||||
return nil
|
||||
} else if poller.Failed(p.CurState) {
|
||||
return exported.NewResponseError(p.resp)
|
||||
}
|
||||
var req *exported.Request
|
||||
var err error
|
||||
if p.Method == http.MethodPatch || p.Method == http.MethodPut {
|
||||
// for PATCH and PUT, the final GET is on the original resource URL
|
||||
req, err = exported.NewRequest(ctx, http.MethodGet, p.OrigURL)
|
||||
} else if p.Method == http.MethodPost {
|
||||
if p.FinalState == pollers.FinalStateViaAzureAsyncOp {
|
||||
// no final GET required
|
||||
} else if p.FinalState == pollers.FinalStateViaOriginalURI {
|
||||
req, err = exported.NewRequest(ctx, http.MethodGet, p.OrigURL)
|
||||
} else if p.LocURL != "" {
|
||||
// ideally FinalState would be set to "location" but it isn't always.
|
||||
// must check last due to more permissive condition.
|
||||
req, err = exported.NewRequest(ctx, http.MethodGet, p.LocURL)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if a final GET request has been created, execute it
|
||||
if req != nil {
|
||||
resp, err := p.pl.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.resp = resp
|
||||
}
|
||||
|
||||
return pollers.ResultHelper(p.resp, poller.Failed(p.CurState), "", out)
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package body
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
||||
)
|
||||
|
||||
// Kind is the identifier of this type in a resume token.
|
||||
const kind = "body"
|
||||
|
||||
// Applicable returns true if the LRO is using no headers, just provisioning state.
|
||||
// This is only applicable to PATCH and PUT methods and assumes no polling headers.
|
||||
func Applicable(resp *http.Response) bool {
|
||||
// we can't check for absense of headers due to some misbehaving services
|
||||
// like redis that return a Location header but don't actually use that protocol
|
||||
return resp.Request.Method == http.MethodPatch || resp.Request.Method == http.MethodPut
|
||||
}
|
||||
|
||||
// CanResume returns true if the token can rehydrate this poller type.
|
||||
func CanResume(token map[string]any) bool {
|
||||
t, ok := token["type"]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
tt, ok := t.(string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return tt == kind
|
||||
}
|
||||
|
||||
// Poller is an LRO poller that uses the Body pattern.
|
||||
type Poller[T any] struct {
|
||||
pl exported.Pipeline
|
||||
|
||||
resp *http.Response
|
||||
|
||||
// The poller's type, used for resume token processing.
|
||||
Type string `json:"type"`
|
||||
|
||||
// The URL for polling.
|
||||
PollURL string `json:"pollURL"`
|
||||
|
||||
// The LRO's current state.
|
||||
CurState string `json:"state"`
|
||||
}
|
||||
|
||||
// New creates a new Poller from the provided initial response.
|
||||
// Pass nil for response to create an empty Poller for rehydration.
|
||||
func New[T any](pl exported.Pipeline, resp *http.Response) (*Poller[T], error) {
|
||||
if resp == nil {
|
||||
log.Write(log.EventLRO, "Resuming Body poller.")
|
||||
return &Poller[T]{pl: pl}, nil
|
||||
}
|
||||
log.Write(log.EventLRO, "Using Body poller.")
|
||||
p := &Poller[T]{
|
||||
pl: pl,
|
||||
resp: resp,
|
||||
Type: kind,
|
||||
PollURL: resp.Request.URL.String(),
|
||||
}
|
||||
// default initial state to InProgress. depending on the HTTP
|
||||
// status code and provisioning state, we might change the value.
|
||||
curState := poller.StatusInProgress
|
||||
provState, err := poller.GetProvisioningState(resp)
|
||||
if err != nil && !errors.Is(err, poller.ErrNoBody) {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode == http.StatusCreated && provState != "" {
|
||||
// absense of provisioning state is ok for a 201, means the operation is in progress
|
||||
curState = provState
|
||||
} else if resp.StatusCode == http.StatusOK {
|
||||
if provState != "" {
|
||||
curState = provState
|
||||
} else if provState == "" {
|
||||
// for a 200, absense of provisioning state indicates success
|
||||
curState = poller.StatusSucceeded
|
||||
}
|
||||
} else if resp.StatusCode == http.StatusNoContent {
|
||||
curState = poller.StatusSucceeded
|
||||
}
|
||||
p.CurState = curState
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p *Poller[T]) Done() bool {
|
||||
return poller.IsTerminalState(p.CurState)
|
||||
}
|
||||
|
||||
func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) {
|
||||
err := pollers.PollHelper(ctx, p.PollURL, p.pl, func(resp *http.Response) (string, error) {
|
||||
if !poller.StatusCodeValid(resp) {
|
||||
p.resp = resp
|
||||
return "", exported.NewResponseError(resp)
|
||||
}
|
||||
if resp.StatusCode == http.StatusNoContent {
|
||||
p.resp = resp
|
||||
p.CurState = poller.StatusSucceeded
|
||||
return p.CurState, nil
|
||||
}
|
||||
state, err := poller.GetProvisioningState(resp)
|
||||
if errors.Is(err, poller.ErrNoBody) {
|
||||
// a missing response body in non-204 case is an error
|
||||
return "", err
|
||||
} else if state == "" {
|
||||
// a response body without provisioning state is considered terminal success
|
||||
state = poller.StatusSucceeded
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
}
|
||||
p.resp = resp
|
||||
p.CurState = state
|
||||
return p.CurState, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.resp, nil
|
||||
}
|
||||
|
||||
func (p *Poller[T]) Result(ctx context.Context, out *T) error {
|
||||
return pollers.ResultHelper(p.resp, poller.Failed(p.CurState), "", out)
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
||||
)
|
||||
|
||||
// Applicable returns true if the LRO is a fake.
|
||||
func Applicable(resp *http.Response) bool {
|
||||
return resp.Header.Get(shared.HeaderFakePollerStatus) != ""
|
||||
}
|
||||
|
||||
// CanResume returns true if the token can rehydrate this poller type.
|
||||
func CanResume(token map[string]any) bool {
|
||||
_, ok := token["fakeURL"]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Poller is an LRO poller that uses the Core-Fake-Poller pattern.
|
||||
type Poller[T any] struct {
|
||||
pl exported.Pipeline
|
||||
|
||||
resp *http.Response
|
||||
|
||||
// The API name from CtxAPINameKey
|
||||
APIName string `json:"apiName"`
|
||||
|
||||
// The URL from Core-Fake-Poller header.
|
||||
FakeURL string `json:"fakeURL"`
|
||||
|
||||
// The LRO's current state.
|
||||
FakeStatus string `json:"status"`
|
||||
}
|
||||
|
||||
// lroStatusURLSuffix is the URL path suffix for a faked LRO.
|
||||
const lroStatusURLSuffix = "/get/fake/status"
|
||||
|
||||
// New creates a new Poller from the provided initial response.
|
||||
// Pass nil for response to create an empty Poller for rehydration.
|
||||
func New[T any](pl exported.Pipeline, resp *http.Response) (*Poller[T], error) {
|
||||
if resp == nil {
|
||||
log.Write(log.EventLRO, "Resuming Core-Fake-Poller poller.")
|
||||
return &Poller[T]{pl: pl}, nil
|
||||
}
|
||||
|
||||
log.Write(log.EventLRO, "Using Core-Fake-Poller poller.")
|
||||
fakeStatus := resp.Header.Get(shared.HeaderFakePollerStatus)
|
||||
if fakeStatus == "" {
|
||||
return nil, errors.New("response is missing Fake-Poller-Status header")
|
||||
}
|
||||
|
||||
ctxVal := resp.Request.Context().Value(shared.CtxAPINameKey{})
|
||||
if ctxVal == nil {
|
||||
return nil, errors.New("missing value for CtxAPINameKey")
|
||||
}
|
||||
|
||||
apiName, ok := ctxVal.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected string for CtxAPINameKey, the type was %T", ctxVal)
|
||||
}
|
||||
|
||||
qp := ""
|
||||
if resp.Request.URL.RawQuery != "" {
|
||||
qp = "?" + resp.Request.URL.RawQuery
|
||||
}
|
||||
|
||||
p := &Poller[T]{
|
||||
pl: pl,
|
||||
resp: resp,
|
||||
APIName: apiName,
|
||||
// NOTE: any changes to this path format MUST be reflected in SanitizePollerPath()
|
||||
FakeURL: fmt.Sprintf("%s://%s%s%s%s", resp.Request.URL.Scheme, resp.Request.URL.Host, resp.Request.URL.Path, lroStatusURLSuffix, qp),
|
||||
FakeStatus: fakeStatus,
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// Done returns true if the LRO is in a terminal state.
|
||||
func (p *Poller[T]) Done() bool {
|
||||
return poller.IsTerminalState(p.FakeStatus)
|
||||
}
|
||||
|
||||
// Poll retrieves the current state of the LRO.
|
||||
func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) {
|
||||
ctx = context.WithValue(ctx, shared.CtxAPINameKey{}, p.APIName)
|
||||
err := pollers.PollHelper(ctx, p.FakeURL, p.pl, func(resp *http.Response) (string, error) {
|
||||
if !poller.StatusCodeValid(resp) {
|
||||
p.resp = resp
|
||||
return "", exported.NewResponseError(resp)
|
||||
}
|
||||
fakeStatus := resp.Header.Get(shared.HeaderFakePollerStatus)
|
||||
if fakeStatus == "" {
|
||||
return "", errors.New("response is missing Fake-Poller-Status header")
|
||||
}
|
||||
p.resp = resp
|
||||
p.FakeStatus = fakeStatus
|
||||
return p.FakeStatus, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.resp, nil
|
||||
}
|
||||
|
||||
func (p *Poller[T]) Result(ctx context.Context, out *T) error {
|
||||
if p.resp.StatusCode == http.StatusNoContent {
|
||||
return nil
|
||||
} else if poller.Failed(p.FakeStatus) {
|
||||
return exported.NewResponseError(p.resp)
|
||||
}
|
||||
|
||||
return pollers.ResultHelper(p.resp, poller.Failed(p.FakeStatus), "", out)
|
||||
}
|
||||
|
||||
// SanitizePollerPath removes any fake-appended suffix from a URL's path.
|
||||
func SanitizePollerPath(path string) string {
|
||||
return strings.TrimSuffix(path, lroStatusURLSuffix)
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package loc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
||||
)
|
||||
|
||||
// Kind is the identifier of this type in a resume token.
|
||||
const kind = "loc"
|
||||
|
||||
// Applicable returns true if the LRO is using Location.
|
||||
func Applicable(resp *http.Response) bool {
|
||||
return resp.Header.Get(shared.HeaderLocation) != ""
|
||||
}
|
||||
|
||||
// CanResume returns true if the token can rehydrate this poller type.
|
||||
func CanResume(token map[string]any) bool {
|
||||
t, ok := token["type"]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
tt, ok := t.(string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return tt == kind
|
||||
}
|
||||
|
||||
// Poller is an LRO poller that uses the Location pattern.
|
||||
type Poller[T any] struct {
|
||||
pl exported.Pipeline
|
||||
resp *http.Response
|
||||
|
||||
Type string `json:"type"`
|
||||
PollURL string `json:"pollURL"`
|
||||
CurState string `json:"state"`
|
||||
}
|
||||
|
||||
// New creates a new Poller from the provided initial response.
|
||||
// Pass nil for response to create an empty Poller for rehydration.
|
||||
func New[T any](pl exported.Pipeline, resp *http.Response) (*Poller[T], error) {
|
||||
if resp == nil {
|
||||
log.Write(log.EventLRO, "Resuming Location poller.")
|
||||
return &Poller[T]{pl: pl}, nil
|
||||
}
|
||||
log.Write(log.EventLRO, "Using Location poller.")
|
||||
locURL := resp.Header.Get(shared.HeaderLocation)
|
||||
if locURL == "" {
|
||||
return nil, errors.New("response is missing Location header")
|
||||
}
|
||||
if !poller.IsValidURL(locURL) {
|
||||
return nil, fmt.Errorf("invalid polling URL %s", locURL)
|
||||
}
|
||||
// check for provisioning state. if the operation is a RELO
|
||||
// and terminates synchronously this will prevent extra polling.
|
||||
// it's ok if there's no provisioning state.
|
||||
state, _ := poller.GetProvisioningState(resp)
|
||||
if state == "" {
|
||||
state = poller.StatusInProgress
|
||||
}
|
||||
return &Poller[T]{
|
||||
pl: pl,
|
||||
resp: resp,
|
||||
Type: kind,
|
||||
PollURL: locURL,
|
||||
CurState: state,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Poller[T]) Done() bool {
|
||||
return poller.IsTerminalState(p.CurState)
|
||||
}
|
||||
|
||||
func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) {
|
||||
err := pollers.PollHelper(ctx, p.PollURL, p.pl, func(resp *http.Response) (string, error) {
|
||||
// location polling can return an updated polling URL
|
||||
if h := resp.Header.Get(shared.HeaderLocation); h != "" {
|
||||
p.PollURL = h
|
||||
}
|
||||
// if provisioning state is available, use that. this is only
|
||||
// for some ARM LRO scenarios (e.g. DELETE with a Location header)
|
||||
// so if it's missing then use HTTP status code.
|
||||
provState, _ := poller.GetProvisioningState(resp)
|
||||
p.resp = resp
|
||||
if provState != "" {
|
||||
p.CurState = provState
|
||||
} else if resp.StatusCode == http.StatusAccepted {
|
||||
p.CurState = poller.StatusInProgress
|
||||
} else if resp.StatusCode > 199 && resp.StatusCode < 300 {
|
||||
// any 2xx other than a 202 indicates success
|
||||
p.CurState = poller.StatusSucceeded
|
||||
} else if pollers.IsNonTerminalHTTPStatusCode(resp) {
|
||||
// the request timed out or is being throttled.
|
||||
// DO NOT include this as a terminal failure. preserve
|
||||
// the existing state and return the response.
|
||||
} else {
|
||||
p.CurState = poller.StatusFailed
|
||||
}
|
||||
return p.CurState, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.resp, nil
|
||||
}
|
||||
|
||||
func (p *Poller[T]) Result(ctx context.Context, out *T) error {
|
||||
return pollers.ResultHelper(p.resp, poller.Failed(p.CurState), "", out)
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package op
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
||||
)
|
||||
|
||||
// Applicable returns true if the LRO is using Operation-Location.
|
||||
func Applicable(resp *http.Response) bool {
|
||||
return resp.Header.Get(shared.HeaderOperationLocation) != ""
|
||||
}
|
||||
|
||||
// CanResume returns true if the token can rehydrate this poller type.
|
||||
func CanResume(token map[string]any) bool {
|
||||
_, ok := token["oplocURL"]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Poller is an LRO poller that uses the Operation-Location pattern.
|
||||
type Poller[T any] struct {
|
||||
pl exported.Pipeline
|
||||
resp *http.Response
|
||||
|
||||
OpLocURL string `json:"oplocURL"`
|
||||
LocURL string `json:"locURL"`
|
||||
OrigURL string `json:"origURL"`
|
||||
Method string `json:"method"`
|
||||
FinalState pollers.FinalStateVia `json:"finalState"`
|
||||
ResultPath string `json:"resultPath"`
|
||||
CurState string `json:"state"`
|
||||
}
|
||||
|
||||
// New creates a new Poller from the provided initial response.
|
||||
// Pass nil for response to create an empty Poller for rehydration.
|
||||
func New[T any](pl exported.Pipeline, resp *http.Response, finalState pollers.FinalStateVia, resultPath string) (*Poller[T], error) {
|
||||
if resp == nil {
|
||||
log.Write(log.EventLRO, "Resuming Operation-Location poller.")
|
||||
return &Poller[T]{pl: pl}, nil
|
||||
}
|
||||
log.Write(log.EventLRO, "Using Operation-Location poller.")
|
||||
opURL := resp.Header.Get(shared.HeaderOperationLocation)
|
||||
if opURL == "" {
|
||||
return nil, errors.New("response is missing Operation-Location header")
|
||||
}
|
||||
if !poller.IsValidURL(opURL) {
|
||||
return nil, fmt.Errorf("invalid Operation-Location URL %s", opURL)
|
||||
}
|
||||
locURL := resp.Header.Get(shared.HeaderLocation)
|
||||
// Location header is optional
|
||||
if locURL != "" && !poller.IsValidURL(locURL) {
|
||||
return nil, fmt.Errorf("invalid Location URL %s", locURL)
|
||||
}
|
||||
// default initial state to InProgress. if the
|
||||
// service sent us a status then use that instead.
|
||||
curState := poller.StatusInProgress
|
||||
status, err := poller.GetStatus(resp)
|
||||
if err != nil && !errors.Is(err, poller.ErrNoBody) {
|
||||
return nil, err
|
||||
}
|
||||
if status != "" {
|
||||
curState = status
|
||||
}
|
||||
|
||||
return &Poller[T]{
|
||||
pl: pl,
|
||||
resp: resp,
|
||||
OpLocURL: opURL,
|
||||
LocURL: locURL,
|
||||
OrigURL: resp.Request.URL.String(),
|
||||
Method: resp.Request.Method,
|
||||
FinalState: finalState,
|
||||
ResultPath: resultPath,
|
||||
CurState: curState,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Poller[T]) Done() bool {
|
||||
return poller.IsTerminalState(p.CurState)
|
||||
}
|
||||
|
||||
func (p *Poller[T]) Poll(ctx context.Context) (*http.Response, error) {
|
||||
err := pollers.PollHelper(ctx, p.OpLocURL, p.pl, func(resp *http.Response) (string, error) {
|
||||
if !poller.StatusCodeValid(resp) {
|
||||
p.resp = resp
|
||||
return "", exported.NewResponseError(resp)
|
||||
}
|
||||
state, err := poller.GetStatus(resp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if state == "" {
|
||||
return "", errors.New("the response did not contain a status")
|
||||
}
|
||||
p.resp = resp
|
||||
p.CurState = state
|
||||
return p.CurState, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.resp, nil
|
||||
}
|
||||
|
||||
func (p *Poller[T]) Result(ctx context.Context, out *T) error {
|
||||
var req *exported.Request
|
||||
var err error
|
||||
|
||||
if p.FinalState == pollers.FinalStateViaLocation && p.LocURL != "" {
|
||||
req, err = exported.NewRequest(ctx, http.MethodGet, p.LocURL)
|
||||
} else if rl, rlErr := poller.GetResourceLocation(p.resp); rlErr != nil && !errors.Is(rlErr, poller.ErrNoBody) {
|
||||
return rlErr
|
||||
} else if rl != "" {
|
||||
req, err = exported.NewRequest(ctx, http.MethodGet, rl)
|
||||
} else if p.Method == http.MethodPatch || p.Method == http.MethodPut {
|
||||
req, err = exported.NewRequest(ctx, http.MethodGet, p.OrigURL)
|
||||
} else if p.Method == http.MethodPost && p.LocURL != "" {
|
||||
req, err = exported.NewRequest(ctx, http.MethodGet, p.LocURL)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if a final GET request has been created, execute it
|
||||
if req != nil {
|
||||
// no JSON path when making a final GET request
|
||||
p.ResultPath = ""
|
||||
resp, err := p.pl.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.resp = resp
|
||||
}
|
||||
|
||||
return pollers.ResultHelper(p.resp, poller.Failed(p.CurState), p.ResultPath, out)
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package pollers
|
||||
|
||||
// FinalStateVia is the enumerated type for the possible final-state-via values.
|
||||
type FinalStateVia string
|
||||
|
||||
const (
|
||||
// FinalStateViaAzureAsyncOp indicates the final payload comes from the Azure-AsyncOperation URL.
|
||||
FinalStateViaAzureAsyncOp FinalStateVia = "azure-async-operation"
|
||||
|
||||
// FinalStateViaLocation indicates the final payload comes from the Location URL.
|
||||
FinalStateViaLocation FinalStateVia = "location"
|
||||
|
||||
// FinalStateViaOriginalURI indicates the final payload comes from the original URL.
|
||||
FinalStateViaOriginalURI FinalStateVia = "original-uri"
|
||||
|
||||
// FinalStateViaOpLocation indicates the final payload comes from the Operation-Location URL.
|
||||
FinalStateViaOpLocation FinalStateVia = "operation-location"
|
||||
)
|
||||
@@ -1,212 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package pollers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
azexported "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
||||
)
|
||||
|
||||
// getTokenTypeName creates a type name from the type parameter T.
|
||||
func getTokenTypeName[T any]() (string, error) {
|
||||
tt := shared.TypeOfT[T]()
|
||||
var n string
|
||||
if tt.Kind() == reflect.Pointer {
|
||||
n = "*"
|
||||
tt = tt.Elem()
|
||||
}
|
||||
n += tt.Name()
|
||||
if n == "" {
|
||||
return "", errors.New("nameless types are not allowed")
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
type resumeTokenWrapper[T any] struct {
|
||||
Type string `json:"type"`
|
||||
Token T `json:"token"`
|
||||
}
|
||||
|
||||
// NewResumeToken creates a resume token from the specified type.
|
||||
// An error is returned if the generic type has no name (e.g. struct{}).
|
||||
func NewResumeToken[TResult, TSource any](from TSource) (string, error) {
|
||||
n, err := getTokenTypeName[TResult]()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
b, err := json.Marshal(resumeTokenWrapper[TSource]{
|
||||
Type: n,
|
||||
Token: from,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
// ExtractToken returns the poller-specific token information from the provided token value.
|
||||
func ExtractToken(token string) ([]byte, error) {
|
||||
raw := map[string]json.RawMessage{}
|
||||
if err := json.Unmarshal([]byte(token), &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// this is dependent on the type resumeTokenWrapper[T]
|
||||
tk, ok := raw["token"]
|
||||
if !ok {
|
||||
return nil, errors.New("missing token value")
|
||||
}
|
||||
return tk, nil
|
||||
}
|
||||
|
||||
// IsTokenValid returns an error if the specified token isn't applicable for generic type T.
|
||||
func IsTokenValid[T any](token string) error {
|
||||
raw := map[string]any{}
|
||||
if err := json.Unmarshal([]byte(token), &raw); err != nil {
|
||||
return err
|
||||
}
|
||||
t, ok := raw["type"]
|
||||
if !ok {
|
||||
return errors.New("missing type value")
|
||||
}
|
||||
tt, ok := t.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid type format %T", t)
|
||||
}
|
||||
n, err := getTokenTypeName[T]()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tt != n {
|
||||
return fmt.Errorf("cannot resume from this poller token. token is for type %s, not %s", tt, n)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// used if the operation synchronously completed
|
||||
type NopPoller[T any] struct {
|
||||
resp *http.Response
|
||||
result T
|
||||
}
|
||||
|
||||
// NewNopPoller creates a NopPoller from the provided response.
|
||||
// It unmarshals the response body into an instance of T.
|
||||
func NewNopPoller[T any](resp *http.Response) (*NopPoller[T], error) {
|
||||
np := &NopPoller[T]{resp: resp}
|
||||
if resp.StatusCode == http.StatusNoContent {
|
||||
return np, nil
|
||||
}
|
||||
payload, err := exported.Payload(resp, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(payload) == 0 {
|
||||
return np, nil
|
||||
}
|
||||
if err = json.Unmarshal(payload, &np.result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return np, nil
|
||||
}
|
||||
|
||||
func (*NopPoller[T]) Done() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *NopPoller[T]) Poll(context.Context) (*http.Response, error) {
|
||||
return p.resp, nil
|
||||
}
|
||||
|
||||
func (p *NopPoller[T]) Result(ctx context.Context, out *T) error {
|
||||
*out = p.result
|
||||
return nil
|
||||
}
|
||||
|
||||
// PollHelper creates and executes the request, calling update() with the response.
|
||||
// If the request fails, the update func is not called.
|
||||
// The update func returns the state of the operation for logging purposes or an error
|
||||
// if it fails to extract the required state from the response.
|
||||
func PollHelper(ctx context.Context, endpoint string, pl azexported.Pipeline, update func(resp *http.Response) (string, error)) error {
|
||||
req, err := azexported.NewRequest(ctx, http.MethodGet, endpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp, err := pl.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
state, err := update(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Writef(log.EventLRO, "State %s", state)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResultHelper processes the response as success or failure.
|
||||
// In the success case, it unmarshals the payload into either a new instance of T or out.
|
||||
// In the failure case, it creates an *azcore.Response error from the response.
|
||||
func ResultHelper[T any](resp *http.Response, failed bool, jsonPath string, out *T) error {
|
||||
// short-circuit the simple success case with no response body to unmarshal
|
||||
if resp.StatusCode == http.StatusNoContent {
|
||||
return nil
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
if !poller.StatusCodeValid(resp) || failed {
|
||||
// the LRO failed. unmarshall the error and update state
|
||||
return azexported.NewResponseError(resp)
|
||||
}
|
||||
|
||||
// success case
|
||||
payload, err := exported.Payload(resp, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if jsonPath != "" && len(payload) > 0 {
|
||||
// extract the payload from the specified JSON path.
|
||||
// do this before the zero-length check in case there
|
||||
// is no payload.
|
||||
jsonBody := map[string]json.RawMessage{}
|
||||
if err = json.Unmarshal(payload, &jsonBody); err != nil {
|
||||
return err
|
||||
}
|
||||
payload = jsonBody[jsonPath]
|
||||
}
|
||||
|
||||
if len(payload) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(payload, out); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsNonTerminalHTTPStatusCode returns true if the HTTP status code should be
|
||||
// considered non-terminal thus eligible for retry.
|
||||
func IsNonTerminalHTTPStatusCode(resp *http.Response) bool {
|
||||
return exported.HasStatusCode(resp,
|
||||
http.StatusRequestTimeout, // 408
|
||||
http.StatusTooManyRequests, // 429
|
||||
http.StatusInternalServerError, // 500
|
||||
http.StatusBadGateway, // 502
|
||||
http.StatusServiceUnavailable, // 503
|
||||
http.StatusGatewayTimeout, // 504
|
||||
)
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package shared
|
||||
|
||||
const (
|
||||
ContentTypeAppJSON = "application/json"
|
||||
ContentTypeAppXML = "application/xml"
|
||||
ContentTypeTextPlain = "text/plain"
|
||||
)
|
||||
|
||||
const (
|
||||
HeaderAuthorization = "Authorization"
|
||||
HeaderAuxiliaryAuthorization = "x-ms-authorization-auxiliary"
|
||||
HeaderAzureAsync = "Azure-AsyncOperation"
|
||||
HeaderContentLength = "Content-Length"
|
||||
HeaderContentType = "Content-Type"
|
||||
HeaderFakePollerStatus = "Fake-Poller-Status"
|
||||
HeaderLocation = "Location"
|
||||
HeaderOperationLocation = "Operation-Location"
|
||||
HeaderRetryAfter = "Retry-After"
|
||||
HeaderRetryAfterMS = "Retry-After-Ms"
|
||||
HeaderUserAgent = "User-Agent"
|
||||
HeaderWWWAuthenticate = "WWW-Authenticate"
|
||||
HeaderXMSClientRequestID = "x-ms-client-request-id"
|
||||
HeaderXMSRequestID = "x-ms-request-id"
|
||||
HeaderXMSErrorCode = "x-ms-error-code"
|
||||
HeaderXMSRetryAfterMS = "x-ms-retry-after-ms"
|
||||
)
|
||||
|
||||
const BearerTokenPrefix = "Bearer "
|
||||
|
||||
const TracingNamespaceAttrName = "az.namespace"
|
||||
|
||||
const (
|
||||
// Module is the name of the calling module used in telemetry data.
|
||||
Module = "azcore"
|
||||
|
||||
// Version is the semantic version (see http://semver.org) of this module.
|
||||
Version = "v1.17.0"
|
||||
)
|
||||
@@ -1,149 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package shared
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NOTE: when adding a new context key type, it likely needs to be
|
||||
// added to the deny-list of key types in ContextWithDeniedValues
|
||||
|
||||
// CtxWithHTTPHeaderKey is used as a context key for adding/retrieving http.Header.
|
||||
type CtxWithHTTPHeaderKey struct{}
|
||||
|
||||
// CtxWithRetryOptionsKey is used as a context key for adding/retrieving RetryOptions.
|
||||
type CtxWithRetryOptionsKey struct{}
|
||||
|
||||
// CtxWithCaptureResponse is used as a context key for retrieving the raw response.
|
||||
type CtxWithCaptureResponse struct{}
|
||||
|
||||
// CtxWithTracingTracer is used as a context key for adding/retrieving tracing.Tracer.
|
||||
type CtxWithTracingTracer struct{}
|
||||
|
||||
// CtxAPINameKey is used as a context key for adding/retrieving the API name.
|
||||
type CtxAPINameKey struct{}
|
||||
|
||||
// Delay waits for the duration to elapse or the context to be cancelled.
|
||||
func Delay(ctx context.Context, delay time.Duration) error {
|
||||
select {
|
||||
case <-time.After(delay):
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
// RetryAfter returns non-zero if the response contains one of the headers with a "retry after" value.
|
||||
// Headers are checked in the following order: retry-after-ms, x-ms-retry-after-ms, retry-after
|
||||
func RetryAfter(resp *http.Response) time.Duration {
|
||||
if resp == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
type retryData struct {
|
||||
header string
|
||||
units time.Duration
|
||||
|
||||
// custom is used when the regular algorithm failed and is optional.
|
||||
// the returned duration is used verbatim (units is not applied).
|
||||
custom func(string) time.Duration
|
||||
}
|
||||
|
||||
nop := func(string) time.Duration { return 0 }
|
||||
|
||||
// the headers are listed in order of preference
|
||||
retries := []retryData{
|
||||
{
|
||||
header: HeaderRetryAfterMS,
|
||||
units: time.Millisecond,
|
||||
custom: nop,
|
||||
},
|
||||
{
|
||||
header: HeaderXMSRetryAfterMS,
|
||||
units: time.Millisecond,
|
||||
custom: nop,
|
||||
},
|
||||
{
|
||||
header: HeaderRetryAfter,
|
||||
units: time.Second,
|
||||
|
||||
// retry-after values are expressed in either number of
|
||||
// seconds or an HTTP-date indicating when to try again
|
||||
custom: func(ra string) time.Duration {
|
||||
t, err := time.Parse(time.RFC1123, ra)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return time.Until(t)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, retry := range retries {
|
||||
v := resp.Header.Get(retry.header)
|
||||
if v == "" {
|
||||
continue
|
||||
}
|
||||
if retryAfter, _ := strconv.Atoi(v); retryAfter > 0 {
|
||||
return time.Duration(retryAfter) * retry.units
|
||||
} else if d := retry.custom(v); d > 0 {
|
||||
return d
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// TypeOfT returns the type of the generic type param.
|
||||
func TypeOfT[T any]() reflect.Type {
|
||||
// you can't, at present, obtain the type of
|
||||
// a type parameter, so this is the trick
|
||||
return reflect.TypeOf((*T)(nil)).Elem()
|
||||
}
|
||||
|
||||
// TransportFunc is a helper to use a first-class func to satisfy the Transporter interface.
|
||||
type TransportFunc func(*http.Request) (*http.Response, error)
|
||||
|
||||
// Do implements the Transporter interface for the TransportFunc type.
|
||||
func (pf TransportFunc) Do(req *http.Request) (*http.Response, error) {
|
||||
return pf(req)
|
||||
}
|
||||
|
||||
// ValidateModVer verifies that moduleVersion is a valid semver 2.0 string.
|
||||
func ValidateModVer(moduleVersion string) error {
|
||||
modVerRegx := regexp.MustCompile(`^v\d+\.\d+\.\d+(?:-[a-zA-Z0-9_.-]+)?$`)
|
||||
if !modVerRegx.MatchString(moduleVersion) {
|
||||
return fmt.Errorf("malformed moduleVersion param value %s", moduleVersion)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextWithDeniedValues wraps an existing [context.Context], denying access to certain context values.
|
||||
// Pipeline policies that create new requests to be sent down their own pipeline MUST wrap the caller's
|
||||
// context with an instance of this type. This is to prevent context values from flowing across disjoint
|
||||
// requests which can have unintended side-effects.
|
||||
type ContextWithDeniedValues struct {
|
||||
context.Context
|
||||
}
|
||||
|
||||
// Value implements part of the [context.Context] interface.
|
||||
// It acts as a deny-list for certain context keys.
|
||||
func (c *ContextWithDeniedValues) Value(key any) any {
|
||||
switch key.(type) {
|
||||
case CtxAPINameKey, CtxWithCaptureResponse, CtxWithHTTPHeaderKey, CtxWithRetryOptionsKey, CtxWithTracingTracer:
|
||||
return nil
|
||||
default:
|
||||
return c.Context.Value(key)
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
||||
// Use of this source code is governed by an MIT
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package log contains functionality for configuring logging behavior.
|
||||
// Default logging to stderr can be enabled by setting environment variable AZURE_SDK_GO_LOGGING to "all".
|
||||
package log
|
||||
@@ -1,55 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
// Package log provides functionality for configuring logging facilities.
|
||||
package log
|
||||
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
|
||||
)
|
||||
|
||||
// Event is used to group entries. Each group can be toggled on or off.
|
||||
type Event = log.Event
|
||||
|
||||
const (
|
||||
// EventRequest entries contain information about HTTP requests.
|
||||
// This includes information like the URL, query parameters, and headers.
|
||||
EventRequest Event = "Request"
|
||||
|
||||
// EventResponse entries contain information about HTTP responses.
|
||||
// This includes information like the HTTP status code, headers, and request URL.
|
||||
EventResponse Event = "Response"
|
||||
|
||||
// EventResponseError entries contain information about HTTP responses that returned
|
||||
// an *azcore.ResponseError (i.e. responses with a non 2xx HTTP status code).
|
||||
// This includes the contents of ResponseError.Error().
|
||||
EventResponseError Event = "ResponseError"
|
||||
|
||||
// EventRetryPolicy entries contain information specific to the retry policy in use.
|
||||
EventRetryPolicy Event = "Retry"
|
||||
|
||||
// EventLRO entries contain information specific to long-running operations.
|
||||
// This includes information like polling location, operation state, and sleep intervals.
|
||||
EventLRO Event = "LongRunningOperation"
|
||||
)
|
||||
|
||||
// SetEvents is used to control which events are written to
|
||||
// the log. By default all log events are writen.
|
||||
// NOTE: this is not goroutine safe and should be called before using SDK clients.
|
||||
func SetEvents(cls ...Event) {
|
||||
log.SetEvents(cls...)
|
||||
}
|
||||
|
||||
// SetListener will set the Logger to write to the specified Listener.
|
||||
// NOTE: this is not goroutine safe and should be called before using SDK clients.
|
||||
func SetListener(lst func(Event, string)) {
|
||||
log.SetListener(lst)
|
||||
}
|
||||
|
||||
// for testing purposes
|
||||
func resetEvents() {
|
||||
log.TestResetEvents()
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
||||
// Use of this source code is governed by an MIT
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package policy contains the definitions needed for configuring in-box pipeline policies
|
||||
// and creating custom policies.
|
||||
package policy
|
||||
@@ -1,198 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package policy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
|
||||
)
|
||||
|
||||
// Policy represents an extensibility point for the Pipeline that can mutate the specified
|
||||
// Request and react to the received Response.
|
||||
type Policy = exported.Policy
|
||||
|
||||
// Transporter represents an HTTP pipeline transport used to send HTTP requests and receive responses.
|
||||
type Transporter = exported.Transporter
|
||||
|
||||
// Request is an abstraction over the creation of an HTTP request as it passes through the pipeline.
|
||||
// Don't use this type directly, use runtime.NewRequest() instead.
|
||||
type Request = exported.Request
|
||||
|
||||
// ClientOptions contains optional settings for a client's pipeline.
|
||||
// Instances can be shared across calls to SDK client constructors when uniform configuration is desired.
|
||||
// Zero-value fields will have their specified default values applied during use.
|
||||
type ClientOptions struct {
|
||||
// APIVersion overrides the default version requested of the service.
|
||||
// Set with caution as this package version has not been tested with arbitrary service versions.
|
||||
APIVersion string
|
||||
|
||||
// Cloud specifies a cloud for the client. The default is Azure Public Cloud.
|
||||
Cloud cloud.Configuration
|
||||
|
||||
// InsecureAllowCredentialWithHTTP enables authenticated requests over HTTP.
|
||||
// By default, authenticated requests to an HTTP endpoint are rejected by the client.
|
||||
// WARNING: setting this to true will allow sending the credential in clear text. Use with caution.
|
||||
InsecureAllowCredentialWithHTTP bool
|
||||
|
||||
// Logging configures the built-in logging policy.
|
||||
Logging LogOptions
|
||||
|
||||
// Retry configures the built-in retry policy.
|
||||
Retry RetryOptions
|
||||
|
||||
// Telemetry configures the built-in telemetry policy.
|
||||
Telemetry TelemetryOptions
|
||||
|
||||
// TracingProvider configures the tracing provider.
|
||||
// It defaults to a no-op tracer.
|
||||
TracingProvider tracing.Provider
|
||||
|
||||
// Transport sets the transport for HTTP requests.
|
||||
Transport Transporter
|
||||
|
||||
// PerCallPolicies contains custom policies to inject into the pipeline.
|
||||
// Each policy is executed once per request.
|
||||
PerCallPolicies []Policy
|
||||
|
||||
// PerRetryPolicies contains custom policies to inject into the pipeline.
|
||||
// Each policy is executed once per request, and for each retry of that request.
|
||||
PerRetryPolicies []Policy
|
||||
}
|
||||
|
||||
// LogOptions configures the logging policy's behavior.
|
||||
type LogOptions struct {
|
||||
// IncludeBody indicates if request and response bodies should be included in logging.
|
||||
// The default value is false.
|
||||
// NOTE: enabling this can lead to disclosure of sensitive information, use with care.
|
||||
IncludeBody bool
|
||||
|
||||
// AllowedHeaders is the slice of headers to log with their values intact.
|
||||
// All headers not in the slice will have their values REDACTED.
|
||||
// Applies to request and response headers.
|
||||
AllowedHeaders []string
|
||||
|
||||
// AllowedQueryParams is the slice of query parameters to log with their values intact.
|
||||
// All query parameters not in the slice will have their values REDACTED.
|
||||
AllowedQueryParams []string
|
||||
}
|
||||
|
||||
// RetryOptions configures the retry policy's behavior.
|
||||
// Zero-value fields will have their specified default values applied during use.
|
||||
// This allows for modification of a subset of fields.
|
||||
type RetryOptions struct {
|
||||
// MaxRetries specifies the maximum number of attempts a failed operation will be retried
|
||||
// before producing an error.
|
||||
// The default value is three. A value less than zero means one try and no retries.
|
||||
MaxRetries int32
|
||||
|
||||
// TryTimeout indicates the maximum time allowed for any single try of an HTTP request.
|
||||
// This is disabled by default. Specify a value greater than zero to enable.
|
||||
// NOTE: Setting this to a small value might cause premature HTTP request time-outs.
|
||||
TryTimeout time.Duration
|
||||
|
||||
// RetryDelay specifies the initial amount of delay to use before retrying an operation.
|
||||
// The value is used only if the HTTP response does not contain a Retry-After header.
|
||||
// The delay increases exponentially with each retry up to the maximum specified by MaxRetryDelay.
|
||||
// The default value is four seconds. A value less than zero means no delay between retries.
|
||||
RetryDelay time.Duration
|
||||
|
||||
// MaxRetryDelay specifies the maximum delay allowed before retrying an operation.
|
||||
// Typically the value is greater than or equal to the value specified in RetryDelay.
|
||||
// The default Value is 60 seconds. A value less than zero means there is no cap.
|
||||
MaxRetryDelay time.Duration
|
||||
|
||||
// StatusCodes specifies the HTTP status codes that indicate the operation should be retried.
|
||||
// A nil slice will use the following values.
|
||||
// http.StatusRequestTimeout 408
|
||||
// http.StatusTooManyRequests 429
|
||||
// http.StatusInternalServerError 500
|
||||
// http.StatusBadGateway 502
|
||||
// http.StatusServiceUnavailable 503
|
||||
// http.StatusGatewayTimeout 504
|
||||
// Specifying values will replace the default values.
|
||||
// Specifying an empty slice will disable retries for HTTP status codes.
|
||||
StatusCodes []int
|
||||
|
||||
// ShouldRetry evaluates if the retry policy should retry the request.
|
||||
// When specified, the function overrides comparison against the list of
|
||||
// HTTP status codes and error checking within the retry policy. Context
|
||||
// and NonRetriable errors remain evaluated before calling ShouldRetry.
|
||||
// The *http.Response and error parameters are mutually exclusive, i.e.
|
||||
// if one is nil, the other is not nil.
|
||||
// A return value of true means the retry policy should retry.
|
||||
ShouldRetry func(*http.Response, error) bool
|
||||
}
|
||||
|
||||
// TelemetryOptions configures the telemetry policy's behavior.
|
||||
type TelemetryOptions struct {
|
||||
// ApplicationID is an application-specific identification string to add to the User-Agent.
|
||||
// It has a maximum length of 24 characters and must not contain any spaces.
|
||||
ApplicationID string
|
||||
|
||||
// Disabled will prevent the addition of any telemetry data to the User-Agent.
|
||||
Disabled bool
|
||||
}
|
||||
|
||||
// TokenRequestOptions contain specific parameter that may be used by credentials types when attempting to get a token.
|
||||
type TokenRequestOptions = exported.TokenRequestOptions
|
||||
|
||||
// BearerTokenOptions configures the bearer token policy's behavior.
|
||||
type BearerTokenOptions struct {
|
||||
// AuthorizationHandler allows SDK developers to run client-specific logic when BearerTokenPolicy must authorize a request.
|
||||
// When this field isn't set, the policy follows its default behavior of authorizing every request with a bearer token from
|
||||
// its given credential.
|
||||
AuthorizationHandler AuthorizationHandler
|
||||
|
||||
// InsecureAllowCredentialWithHTTP enables authenticated requests over HTTP.
|
||||
// By default, authenticated requests to an HTTP endpoint are rejected by the client.
|
||||
// WARNING: setting this to true will allow sending the bearer token in clear text. Use with caution.
|
||||
InsecureAllowCredentialWithHTTP bool
|
||||
}
|
||||
|
||||
// AuthorizationHandler allows SDK developers to insert custom logic that runs when BearerTokenPolicy must authorize a request.
|
||||
type AuthorizationHandler struct {
|
||||
// OnRequest provides TokenRequestOptions the policy can use to acquire a token for a request. The policy calls OnRequest
|
||||
// whenever it needs a token and may call it multiple times for the same request. Its func parameter authorizes the request
|
||||
// with a token from the policy's credential. Implementations that need to perform I/O should use the Request's context,
|
||||
// available from Request.Raw().Context(). When OnRequest returns an error, the policy propagates that error and doesn't send
|
||||
// the request. When OnRequest is nil, the policy follows its default behavior, which is to authorize the request with a token
|
||||
// from its credential according to its configuration.
|
||||
OnRequest func(*Request, func(TokenRequestOptions) error) error
|
||||
|
||||
// OnChallenge allows clients to implement custom HTTP authentication challenge handling. BearerTokenPolicy calls it upon
|
||||
// receiving a 401 response containing multiple Bearer challenges or a challenge BearerTokenPolicy itself can't handle.
|
||||
// OnChallenge is responsible for parsing challenge(s) (the Response's WWW-Authenticate header) and reauthorizing the
|
||||
// Request accordingly. Its func argument authorizes the Request with a token from the policy's credential using the given
|
||||
// TokenRequestOptions. OnChallenge should honor the Request's context, available from Request.Raw().Context(). When
|
||||
// OnChallenge returns nil, the policy will send the Request again.
|
||||
OnChallenge func(*Request, *http.Response, func(TokenRequestOptions) error) error
|
||||
}
|
||||
|
||||
// WithCaptureResponse applies the HTTP response retrieval annotation to the parent context.
|
||||
// The resp parameter will contain the HTTP response after the request has completed.
|
||||
func WithCaptureResponse(parent context.Context, resp **http.Response) context.Context {
|
||||
return context.WithValue(parent, shared.CtxWithCaptureResponse{}, resp)
|
||||
}
|
||||
|
||||
// WithHTTPHeader adds the specified http.Header to the parent context.
|
||||
// Use this to specify custom HTTP headers at the API-call level.
|
||||
// Any overlapping headers will have their values replaced with the values specified here.
|
||||
func WithHTTPHeader(parent context.Context, header http.Header) context.Context {
|
||||
return context.WithValue(parent, shared.CtxWithHTTPHeaderKey{}, header)
|
||||
}
|
||||
|
||||
// WithRetryOptions adds the specified RetryOptions to the parent context.
|
||||
// Use this to specify custom RetryOptions at the API-call level.
|
||||
func WithRetryOptions(parent context.Context, options RetryOptions) context.Context {
|
||||
return context.WithValue(parent, shared.CtxWithRetryOptionsKey{}, options)
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
||||
// Use of this source code is governed by an MIT
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package runtime contains various facilities for creating requests and handling responses.
|
||||
// The content is intended for SDK authors.
|
||||
package runtime
|
||||
@@ -1,27 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
)
|
||||
|
||||
// NewResponseError creates an *azcore.ResponseError from the provided HTTP response.
|
||||
// Call this when a service request returns a non-successful status code.
|
||||
// The error code will be extracted from the *http.Response, either from the x-ms-error-code
|
||||
// header (preferred) or attempted to be parsed from the response body.
|
||||
func NewResponseError(resp *http.Response) error {
|
||||
return exported.NewResponseError(resp)
|
||||
}
|
||||
|
||||
// NewResponseErrorWithErrorCode creates an *azcore.ResponseError from the provided HTTP response and errorCode.
|
||||
// Use this variant when the error code is in a non-standard location.
|
||||
func NewResponseErrorWithErrorCode(resp *http.Response, errorCode string) error {
|
||||
return exported.NewResponseErrorWithErrorCode(resp, errorCode)
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
|
||||
)
|
||||
|
||||
// PagingHandler contains the required data for constructing a Pager.
|
||||
type PagingHandler[T any] struct {
|
||||
// More returns a boolean indicating if there are more pages to fetch.
|
||||
// It uses the provided page to make the determination.
|
||||
More func(T) bool
|
||||
|
||||
// Fetcher fetches the first and subsequent pages.
|
||||
Fetcher func(context.Context, *T) (T, error)
|
||||
|
||||
// Tracer contains the Tracer from the client that's creating the Pager.
|
||||
Tracer tracing.Tracer
|
||||
}
|
||||
|
||||
// Pager provides operations for iterating over paged responses.
|
||||
// Methods on this type are not safe for concurrent use.
|
||||
type Pager[T any] struct {
|
||||
current *T
|
||||
handler PagingHandler[T]
|
||||
tracer tracing.Tracer
|
||||
firstPage bool
|
||||
}
|
||||
|
||||
// NewPager creates an instance of Pager using the specified PagingHandler.
|
||||
// Pass a non-nil T for firstPage if the first page has already been retrieved.
|
||||
func NewPager[T any](handler PagingHandler[T]) *Pager[T] {
|
||||
return &Pager[T]{
|
||||
handler: handler,
|
||||
tracer: handler.Tracer,
|
||||
firstPage: true,
|
||||
}
|
||||
}
|
||||
|
||||
// More returns true if there are more pages to retrieve.
|
||||
func (p *Pager[T]) More() bool {
|
||||
if p.current != nil {
|
||||
return p.handler.More(*p.current)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// NextPage advances the pager to the next page.
|
||||
func (p *Pager[T]) NextPage(ctx context.Context) (T, error) {
|
||||
if p.current != nil {
|
||||
if p.firstPage {
|
||||
// we get here if it's an LRO-pager, we already have the first page
|
||||
p.firstPage = false
|
||||
return *p.current, nil
|
||||
} else if !p.handler.More(*p.current) {
|
||||
return *new(T), errors.New("no more pages")
|
||||
}
|
||||
} else {
|
||||
// non-LRO case, first page
|
||||
p.firstPage = false
|
||||
}
|
||||
|
||||
var err error
|
||||
ctx, endSpan := StartSpan(ctx, fmt.Sprintf("%s.NextPage", shortenTypeName(reflect.TypeOf(*p).Name())), p.tracer, nil)
|
||||
defer func() { endSpan(err) }()
|
||||
|
||||
resp, err := p.handler.Fetcher(ctx, p.current)
|
||||
if err != nil {
|
||||
return *new(T), err
|
||||
}
|
||||
p.current = &resp
|
||||
return *p.current, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface for Pager[T].
|
||||
func (p *Pager[T]) UnmarshalJSON(data []byte) error {
|
||||
return json.Unmarshal(data, &p.current)
|
||||
}
|
||||
|
||||
// FetcherForNextLinkOptions contains the optional values for [FetcherForNextLink].
|
||||
type FetcherForNextLinkOptions struct {
|
||||
// NextReq is the func to be called when requesting subsequent pages.
|
||||
// Used for paged operations that have a custom next link operation.
|
||||
NextReq func(context.Context, string) (*policy.Request, error)
|
||||
|
||||
// StatusCodes contains additional HTTP status codes indicating success.
|
||||
// The default value is http.StatusOK.
|
||||
StatusCodes []int
|
||||
}
|
||||
|
||||
// FetcherForNextLink is a helper containing boilerplate code to simplify creating a PagingHandler[T].Fetcher from a next link URL.
|
||||
// - ctx is the [context.Context] controlling the lifetime of the HTTP operation
|
||||
// - pl is the [Pipeline] used to dispatch the HTTP request
|
||||
// - nextLink is the URL used to fetch the next page. the empty string indicates the first page is to be requested
|
||||
// - firstReq is the func to be called when creating the request for the first page
|
||||
// - options contains any optional parameters, pass nil to accept the default values
|
||||
func FetcherForNextLink(ctx context.Context, pl Pipeline, nextLink string, firstReq func(context.Context) (*policy.Request, error), options *FetcherForNextLinkOptions) (*http.Response, error) {
|
||||
var req *policy.Request
|
||||
var err error
|
||||
if options == nil {
|
||||
options = &FetcherForNextLinkOptions{}
|
||||
}
|
||||
if nextLink == "" {
|
||||
req, err = firstReq(ctx)
|
||||
} else if nextLink, err = EncodeQueryParams(nextLink); err == nil {
|
||||
if options.NextReq != nil {
|
||||
req, err = options.NextReq(ctx, nextLink)
|
||||
} else {
|
||||
req, err = NewRequest(ctx, http.MethodGet, nextLink)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := pl.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
successCodes := []int{http.StatusOK}
|
||||
successCodes = append(successCodes, options.StatusCodes...)
|
||||
if !HasStatusCode(resp, successCodes...) {
|
||||
return nil, NewResponseError(resp)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
)
|
||||
|
||||
// PipelineOptions contains Pipeline options for SDK developers
|
||||
type PipelineOptions struct {
|
||||
// AllowedHeaders is the slice of headers to log with their values intact.
|
||||
// All headers not in the slice will have their values REDACTED.
|
||||
// Applies to request and response headers.
|
||||
AllowedHeaders []string
|
||||
|
||||
// AllowedQueryParameters is the slice of query parameters to log with their values intact.
|
||||
// All query parameters not in the slice will have their values REDACTED.
|
||||
AllowedQueryParameters []string
|
||||
|
||||
// APIVersion overrides the default version requested of the service.
|
||||
// Set with caution as this package version has not been tested with arbitrary service versions.
|
||||
APIVersion APIVersionOptions
|
||||
|
||||
// PerCall contains custom policies to inject into the pipeline.
|
||||
// Each policy is executed once per request.
|
||||
PerCall []policy.Policy
|
||||
|
||||
// PerRetry contains custom policies to inject into the pipeline.
|
||||
// Each policy is executed once per request, and for each retry of that request.
|
||||
PerRetry []policy.Policy
|
||||
|
||||
// Tracing contains options used to configure distributed tracing.
|
||||
Tracing TracingOptions
|
||||
}
|
||||
|
||||
// TracingOptions contains tracing options for SDK developers.
|
||||
type TracingOptions struct {
|
||||
// Namespace contains the value to use for the az.namespace span attribute.
|
||||
Namespace string
|
||||
}
|
||||
|
||||
// Pipeline represents a primitive for sending HTTP requests and receiving responses.
|
||||
// Its behavior can be extended by specifying policies during construction.
|
||||
type Pipeline = exported.Pipeline
|
||||
|
||||
// NewPipeline creates a pipeline from connection options, with any additional policies as specified.
|
||||
// Policies from ClientOptions are placed after policies from PipelineOptions.
|
||||
// The module and version parameters are used by the telemetry policy, when enabled.
|
||||
func NewPipeline(module, version string, plOpts PipelineOptions, options *policy.ClientOptions) Pipeline {
|
||||
cp := policy.ClientOptions{}
|
||||
if options != nil {
|
||||
cp = *options
|
||||
}
|
||||
if len(plOpts.AllowedHeaders) > 0 {
|
||||
headers := make([]string, len(plOpts.AllowedHeaders)+len(cp.Logging.AllowedHeaders))
|
||||
copy(headers, plOpts.AllowedHeaders)
|
||||
headers = append(headers, cp.Logging.AllowedHeaders...)
|
||||
cp.Logging.AllowedHeaders = headers
|
||||
}
|
||||
if len(plOpts.AllowedQueryParameters) > 0 {
|
||||
qp := make([]string, len(plOpts.AllowedQueryParameters)+len(cp.Logging.AllowedQueryParams))
|
||||
copy(qp, plOpts.AllowedQueryParameters)
|
||||
qp = append(qp, cp.Logging.AllowedQueryParams...)
|
||||
cp.Logging.AllowedQueryParams = qp
|
||||
}
|
||||
// we put the includeResponsePolicy at the very beginning so that the raw response
|
||||
// is populated with the final response (some policies might mutate the response)
|
||||
policies := []policy.Policy{exported.PolicyFunc(includeResponsePolicy)}
|
||||
if cp.APIVersion != "" {
|
||||
policies = append(policies, newAPIVersionPolicy(cp.APIVersion, &plOpts.APIVersion))
|
||||
}
|
||||
if !cp.Telemetry.Disabled {
|
||||
policies = append(policies, NewTelemetryPolicy(module, version, &cp.Telemetry))
|
||||
}
|
||||
policies = append(policies, plOpts.PerCall...)
|
||||
policies = append(policies, cp.PerCallPolicies...)
|
||||
policies = append(policies, NewRetryPolicy(&cp.Retry))
|
||||
policies = append(policies, plOpts.PerRetry...)
|
||||
policies = append(policies, cp.PerRetryPolicies...)
|
||||
policies = append(policies, exported.PolicyFunc(httpHeaderPolicy))
|
||||
policies = append(policies, newHTTPTracePolicy(cp.Logging.AllowedQueryParams))
|
||||
policies = append(policies, NewLogPolicy(&cp.Logging))
|
||||
policies = append(policies, exported.PolicyFunc(bodyDownloadPolicy))
|
||||
transport := cp.Transport
|
||||
if transport == nil {
|
||||
transport = defaultHTTPClient
|
||||
}
|
||||
return exported.NewPipeline(transport, policies...)
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
)
|
||||
|
||||
// APIVersionOptions contains options for API versions
|
||||
type APIVersionOptions struct {
|
||||
// Location indicates where to set the version on a request, for example in a header or query param
|
||||
Location APIVersionLocation
|
||||
// Name is the name of the header or query parameter, for example "api-version"
|
||||
Name string
|
||||
}
|
||||
|
||||
// APIVersionLocation indicates which part of a request identifies the service version
|
||||
type APIVersionLocation int
|
||||
|
||||
const (
|
||||
// APIVersionLocationQueryParam indicates a query parameter
|
||||
APIVersionLocationQueryParam = 0
|
||||
// APIVersionLocationHeader indicates a header
|
||||
APIVersionLocationHeader = 1
|
||||
)
|
||||
|
||||
// newAPIVersionPolicy constructs an APIVersionPolicy. If version is "", Do will be a no-op. If version
|
||||
// isn't empty and opts.Name is empty, Do will return an error.
|
||||
func newAPIVersionPolicy(version string, opts *APIVersionOptions) *apiVersionPolicy {
|
||||
if opts == nil {
|
||||
opts = &APIVersionOptions{}
|
||||
}
|
||||
return &apiVersionPolicy{location: opts.Location, name: opts.Name, version: version}
|
||||
}
|
||||
|
||||
// apiVersionPolicy enables users to set the API version of every request a client sends.
|
||||
type apiVersionPolicy struct {
|
||||
// location indicates whether "name" refers to a query parameter or header.
|
||||
location APIVersionLocation
|
||||
|
||||
// name of the query param or header whose value should be overridden; provided by the client.
|
||||
name string
|
||||
|
||||
// version is the value (provided by the user) that replaces the default version value.
|
||||
version string
|
||||
}
|
||||
|
||||
// Do sets the request's API version, if the policy is configured to do so, replacing any prior value.
|
||||
func (a *apiVersionPolicy) Do(req *policy.Request) (*http.Response, error) {
|
||||
if a.version != "" {
|
||||
if a.name == "" {
|
||||
// user set ClientOptions.APIVersion but the client ctor didn't set PipelineOptions.APIVersionOptions
|
||||
return nil, errors.New("this client doesn't support overriding its API version")
|
||||
}
|
||||
switch a.location {
|
||||
case APIVersionLocationHeader:
|
||||
req.Raw().Header.Set(a.name, a.version)
|
||||
case APIVersionLocationQueryParam:
|
||||
q := req.Raw().URL.Query()
|
||||
q.Set(a.name, a.version)
|
||||
req.Raw().URL.RawQuery = q.Encode()
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown APIVersionLocation %d", a.location)
|
||||
}
|
||||
}
|
||||
return req.Next()
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/temporal"
|
||||
)
|
||||
|
||||
// BearerTokenPolicy authorizes requests with bearer tokens acquired from a TokenCredential.
|
||||
// It handles [Continuous Access Evaluation] (CAE) challenges. Clients needing to handle
|
||||
// additional authentication challenges, or needing more control over authorization, should
|
||||
// provide a [policy.AuthorizationHandler] in [policy.BearerTokenOptions].
|
||||
//
|
||||
// [Continuous Access Evaluation]: https://learn.microsoft.com/entra/identity/conditional-access/concept-continuous-access-evaluation
|
||||
type BearerTokenPolicy struct {
|
||||
// mainResource is the resource to be retreived using the tenant specified in the credential
|
||||
mainResource *temporal.Resource[exported.AccessToken, acquiringResourceState]
|
||||
// the following fields are read-only
|
||||
authzHandler policy.AuthorizationHandler
|
||||
cred exported.TokenCredential
|
||||
scopes []string
|
||||
allowHTTP bool
|
||||
}
|
||||
|
||||
type acquiringResourceState struct {
|
||||
req *policy.Request
|
||||
p *BearerTokenPolicy
|
||||
tro policy.TokenRequestOptions
|
||||
}
|
||||
|
||||
// acquire acquires or updates the resource; only one
|
||||
// thread/goroutine at a time ever calls this function
|
||||
func acquire(state acquiringResourceState) (newResource exported.AccessToken, newExpiration time.Time, err error) {
|
||||
tk, err := state.p.cred.GetToken(&shared.ContextWithDeniedValues{Context: state.req.Raw().Context()}, state.tro)
|
||||
if err != nil {
|
||||
return exported.AccessToken{}, time.Time{}, err
|
||||
}
|
||||
return tk, tk.ExpiresOn, nil
|
||||
}
|
||||
|
||||
// NewBearerTokenPolicy creates a policy object that authorizes requests with bearer tokens.
|
||||
// cred: an azcore.TokenCredential implementation such as a credential object from azidentity
|
||||
// scopes: the list of permission scopes required for the token.
|
||||
// opts: optional settings. Pass nil to accept default values; this is the same as passing a zero-value options.
|
||||
func NewBearerTokenPolicy(cred exported.TokenCredential, scopes []string, opts *policy.BearerTokenOptions) *BearerTokenPolicy {
|
||||
if opts == nil {
|
||||
opts = &policy.BearerTokenOptions{}
|
||||
}
|
||||
ah := opts.AuthorizationHandler
|
||||
if ah.OnRequest == nil {
|
||||
// Set a default OnRequest that simply requests a token with the given scopes. OnChallenge
|
||||
// doesn't get a default so the policy can use a nil check to determine whether the caller
|
||||
// provided an implementation.
|
||||
ah.OnRequest = func(_ *policy.Request, authNZ func(policy.TokenRequestOptions) error) error {
|
||||
// authNZ sets EnableCAE: true in all cases, no need to duplicate that here
|
||||
return authNZ(policy.TokenRequestOptions{Scopes: scopes})
|
||||
}
|
||||
}
|
||||
return &BearerTokenPolicy{
|
||||
authzHandler: ah,
|
||||
cred: cred,
|
||||
scopes: scopes,
|
||||
mainResource: temporal.NewResource(acquire),
|
||||
allowHTTP: opts.InsecureAllowCredentialWithHTTP,
|
||||
}
|
||||
}
|
||||
|
||||
// authenticateAndAuthorize returns a function which authorizes req with a token from the policy's credential
|
||||
func (b *BearerTokenPolicy) authenticateAndAuthorize(req *policy.Request) func(policy.TokenRequestOptions) error {
|
||||
return func(tro policy.TokenRequestOptions) error {
|
||||
tro.EnableCAE = true
|
||||
as := acquiringResourceState{p: b, req: req, tro: tro}
|
||||
tk, err := b.mainResource.Get(as)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Raw().Header.Set(shared.HeaderAuthorization, shared.BearerTokenPrefix+tk.Token)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Do authorizes a request with a bearer token
|
||||
func (b *BearerTokenPolicy) Do(req *policy.Request) (*http.Response, error) {
|
||||
// skip adding the authorization header if no TokenCredential was provided.
|
||||
// this prevents a panic that might be hard to diagnose and allows testing
|
||||
// against http endpoints that don't require authentication.
|
||||
if b.cred == nil {
|
||||
return req.Next()
|
||||
}
|
||||
|
||||
if err := checkHTTPSForAuth(req, b.allowHTTP); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err := b.authzHandler.OnRequest(req, b.authenticateAndAuthorize(req))
|
||||
if err != nil {
|
||||
return nil, errorinfo.NonRetriableError(err)
|
||||
}
|
||||
|
||||
res, err := req.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err = b.handleChallenge(req, res, false)
|
||||
return res, err
|
||||
}
|
||||
|
||||
// handleChallenge handles authentication challenges either directly (for CAE challenges) or by calling
|
||||
// the AuthorizationHandler. It's a no-op when the response doesn't include an authentication challenge.
|
||||
// It will recurse at most once, to handle a CAE challenge following a non-CAE challenge handled by the
|
||||
// AuthorizationHandler.
|
||||
func (b *BearerTokenPolicy) handleChallenge(req *policy.Request, res *http.Response, recursed bool) (*http.Response, error) {
|
||||
var err error
|
||||
if res.StatusCode == http.StatusUnauthorized {
|
||||
b.mainResource.Expire()
|
||||
if res.Header.Get(shared.HeaderWWWAuthenticate) != "" {
|
||||
caeChallenge, parseErr := parseCAEChallenge(res)
|
||||
if parseErr != nil {
|
||||
return res, parseErr
|
||||
}
|
||||
switch {
|
||||
case caeChallenge != nil:
|
||||
authNZ := func(tro policy.TokenRequestOptions) error {
|
||||
// Take the TokenRequestOptions provided by OnRequest and add the challenge claims. The value
|
||||
// will be empty at time of writing because CAE is the only feature involving claims. If in
|
||||
// the future some client needs to specify unrelated claims, this function may need to merge
|
||||
// them with the challenge claims.
|
||||
tro.Claims = caeChallenge.params["claims"]
|
||||
return b.authenticateAndAuthorize(req)(tro)
|
||||
}
|
||||
if err = b.authzHandler.OnRequest(req, authNZ); err == nil {
|
||||
if err = req.RewindBody(); err == nil {
|
||||
res, err = req.Next()
|
||||
}
|
||||
}
|
||||
case b.authzHandler.OnChallenge != nil && !recursed:
|
||||
if err = b.authzHandler.OnChallenge(req, res, b.authenticateAndAuthorize(req)); err == nil {
|
||||
if err = req.RewindBody(); err == nil {
|
||||
if res, err = req.Next(); err == nil {
|
||||
res, err = b.handleChallenge(req, res, true)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// don't retry challenge handling errors
|
||||
err = errorinfo.NonRetriableError(err)
|
||||
}
|
||||
default:
|
||||
// return the response to the pipeline
|
||||
}
|
||||
}
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func checkHTTPSForAuth(req *policy.Request, allowHTTP bool) error {
|
||||
if strings.ToLower(req.Raw().URL.Scheme) != "https" && !allowHTTP {
|
||||
return errorinfo.NonRetriableError(errors.New("authenticated requests are not permitted for non TLS protected (https) endpoints"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseCAEChallenge returns a *authChallenge representing Response's CAE challenge (nil when Response has none).
|
||||
// If Response includes a CAE challenge having invalid claims, it returns a NonRetriableError.
|
||||
func parseCAEChallenge(res *http.Response) (*authChallenge, error) {
|
||||
var (
|
||||
caeChallenge *authChallenge
|
||||
err error
|
||||
)
|
||||
for _, c := range parseChallenges(res) {
|
||||
if c.scheme == "Bearer" {
|
||||
if claims := c.params["claims"]; claims != "" && c.params["error"] == "insufficient_claims" {
|
||||
if b, de := base64.StdEncoding.DecodeString(claims); de == nil {
|
||||
c.params["claims"] = string(b)
|
||||
caeChallenge = &c
|
||||
} else {
|
||||
// don't include the decoding error because it's something
|
||||
// unhelpful like "illegal base64 data at input byte 42"
|
||||
err = errorinfo.NonRetriableError(errors.New("authentication challenge contains invalid claims: " + claims))
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return caeChallenge, err
|
||||
}
|
||||
|
||||
var (
|
||||
challenge, challengeParams *regexp.Regexp
|
||||
once = &sync.Once{}
|
||||
)
|
||||
|
||||
type authChallenge struct {
|
||||
scheme string
|
||||
params map[string]string
|
||||
}
|
||||
|
||||
// parseChallenges assumes authentication challenges have quoted parameter values
|
||||
func parseChallenges(res *http.Response) []authChallenge {
|
||||
once.Do(func() {
|
||||
// matches challenges having quoted parameters, capturing scheme and parameters
|
||||
challenge = regexp.MustCompile(`(?:(\w+) ((?:\w+="[^"]*",?\s*)+))`)
|
||||
// captures parameter names and values in a match of the above expression
|
||||
challengeParams = regexp.MustCompile(`(\w+)="([^"]*)"`)
|
||||
})
|
||||
parsed := []authChallenge{}
|
||||
// WWW-Authenticate can have multiple values, each containing multiple challenges
|
||||
for _, h := range res.Header.Values(shared.HeaderWWWAuthenticate) {
|
||||
for _, sm := range challenge.FindAllStringSubmatch(h, -1) {
|
||||
// sm is [challenge, scheme, params] (see regexp documentation on submatches)
|
||||
c := authChallenge{
|
||||
params: make(map[string]string),
|
||||
scheme: sm[1],
|
||||
}
|
||||
for _, sm := range challengeParams.FindAllStringSubmatch(sm[2], -1) {
|
||||
// sm is [key="value", key, value] (see regexp documentation on submatches)
|
||||
c.params[sm[1]] = sm[2]
|
||||
}
|
||||
parsed = append(parsed, c)
|
||||
}
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo"
|
||||
)
|
||||
|
||||
// bodyDownloadPolicy creates a policy object that downloads the response's body to a []byte.
|
||||
func bodyDownloadPolicy(req *policy.Request) (*http.Response, error) {
|
||||
resp, err := req.Next()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
var opValues bodyDownloadPolicyOpValues
|
||||
// don't skip downloading error response bodies
|
||||
if req.OperationValue(&opValues); opValues.Skip && resp.StatusCode < 400 {
|
||||
return resp, err
|
||||
}
|
||||
// Either bodyDownloadPolicyOpValues was not specified (so skip is false)
|
||||
// or it was specified and skip is false: don't skip downloading the body
|
||||
_, err = Payload(resp)
|
||||
if err != nil {
|
||||
return resp, newBodyDownloadError(err, req)
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// bodyDownloadPolicyOpValues is the struct containing the per-operation values
|
||||
type bodyDownloadPolicyOpValues struct {
|
||||
Skip bool
|
||||
}
|
||||
|
||||
type bodyDownloadError struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func newBodyDownloadError(err error, req *policy.Request) error {
|
||||
// on failure, only retry the request for idempotent operations.
|
||||
// we currently identify them as DELETE, GET, and PUT requests.
|
||||
if m := strings.ToUpper(req.Raw().Method); m == http.MethodDelete || m == http.MethodGet || m == http.MethodPut {
|
||||
// error is safe for retry
|
||||
return err
|
||||
}
|
||||
// wrap error to avoid retries
|
||||
return &bodyDownloadError{
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *bodyDownloadError) Error() string {
|
||||
return fmt.Sprintf("body download policy: %s", b.err.Error())
|
||||
}
|
||||
|
||||
func (b *bodyDownloadError) NonRetriable() {
|
||||
// marker method
|
||||
}
|
||||
|
||||
func (b *bodyDownloadError) Unwrap() error {
|
||||
return b.err
|
||||
}
|
||||
|
||||
var _ errorinfo.NonRetriable = (*bodyDownloadError)(nil)
|
||||
@@ -1,40 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
)
|
||||
|
||||
// newHTTPHeaderPolicy creates a policy object that adds custom HTTP headers to a request
|
||||
func httpHeaderPolicy(req *policy.Request) (*http.Response, error) {
|
||||
// check if any custom HTTP headers have been specified
|
||||
if header := req.Raw().Context().Value(shared.CtxWithHTTPHeaderKey{}); header != nil {
|
||||
for k, v := range header.(http.Header) {
|
||||
// use Set to replace any existing value
|
||||
// it also canonicalizes the header key
|
||||
req.Raw().Header.Set(k, v[0])
|
||||
// add any remaining values
|
||||
for i := 1; i < len(v); i++ {
|
||||
req.Raw().Header.Add(k, v[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
return req.Next()
|
||||
}
|
||||
|
||||
// WithHTTPHeader adds the specified http.Header to the parent context.
|
||||
// Use this to specify custom HTTP headers at the API-call level.
|
||||
// Any overlapping headers will have their values replaced with the values specified here.
|
||||
// Deprecated: use [policy.WithHTTPHeader] instead.
|
||||
func WithHTTPHeader(parent context.Context, header http.Header) context.Context {
|
||||
return policy.WithHTTPHeader(parent, header)
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
|
||||
)
|
||||
|
||||
const (
|
||||
attrHTTPMethod = "http.method"
|
||||
attrHTTPURL = "http.url"
|
||||
attrHTTPUserAgent = "http.user_agent"
|
||||
attrHTTPStatusCode = "http.status_code"
|
||||
|
||||
attrAZClientReqID = "az.client_request_id"
|
||||
attrAZServiceReqID = "az.service_request_id"
|
||||
|
||||
attrNetPeerName = "net.peer.name"
|
||||
)
|
||||
|
||||
// newHTTPTracePolicy creates a new instance of the httpTracePolicy.
|
||||
// - allowedQueryParams contains the user-specified query parameters that don't need to be redacted from the trace
|
||||
func newHTTPTracePolicy(allowedQueryParams []string) exported.Policy {
|
||||
return &httpTracePolicy{allowedQP: getAllowedQueryParams(allowedQueryParams)}
|
||||
}
|
||||
|
||||
// httpTracePolicy is a policy that creates a trace for the HTTP request and its response
|
||||
type httpTracePolicy struct {
|
||||
allowedQP map[string]struct{}
|
||||
}
|
||||
|
||||
// Do implements the pipeline.Policy interfaces for the httpTracePolicy type.
|
||||
func (h *httpTracePolicy) Do(req *policy.Request) (resp *http.Response, err error) {
|
||||
rawTracer := req.Raw().Context().Value(shared.CtxWithTracingTracer{})
|
||||
if tracer, ok := rawTracer.(tracing.Tracer); ok && tracer.Enabled() {
|
||||
attributes := []tracing.Attribute{
|
||||
{Key: attrHTTPMethod, Value: req.Raw().Method},
|
||||
{Key: attrHTTPURL, Value: getSanitizedURL(*req.Raw().URL, h.allowedQP)},
|
||||
{Key: attrNetPeerName, Value: req.Raw().URL.Host},
|
||||
}
|
||||
|
||||
if ua := req.Raw().Header.Get(shared.HeaderUserAgent); ua != "" {
|
||||
attributes = append(attributes, tracing.Attribute{Key: attrHTTPUserAgent, Value: ua})
|
||||
}
|
||||
if reqID := req.Raw().Header.Get(shared.HeaderXMSClientRequestID); reqID != "" {
|
||||
attributes = append(attributes, tracing.Attribute{Key: attrAZClientReqID, Value: reqID})
|
||||
}
|
||||
|
||||
ctx := req.Raw().Context()
|
||||
ctx, span := tracer.Start(ctx, "HTTP "+req.Raw().Method, &tracing.SpanOptions{
|
||||
Kind: tracing.SpanKindClient,
|
||||
Attributes: attributes,
|
||||
})
|
||||
|
||||
defer func() {
|
||||
if resp != nil {
|
||||
span.SetAttributes(tracing.Attribute{Key: attrHTTPStatusCode, Value: resp.StatusCode})
|
||||
if resp.StatusCode > 399 {
|
||||
span.SetStatus(tracing.SpanStatusError, resp.Status)
|
||||
}
|
||||
if reqID := resp.Header.Get(shared.HeaderXMSRequestID); reqID != "" {
|
||||
span.SetAttributes(tracing.Attribute{Key: attrAZServiceReqID, Value: reqID})
|
||||
}
|
||||
} else if err != nil {
|
||||
var urlErr *url.Error
|
||||
if errors.As(err, &urlErr) {
|
||||
// calling *url.Error.Error() will include the unsanitized URL
|
||||
// which we don't want. in addition, we already have the HTTP verb
|
||||
// and sanitized URL in the trace so we aren't losing any info
|
||||
err = urlErr.Err
|
||||
}
|
||||
span.SetStatus(tracing.SpanStatusError, err.Error())
|
||||
}
|
||||
span.End()
|
||||
}()
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
}
|
||||
resp, err = req.Next()
|
||||
return
|
||||
}
|
||||
|
||||
// StartSpanOptions contains the optional values for StartSpan.
|
||||
type StartSpanOptions struct {
|
||||
// Kind indicates the kind of Span.
|
||||
Kind tracing.SpanKind
|
||||
// Attributes contains key-value pairs of attributes for the span.
|
||||
Attributes []tracing.Attribute
|
||||
}
|
||||
|
||||
// StartSpan starts a new tracing span.
|
||||
// You must call the returned func to terminate the span. Pass the applicable error
|
||||
// if the span will exit with an error condition.
|
||||
// - ctx is the parent context of the newly created context
|
||||
// - name is the name of the span. this is typically the fully qualified name of an API ("Client.Method")
|
||||
// - tracer is the client's Tracer for creating spans
|
||||
// - options contains optional values. pass nil to accept any default values
|
||||
func StartSpan(ctx context.Context, name string, tracer tracing.Tracer, options *StartSpanOptions) (context.Context, func(error)) {
|
||||
if !tracer.Enabled() {
|
||||
return ctx, func(err error) {}
|
||||
}
|
||||
|
||||
// we MUST propagate the active tracer before returning so that the trace policy can access it
|
||||
ctx = context.WithValue(ctx, shared.CtxWithTracingTracer{}, tracer)
|
||||
|
||||
if activeSpan := ctx.Value(ctxActiveSpan{}); activeSpan != nil {
|
||||
// per the design guidelines, if a SDK method Foo() calls SDK method Bar(),
|
||||
// then the span for Bar() must be suppressed. however, if Bar() makes a REST
|
||||
// call, then Bar's HTTP span must be a child of Foo's span.
|
||||
// however, there is an exception to this rule. if the SDK method Foo() is a
|
||||
// messaging producer/consumer, and it takes a callback that's a SDK method
|
||||
// Bar(), then the span for Bar() must _not_ be suppressed.
|
||||
if kind := activeSpan.(tracing.SpanKind); kind == tracing.SpanKindClient || kind == tracing.SpanKindInternal {
|
||||
return ctx, func(err error) {}
|
||||
}
|
||||
}
|
||||
|
||||
if options == nil {
|
||||
options = &StartSpanOptions{}
|
||||
}
|
||||
if options.Kind == 0 {
|
||||
options.Kind = tracing.SpanKindInternal
|
||||
}
|
||||
|
||||
ctx, span := tracer.Start(ctx, name, &tracing.SpanOptions{
|
||||
Kind: options.Kind,
|
||||
Attributes: options.Attributes,
|
||||
})
|
||||
ctx = context.WithValue(ctx, ctxActiveSpan{}, options.Kind)
|
||||
return ctx, func(err error) {
|
||||
if err != nil {
|
||||
errType := strings.Replace(fmt.Sprintf("%T", err), "*exported.", "*azcore.", 1)
|
||||
span.SetStatus(tracing.SpanStatusError, fmt.Sprintf("%s:\n%s", errType, err.Error()))
|
||||
}
|
||||
span.End()
|
||||
}
|
||||
}
|
||||
|
||||
// ctxActiveSpan is used as a context key for indicating a SDK client span is in progress.
|
||||
type ctxActiveSpan struct{}
|
||||
@@ -1,35 +0,0 @@
|
||||
//go:build go1.16
|
||||
// +build go1.16
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
)
|
||||
|
||||
// includeResponsePolicy creates a policy that retrieves the raw HTTP response upon request
|
||||
func includeResponsePolicy(req *policy.Request) (*http.Response, error) {
|
||||
resp, err := req.Next()
|
||||
if resp == nil {
|
||||
return resp, err
|
||||
}
|
||||
if httpOutRaw := req.Raw().Context().Value(shared.CtxWithCaptureResponse{}); httpOutRaw != nil {
|
||||
httpOut := httpOutRaw.(**http.Response)
|
||||
*httpOut = resp
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// WithCaptureResponse applies the HTTP response retrieval annotation to the parent context.
|
||||
// The resp parameter will contain the HTTP response after the request has completed.
|
||||
// Deprecated: use [policy.WithCaptureResponse] instead.
|
||||
func WithCaptureResponse(parent context.Context, resp **http.Response) context.Context {
|
||||
return policy.WithCaptureResponse(parent, resp)
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
)
|
||||
|
||||
// KeyCredentialPolicy authorizes requests with a [azcore.KeyCredential].
|
||||
type KeyCredentialPolicy struct {
|
||||
cred *exported.KeyCredential
|
||||
header string
|
||||
prefix string
|
||||
allowHTTP bool
|
||||
}
|
||||
|
||||
// KeyCredentialPolicyOptions contains the optional values configuring [KeyCredentialPolicy].
|
||||
type KeyCredentialPolicyOptions struct {
|
||||
// InsecureAllowCredentialWithHTTP enables authenticated requests over HTTP.
|
||||
// By default, authenticated requests to an HTTP endpoint are rejected by the client.
|
||||
// WARNING: setting this to true will allow sending the authentication key in clear text. Use with caution.
|
||||
InsecureAllowCredentialWithHTTP bool
|
||||
|
||||
// Prefix is used if the key requires a prefix before it's inserted into the HTTP request.
|
||||
Prefix string
|
||||
}
|
||||
|
||||
// NewKeyCredentialPolicy creates a new instance of [KeyCredentialPolicy].
|
||||
// - cred is the [azcore.KeyCredential] used to authenticate with the service
|
||||
// - header is the name of the HTTP request header in which the key is placed
|
||||
// - options contains optional configuration, pass nil to accept the default values
|
||||
func NewKeyCredentialPolicy(cred *exported.KeyCredential, header string, options *KeyCredentialPolicyOptions) *KeyCredentialPolicy {
|
||||
if options == nil {
|
||||
options = &KeyCredentialPolicyOptions{}
|
||||
}
|
||||
return &KeyCredentialPolicy{
|
||||
cred: cred,
|
||||
header: header,
|
||||
prefix: options.Prefix,
|
||||
allowHTTP: options.InsecureAllowCredentialWithHTTP,
|
||||
}
|
||||
}
|
||||
|
||||
// Do implementes the Do method on the [policy.Polilcy] interface.
|
||||
func (k *KeyCredentialPolicy) Do(req *policy.Request) (*http.Response, error) {
|
||||
// skip adding the authorization header if no KeyCredential was provided.
|
||||
// this prevents a panic that might be hard to diagnose and allows testing
|
||||
// against http endpoints that don't require authentication.
|
||||
if k.cred != nil {
|
||||
if err := checkHTTPSForAuth(req, k.allowHTTP); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
val := exported.KeyCredentialGet(k.cred)
|
||||
if k.prefix != "" {
|
||||
val = k.prefix + val
|
||||
}
|
||||
req.Raw().Header.Add(k.header, val)
|
||||
}
|
||||
return req.Next()
|
||||
}
|
||||
@@ -1,264 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/diag"
|
||||
)
|
||||
|
||||
type logPolicy struct {
|
||||
includeBody bool
|
||||
allowedHeaders map[string]struct{}
|
||||
allowedQP map[string]struct{}
|
||||
}
|
||||
|
||||
// NewLogPolicy creates a request/response logging policy object configured using the specified options.
|
||||
// Pass nil to accept the default values; this is the same as passing a zero-value options.
|
||||
func NewLogPolicy(o *policy.LogOptions) policy.Policy {
|
||||
if o == nil {
|
||||
o = &policy.LogOptions{}
|
||||
}
|
||||
// construct default hash set of allowed headers
|
||||
allowedHeaders := map[string]struct{}{
|
||||
"accept": {},
|
||||
"cache-control": {},
|
||||
"connection": {},
|
||||
"content-length": {},
|
||||
"content-type": {},
|
||||
"date": {},
|
||||
"etag": {},
|
||||
"expires": {},
|
||||
"if-match": {},
|
||||
"if-modified-since": {},
|
||||
"if-none-match": {},
|
||||
"if-unmodified-since": {},
|
||||
"last-modified": {},
|
||||
"ms-cv": {},
|
||||
"pragma": {},
|
||||
"request-id": {},
|
||||
"retry-after": {},
|
||||
"server": {},
|
||||
"traceparent": {},
|
||||
"transfer-encoding": {},
|
||||
"user-agent": {},
|
||||
"www-authenticate": {},
|
||||
"x-ms-request-id": {},
|
||||
"x-ms-client-request-id": {},
|
||||
"x-ms-return-client-request-id": {},
|
||||
}
|
||||
// add any caller-specified allowed headers to the set
|
||||
for _, ah := range o.AllowedHeaders {
|
||||
allowedHeaders[strings.ToLower(ah)] = struct{}{}
|
||||
}
|
||||
// now do the same thing for query params
|
||||
allowedQP := getAllowedQueryParams(o.AllowedQueryParams)
|
||||
return &logPolicy{
|
||||
includeBody: o.IncludeBody,
|
||||
allowedHeaders: allowedHeaders,
|
||||
allowedQP: allowedQP,
|
||||
}
|
||||
}
|
||||
|
||||
// getAllowedQueryParams merges the default set of allowed query parameters
|
||||
// with a custom set (usually comes from client options).
|
||||
func getAllowedQueryParams(customAllowedQP []string) map[string]struct{} {
|
||||
allowedQP := map[string]struct{}{
|
||||
"api-version": {},
|
||||
}
|
||||
for _, qp := range customAllowedQP {
|
||||
allowedQP[strings.ToLower(qp)] = struct{}{}
|
||||
}
|
||||
return allowedQP
|
||||
}
|
||||
|
||||
// logPolicyOpValues is the struct containing the per-operation values
|
||||
type logPolicyOpValues struct {
|
||||
try int32
|
||||
start time.Time
|
||||
}
|
||||
|
||||
func (p *logPolicy) Do(req *policy.Request) (*http.Response, error) {
|
||||
// Get the per-operation values. These are saved in the Message's map so that they persist across each retry calling into this policy object.
|
||||
var opValues logPolicyOpValues
|
||||
if req.OperationValue(&opValues); opValues.start.IsZero() {
|
||||
opValues.start = time.Now() // If this is the 1st try, record this operation's start time
|
||||
}
|
||||
opValues.try++ // The first try is #1 (not #0)
|
||||
req.SetOperationValue(opValues)
|
||||
|
||||
// Log the outgoing request as informational
|
||||
if log.Should(log.EventRequest) {
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "==> OUTGOING REQUEST (Try=%d)\n", opValues.try)
|
||||
p.writeRequestWithResponse(b, req, nil, nil)
|
||||
var err error
|
||||
if p.includeBody {
|
||||
err = writeReqBody(req, b)
|
||||
}
|
||||
log.Write(log.EventRequest, b.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Set the time for this particular retry operation and then Do the operation.
|
||||
tryStart := time.Now()
|
||||
response, err := req.Next() // Make the request
|
||||
tryEnd := time.Now()
|
||||
tryDuration := tryEnd.Sub(tryStart)
|
||||
opDuration := tryEnd.Sub(opValues.start)
|
||||
|
||||
if log.Should(log.EventResponse) {
|
||||
// We're going to log this; build the string to log
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "==> REQUEST/RESPONSE (Try=%d/%v, OpTime=%v) -- ", opValues.try, tryDuration, opDuration)
|
||||
if err != nil { // This HTTP request did not get a response from the service
|
||||
fmt.Fprint(b, "REQUEST ERROR\n")
|
||||
} else {
|
||||
fmt.Fprint(b, "RESPONSE RECEIVED\n")
|
||||
}
|
||||
|
||||
p.writeRequestWithResponse(b, req, response, err)
|
||||
if err != nil {
|
||||
// skip frames runtime.Callers() and runtime.StackTrace()
|
||||
b.WriteString(diag.StackTrace(2, 32))
|
||||
} else if p.includeBody {
|
||||
err = writeRespBody(response, b)
|
||||
}
|
||||
log.Write(log.EventResponse, b.String())
|
||||
}
|
||||
return response, err
|
||||
}
|
||||
|
||||
const redactedValue = "REDACTED"
|
||||
|
||||
// getSanitizedURL returns a sanitized string for the provided url.URL
|
||||
func getSanitizedURL(u url.URL, allowedQueryParams map[string]struct{}) string {
|
||||
// redact applicable query params
|
||||
qp := u.Query()
|
||||
for k := range qp {
|
||||
if _, ok := allowedQueryParams[strings.ToLower(k)]; !ok {
|
||||
qp.Set(k, redactedValue)
|
||||
}
|
||||
}
|
||||
u.RawQuery = qp.Encode()
|
||||
return u.String()
|
||||
}
|
||||
|
||||
// writeRequestWithResponse appends a formatted HTTP request into a Buffer. If request and/or err are
|
||||
// not nil, then these are also written into the Buffer.
|
||||
func (p *logPolicy) writeRequestWithResponse(b *bytes.Buffer, req *policy.Request, resp *http.Response, err error) {
|
||||
// Write the request into the buffer.
|
||||
fmt.Fprint(b, " "+req.Raw().Method+" "+getSanitizedURL(*req.Raw().URL, p.allowedQP)+"\n")
|
||||
p.writeHeader(b, req.Raw().Header)
|
||||
if resp != nil {
|
||||
fmt.Fprintln(b, " --------------------------------------------------------------------------------")
|
||||
fmt.Fprint(b, " RESPONSE Status: "+resp.Status+"\n")
|
||||
p.writeHeader(b, resp.Header)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintln(b, " --------------------------------------------------------------------------------")
|
||||
fmt.Fprint(b, " ERROR:\n"+err.Error()+"\n")
|
||||
}
|
||||
}
|
||||
|
||||
// formatHeaders appends an HTTP request's or response's header into a Buffer.
|
||||
func (p *logPolicy) writeHeader(b *bytes.Buffer, header http.Header) {
|
||||
if len(header) == 0 {
|
||||
b.WriteString(" (no headers)\n")
|
||||
return
|
||||
}
|
||||
keys := make([]string, 0, len(header))
|
||||
// Alphabetize the headers
|
||||
for k := range header {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
// don't use Get() as it will canonicalize k which might cause a mismatch
|
||||
value := header[k][0]
|
||||
// redact all header values not in the allow-list
|
||||
if _, ok := p.allowedHeaders[strings.ToLower(k)]; !ok {
|
||||
value = redactedValue
|
||||
}
|
||||
fmt.Fprintf(b, " %s: %+v\n", k, value)
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if the request/response body should be logged.
|
||||
// this is determined by looking at the content-type header value.
|
||||
func shouldLogBody(b *bytes.Buffer, contentType string) bool {
|
||||
contentType = strings.ToLower(contentType)
|
||||
if strings.HasPrefix(contentType, "text") ||
|
||||
strings.Contains(contentType, "json") ||
|
||||
strings.Contains(contentType, "xml") {
|
||||
return true
|
||||
}
|
||||
fmt.Fprintf(b, " Skip logging body for %s\n", contentType)
|
||||
return false
|
||||
}
|
||||
|
||||
// writes to a buffer, used for logging purposes
|
||||
func writeReqBody(req *policy.Request, b *bytes.Buffer) error {
|
||||
if req.Raw().Body == nil {
|
||||
fmt.Fprint(b, " Request contained no body\n")
|
||||
return nil
|
||||
}
|
||||
if ct := req.Raw().Header.Get(shared.HeaderContentType); !shouldLogBody(b, ct) {
|
||||
return nil
|
||||
}
|
||||
body, err := io.ReadAll(req.Raw().Body)
|
||||
if err != nil {
|
||||
fmt.Fprintf(b, " Failed to read request body: %s\n", err.Error())
|
||||
return err
|
||||
}
|
||||
if err := req.RewindBody(); err != nil {
|
||||
return err
|
||||
}
|
||||
logBody(b, body)
|
||||
return nil
|
||||
}
|
||||
|
||||
// writes to a buffer, used for logging purposes
|
||||
func writeRespBody(resp *http.Response, b *bytes.Buffer) error {
|
||||
ct := resp.Header.Get(shared.HeaderContentType)
|
||||
if ct == "" {
|
||||
fmt.Fprint(b, " Response contained no body\n")
|
||||
return nil
|
||||
} else if !shouldLogBody(b, ct) {
|
||||
return nil
|
||||
}
|
||||
body, err := Payload(resp)
|
||||
if err != nil {
|
||||
fmt.Fprintf(b, " Failed to read response body: %s\n", err.Error())
|
||||
return err
|
||||
}
|
||||
if len(body) > 0 {
|
||||
logBody(b, body)
|
||||
} else {
|
||||
fmt.Fprint(b, " Response contained no body\n")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func logBody(b *bytes.Buffer, body []byte) {
|
||||
fmt.Fprintln(b, " --------------------------------------------------------------------------------")
|
||||
fmt.Fprintln(b, string(body))
|
||||
fmt.Fprintln(b, " --------------------------------------------------------------------------------")
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/uuid"
|
||||
)
|
||||
|
||||
type requestIDPolicy struct{}
|
||||
|
||||
// NewRequestIDPolicy returns a policy that add the x-ms-client-request-id header
|
||||
func NewRequestIDPolicy() policy.Policy {
|
||||
return &requestIDPolicy{}
|
||||
}
|
||||
|
||||
func (r *requestIDPolicy) Do(req *policy.Request) (*http.Response, error) {
|
||||
if req.Raw().Header.Get(shared.HeaderXMSClientRequestID) == "" {
|
||||
id, err := uuid.New()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Raw().Header.Set(shared.HeaderXMSClientRequestID, id.String())
|
||||
}
|
||||
|
||||
return req.Next()
|
||||
}
|
||||
@@ -1,276 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/errorinfo"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/exported"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultMaxRetries = 3
|
||||
)
|
||||
|
||||
func setDefaults(o *policy.RetryOptions) {
|
||||
if o.MaxRetries == 0 {
|
||||
o.MaxRetries = defaultMaxRetries
|
||||
} else if o.MaxRetries < 0 {
|
||||
o.MaxRetries = 0
|
||||
}
|
||||
|
||||
// SDK guidelines specify the default MaxRetryDelay is 60 seconds
|
||||
if o.MaxRetryDelay == 0 {
|
||||
o.MaxRetryDelay = 60 * time.Second
|
||||
} else if o.MaxRetryDelay < 0 {
|
||||
// not really an unlimited cap, but sufficiently large enough to be considered as such
|
||||
o.MaxRetryDelay = math.MaxInt64
|
||||
}
|
||||
if o.RetryDelay == 0 {
|
||||
o.RetryDelay = 800 * time.Millisecond
|
||||
} else if o.RetryDelay < 0 {
|
||||
o.RetryDelay = 0
|
||||
}
|
||||
if o.StatusCodes == nil {
|
||||
// NOTE: if you change this list, you MUST update the docs in policy/policy.go
|
||||
o.StatusCodes = []int{
|
||||
http.StatusRequestTimeout, // 408
|
||||
http.StatusTooManyRequests, // 429
|
||||
http.StatusInternalServerError, // 500
|
||||
http.StatusBadGateway, // 502
|
||||
http.StatusServiceUnavailable, // 503
|
||||
http.StatusGatewayTimeout, // 504
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func calcDelay(o policy.RetryOptions, try int32) time.Duration { // try is >=1; never 0
|
||||
// avoid overflow when shifting left
|
||||
factor := time.Duration(math.MaxInt64)
|
||||
if try < 63 {
|
||||
factor = time.Duration(int64(1<<try) - 1)
|
||||
}
|
||||
|
||||
delay := factor * o.RetryDelay
|
||||
if delay < factor {
|
||||
// overflow has happened so set to max value
|
||||
delay = time.Duration(math.MaxInt64)
|
||||
}
|
||||
|
||||
// Introduce jitter: [0.0, 1.0) / 2 = [0.0, 0.5) + 0.8 = [0.8, 1.3)
|
||||
jitterMultiplier := rand.Float64()/2 + 0.8 // NOTE: We want math/rand; not crypto/rand
|
||||
|
||||
delayFloat := float64(delay) * jitterMultiplier
|
||||
if delayFloat > float64(math.MaxInt64) {
|
||||
// the jitter pushed us over MaxInt64, so just use MaxInt64
|
||||
delay = time.Duration(math.MaxInt64)
|
||||
} else {
|
||||
delay = time.Duration(delayFloat)
|
||||
}
|
||||
|
||||
if delay > o.MaxRetryDelay { // MaxRetryDelay is backfilled with non-negative value
|
||||
delay = o.MaxRetryDelay
|
||||
}
|
||||
|
||||
return delay
|
||||
}
|
||||
|
||||
// NewRetryPolicy creates a policy object configured using the specified options.
|
||||
// Pass nil to accept the default values; this is the same as passing a zero-value options.
|
||||
func NewRetryPolicy(o *policy.RetryOptions) policy.Policy {
|
||||
if o == nil {
|
||||
o = &policy.RetryOptions{}
|
||||
}
|
||||
p := &retryPolicy{options: *o}
|
||||
return p
|
||||
}
|
||||
|
||||
type retryPolicy struct {
|
||||
options policy.RetryOptions
|
||||
}
|
||||
|
||||
func (p *retryPolicy) Do(req *policy.Request) (resp *http.Response, err error) {
|
||||
options := p.options
|
||||
// check if the retry options have been overridden for this call
|
||||
if override := req.Raw().Context().Value(shared.CtxWithRetryOptionsKey{}); override != nil {
|
||||
options = override.(policy.RetryOptions)
|
||||
}
|
||||
setDefaults(&options)
|
||||
// Exponential retry algorithm: ((2 ^ attempt) - 1) * delay * random(0.8, 1.2)
|
||||
// When to retry: connection failure or temporary/timeout.
|
||||
var rwbody *retryableRequestBody
|
||||
if req.Body() != nil {
|
||||
// wrap the body so we control when it's actually closed.
|
||||
// do this outside the for loop so defers don't accumulate.
|
||||
rwbody = &retryableRequestBody{body: req.Body()}
|
||||
defer rwbody.realClose()
|
||||
}
|
||||
try := int32(1)
|
||||
for {
|
||||
resp = nil // reset
|
||||
// unfortunately we don't have access to the custom allow-list of query params, so we'll redact everything but the default allowed QPs
|
||||
log.Writef(log.EventRetryPolicy, "=====> Try=%d for %s %s", try, req.Raw().Method, getSanitizedURL(*req.Raw().URL, getAllowedQueryParams(nil)))
|
||||
|
||||
// For each try, seek to the beginning of the Body stream. We do this even for the 1st try because
|
||||
// the stream may not be at offset 0 when we first get it and we want the same behavior for the
|
||||
// 1st try as for additional tries.
|
||||
err = req.RewindBody()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// RewindBody() restores Raw().Body to its original state, so set our rewindable after
|
||||
if rwbody != nil {
|
||||
req.Raw().Body = rwbody
|
||||
}
|
||||
|
||||
if options.TryTimeout == 0 {
|
||||
clone := req.Clone(req.Raw().Context())
|
||||
resp, err = clone.Next()
|
||||
} else {
|
||||
// Set the per-try time for this particular retry operation and then Do the operation.
|
||||
tryCtx, tryCancel := context.WithTimeout(req.Raw().Context(), options.TryTimeout)
|
||||
clone := req.Clone(tryCtx)
|
||||
resp, err = clone.Next() // Make the request
|
||||
// if the body was already downloaded or there was an error it's safe to cancel the context now
|
||||
if err != nil {
|
||||
tryCancel()
|
||||
} else if exported.PayloadDownloaded(resp) {
|
||||
tryCancel()
|
||||
} else {
|
||||
// must cancel the context after the body has been read and closed
|
||||
resp.Body = &contextCancelReadCloser{cf: tryCancel, body: resp.Body}
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
log.Writef(log.EventRetryPolicy, "response %d", resp.StatusCode)
|
||||
} else {
|
||||
log.Writef(log.EventRetryPolicy, "error %v", err)
|
||||
}
|
||||
|
||||
if ctxErr := req.Raw().Context().Err(); ctxErr != nil {
|
||||
// don't retry if the parent context has been cancelled or its deadline exceeded
|
||||
err = ctxErr
|
||||
log.Writef(log.EventRetryPolicy, "abort due to %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// check if the error is not retriable
|
||||
var nre errorinfo.NonRetriable
|
||||
if errors.As(err, &nre) {
|
||||
// the error says it's not retriable so don't retry
|
||||
log.Writef(log.EventRetryPolicy, "non-retriable error %T", nre)
|
||||
return
|
||||
}
|
||||
|
||||
if options.ShouldRetry != nil {
|
||||
// a non-nil ShouldRetry overrides our HTTP status code check
|
||||
if !options.ShouldRetry(resp, err) {
|
||||
// predicate says we shouldn't retry
|
||||
log.Write(log.EventRetryPolicy, "exit due to ShouldRetry")
|
||||
return
|
||||
}
|
||||
} else if err == nil && !HasStatusCode(resp, options.StatusCodes...) {
|
||||
// if there is no error and the response code isn't in the list of retry codes then we're done.
|
||||
log.Write(log.EventRetryPolicy, "exit due to non-retriable status code")
|
||||
return
|
||||
}
|
||||
|
||||
if try == options.MaxRetries+1 {
|
||||
// max number of tries has been reached, don't sleep again
|
||||
log.Writef(log.EventRetryPolicy, "MaxRetries %d exceeded", options.MaxRetries)
|
||||
return
|
||||
}
|
||||
|
||||
// use the delay from retry-after if available
|
||||
delay := shared.RetryAfter(resp)
|
||||
if delay <= 0 {
|
||||
delay = calcDelay(options, try)
|
||||
} else if delay > options.MaxRetryDelay {
|
||||
// the retry-after delay exceeds the the cap so don't retry
|
||||
log.Writef(log.EventRetryPolicy, "Retry-After delay %s exceeds MaxRetryDelay of %s", delay, options.MaxRetryDelay)
|
||||
return
|
||||
}
|
||||
|
||||
// drain before retrying so nothing is leaked
|
||||
Drain(resp)
|
||||
|
||||
log.Writef(log.EventRetryPolicy, "End Try #%d, Delay=%v", try, delay)
|
||||
select {
|
||||
case <-time.After(delay):
|
||||
try++
|
||||
case <-req.Raw().Context().Done():
|
||||
err = req.Raw().Context().Err()
|
||||
log.Writef(log.EventRetryPolicy, "abort due to %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithRetryOptions adds the specified RetryOptions to the parent context.
|
||||
// Use this to specify custom RetryOptions at the API-call level.
|
||||
// Deprecated: use [policy.WithRetryOptions] instead.
|
||||
func WithRetryOptions(parent context.Context, options policy.RetryOptions) context.Context {
|
||||
return policy.WithRetryOptions(parent, options)
|
||||
}
|
||||
|
||||
// ********** The following type/methods implement the retryableRequestBody (a ReadSeekCloser)
|
||||
|
||||
// This struct is used when sending a body to the network
|
||||
type retryableRequestBody struct {
|
||||
body io.ReadSeeker // Seeking is required to support retries
|
||||
}
|
||||
|
||||
// Read reads a block of data from an inner stream and reports progress
|
||||
func (b *retryableRequestBody) Read(p []byte) (n int, err error) {
|
||||
return b.body.Read(p)
|
||||
}
|
||||
|
||||
func (b *retryableRequestBody) Seek(offset int64, whence int) (offsetFromStart int64, err error) {
|
||||
return b.body.Seek(offset, whence)
|
||||
}
|
||||
|
||||
func (b *retryableRequestBody) Close() error {
|
||||
// We don't want the underlying transport to close the request body on transient failures so this is a nop.
|
||||
// The retry policy closes the request body upon success.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *retryableRequestBody) realClose() error {
|
||||
if c, ok := b.body.(io.Closer); ok {
|
||||
return c.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ********** The following type/methods implement the contextCancelReadCloser
|
||||
|
||||
// contextCancelReadCloser combines an io.ReadCloser with a cancel func.
|
||||
// it ensures the cancel func is invoked once the body has been read and closed.
|
||||
type contextCancelReadCloser struct {
|
||||
cf context.CancelFunc
|
||||
body io.ReadCloser
|
||||
}
|
||||
|
||||
func (rc *contextCancelReadCloser) Read(p []byte) (n int, err error) {
|
||||
return rc.body.Read(p)
|
||||
}
|
||||
|
||||
func (rc *contextCancelReadCloser) Close() error {
|
||||
err := rc.body.Close()
|
||||
rc.cf()
|
||||
return err
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
)
|
||||
|
||||
// SASCredentialPolicy authorizes requests with a [azcore.SASCredential].
|
||||
type SASCredentialPolicy struct {
|
||||
cred *exported.SASCredential
|
||||
header string
|
||||
allowHTTP bool
|
||||
}
|
||||
|
||||
// SASCredentialPolicyOptions contains the optional values configuring [SASCredentialPolicy].
|
||||
type SASCredentialPolicyOptions struct {
|
||||
// InsecureAllowCredentialWithHTTP enables authenticated requests over HTTP.
|
||||
// By default, authenticated requests to an HTTP endpoint are rejected by the client.
|
||||
// WARNING: setting this to true will allow sending the authentication key in clear text. Use with caution.
|
||||
InsecureAllowCredentialWithHTTP bool
|
||||
}
|
||||
|
||||
// NewSASCredentialPolicy creates a new instance of [SASCredentialPolicy].
|
||||
// - cred is the [azcore.SASCredential] used to authenticate with the service
|
||||
// - header is the name of the HTTP request header in which the shared access signature is placed
|
||||
// - options contains optional configuration, pass nil to accept the default values
|
||||
func NewSASCredentialPolicy(cred *exported.SASCredential, header string, options *SASCredentialPolicyOptions) *SASCredentialPolicy {
|
||||
if options == nil {
|
||||
options = &SASCredentialPolicyOptions{}
|
||||
}
|
||||
return &SASCredentialPolicy{
|
||||
cred: cred,
|
||||
header: header,
|
||||
allowHTTP: options.InsecureAllowCredentialWithHTTP,
|
||||
}
|
||||
}
|
||||
|
||||
// Do implementes the Do method on the [policy.Polilcy] interface.
|
||||
func (k *SASCredentialPolicy) Do(req *policy.Request) (*http.Response, error) {
|
||||
// skip adding the authorization header if no SASCredential was provided.
|
||||
// this prevents a panic that might be hard to diagnose and allows testing
|
||||
// against http endpoints that don't require authentication.
|
||||
if k.cred != nil {
|
||||
if err := checkHTTPSForAuth(req, k.allowHTTP); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Raw().Header.Add(k.header, exported.SASCredentialGet(k.cred))
|
||||
}
|
||||
return req.Next()
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
)
|
||||
|
||||
type telemetryPolicy struct {
|
||||
telemetryValue string
|
||||
}
|
||||
|
||||
// NewTelemetryPolicy creates a telemetry policy object that adds telemetry information to outgoing HTTP requests.
|
||||
// The format is [<application_id> ]azsdk-go-<mod>/<ver> <platform_info>.
|
||||
// Pass nil to accept the default values; this is the same as passing a zero-value options.
|
||||
func NewTelemetryPolicy(mod, ver string, o *policy.TelemetryOptions) policy.Policy {
|
||||
if o == nil {
|
||||
o = &policy.TelemetryOptions{}
|
||||
}
|
||||
tp := telemetryPolicy{}
|
||||
if o.Disabled {
|
||||
return &tp
|
||||
}
|
||||
b := &bytes.Buffer{}
|
||||
// normalize ApplicationID
|
||||
if o.ApplicationID != "" {
|
||||
o.ApplicationID = strings.ReplaceAll(o.ApplicationID, " ", "/")
|
||||
if len(o.ApplicationID) > 24 {
|
||||
o.ApplicationID = o.ApplicationID[:24]
|
||||
}
|
||||
b.WriteString(o.ApplicationID)
|
||||
b.WriteRune(' ')
|
||||
}
|
||||
// mod might be the fully qualified name. in that case, we just want the package name
|
||||
if i := strings.LastIndex(mod, "/"); i > -1 {
|
||||
mod = mod[i+1:]
|
||||
}
|
||||
b.WriteString(formatTelemetry(mod, ver))
|
||||
b.WriteRune(' ')
|
||||
b.WriteString(platformInfo)
|
||||
tp.telemetryValue = b.String()
|
||||
return &tp
|
||||
}
|
||||
|
||||
func formatTelemetry(comp, ver string) string {
|
||||
return fmt.Sprintf("azsdk-go-%s/%s", comp, ver)
|
||||
}
|
||||
|
||||
func (p telemetryPolicy) Do(req *policy.Request) (*http.Response, error) {
|
||||
if p.telemetryValue == "" {
|
||||
return req.Next()
|
||||
}
|
||||
// preserve the existing User-Agent string
|
||||
if ua := req.Raw().Header.Get(shared.HeaderUserAgent); ua != "" {
|
||||
p.telemetryValue = fmt.Sprintf("%s %s", p.telemetryValue, ua)
|
||||
}
|
||||
req.Raw().Header.Set(shared.HeaderUserAgent, p.telemetryValue)
|
||||
return req.Next()
|
||||
}
|
||||
|
||||
// NOTE: the ONLY function that should write to this variable is this func
|
||||
var platformInfo = func() string {
|
||||
operatingSystem := runtime.GOOS // Default OS string
|
||||
switch operatingSystem {
|
||||
case "windows":
|
||||
operatingSystem = os.Getenv("OS") // Get more specific OS information
|
||||
case "linux": // accept default OS info
|
||||
case "freebsd": // accept default OS info
|
||||
}
|
||||
return fmt.Sprintf("(%s; %s)", runtime.Version(), operatingSystem)
|
||||
}()
|
||||
@@ -1,396 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/log"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/async"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/body"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/fake"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/loc"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/pollers/op"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/tracing"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/poller"
|
||||
)
|
||||
|
||||
// FinalStateVia is the enumerated type for the possible final-state-via values.
|
||||
type FinalStateVia = pollers.FinalStateVia
|
||||
|
||||
const (
|
||||
// FinalStateViaAzureAsyncOp indicates the final payload comes from the Azure-AsyncOperation URL.
|
||||
FinalStateViaAzureAsyncOp = pollers.FinalStateViaAzureAsyncOp
|
||||
|
||||
// FinalStateViaLocation indicates the final payload comes from the Location URL.
|
||||
FinalStateViaLocation = pollers.FinalStateViaLocation
|
||||
|
||||
// FinalStateViaOriginalURI indicates the final payload comes from the original URL.
|
||||
FinalStateViaOriginalURI = pollers.FinalStateViaOriginalURI
|
||||
|
||||
// FinalStateViaOpLocation indicates the final payload comes from the Operation-Location URL.
|
||||
FinalStateViaOpLocation = pollers.FinalStateViaOpLocation
|
||||
)
|
||||
|
||||
// NewPollerOptions contains the optional parameters for NewPoller.
|
||||
type NewPollerOptions[T any] struct {
|
||||
// FinalStateVia contains the final-state-via value for the LRO.
|
||||
// NOTE: used only for Azure-AsyncOperation and Operation-Location LROs.
|
||||
FinalStateVia FinalStateVia
|
||||
|
||||
// OperationLocationResultPath contains the JSON path to the result's
|
||||
// payload when it's included with the terminal success response.
|
||||
// NOTE: only used for Operation-Location LROs.
|
||||
OperationLocationResultPath string
|
||||
|
||||
// Response contains a preconstructed response type.
|
||||
// The final payload will be unmarshaled into it and returned.
|
||||
Response *T
|
||||
|
||||
// Handler[T] contains a custom polling implementation.
|
||||
Handler PollingHandler[T]
|
||||
|
||||
// Tracer contains the Tracer from the client that's creating the Poller.
|
||||
Tracer tracing.Tracer
|
||||
}
|
||||
|
||||
// NewPoller creates a Poller based on the provided initial response.
|
||||
func NewPoller[T any](resp *http.Response, pl exported.Pipeline, options *NewPollerOptions[T]) (*Poller[T], error) {
|
||||
if options == nil {
|
||||
options = &NewPollerOptions[T]{}
|
||||
}
|
||||
result := options.Response
|
||||
if result == nil {
|
||||
result = new(T)
|
||||
}
|
||||
if options.Handler != nil {
|
||||
return &Poller[T]{
|
||||
op: options.Handler,
|
||||
resp: resp,
|
||||
result: result,
|
||||
tracer: options.Tracer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
// this is a back-stop in case the swagger is incorrect (i.e. missing one or more status codes for success).
|
||||
// ideally the codegen should return an error if the initial response failed and not even create a poller.
|
||||
if !poller.StatusCodeValid(resp) {
|
||||
return nil, errors.New("the operation failed or was cancelled")
|
||||
}
|
||||
|
||||
// determine the polling method
|
||||
var opr PollingHandler[T]
|
||||
var err error
|
||||
if fake.Applicable(resp) {
|
||||
opr, err = fake.New[T](pl, resp)
|
||||
} else if async.Applicable(resp) {
|
||||
// async poller must be checked first as it can also have a location header
|
||||
opr, err = async.New[T](pl, resp, options.FinalStateVia)
|
||||
} else if op.Applicable(resp) {
|
||||
// op poller must be checked before loc as it can also have a location header
|
||||
opr, err = op.New[T](pl, resp, options.FinalStateVia, options.OperationLocationResultPath)
|
||||
} else if loc.Applicable(resp) {
|
||||
opr, err = loc.New[T](pl, resp)
|
||||
} else if body.Applicable(resp) {
|
||||
// must test body poller last as it's a subset of the other pollers.
|
||||
// TODO: this is ambiguous for PATCH/PUT if it returns a 200 with no polling headers (sync completion)
|
||||
opr, err = body.New[T](pl, resp)
|
||||
} else if m := resp.Request.Method; resp.StatusCode == http.StatusAccepted && (m == http.MethodDelete || m == http.MethodPost) {
|
||||
// if we get here it means we have a 202 with no polling headers.
|
||||
// for DELETE and POST this is a hard error per ARM RPC spec.
|
||||
return nil, errors.New("response is missing polling URL")
|
||||
} else {
|
||||
opr, err = pollers.NewNopPoller[T](resp)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Poller[T]{
|
||||
op: opr,
|
||||
resp: resp,
|
||||
result: result,
|
||||
tracer: options.Tracer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewPollerFromResumeTokenOptions contains the optional parameters for NewPollerFromResumeToken.
|
||||
type NewPollerFromResumeTokenOptions[T any] struct {
|
||||
// Response contains a preconstructed response type.
|
||||
// The final payload will be unmarshaled into it and returned.
|
||||
Response *T
|
||||
|
||||
// Handler[T] contains a custom polling implementation.
|
||||
Handler PollingHandler[T]
|
||||
|
||||
// Tracer contains the Tracer from the client that's creating the Poller.
|
||||
Tracer tracing.Tracer
|
||||
}
|
||||
|
||||
// NewPollerFromResumeToken creates a Poller from a resume token string.
|
||||
func NewPollerFromResumeToken[T any](token string, pl exported.Pipeline, options *NewPollerFromResumeTokenOptions[T]) (*Poller[T], error) {
|
||||
if options == nil {
|
||||
options = &NewPollerFromResumeTokenOptions[T]{}
|
||||
}
|
||||
result := options.Response
|
||||
if result == nil {
|
||||
result = new(T)
|
||||
}
|
||||
|
||||
if err := pollers.IsTokenValid[T](token); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
raw, err := pollers.ExtractToken(token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var asJSON map[string]any
|
||||
if err := json.Unmarshal(raw, &asJSON); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
opr := options.Handler
|
||||
// now rehydrate the poller based on the encoded poller type
|
||||
if fake.CanResume(asJSON) {
|
||||
opr, _ = fake.New[T](pl, nil)
|
||||
} else if opr != nil {
|
||||
log.Writef(log.EventLRO, "Resuming custom poller %T.", opr)
|
||||
} else if async.CanResume(asJSON) {
|
||||
opr, _ = async.New[T](pl, nil, "")
|
||||
} else if body.CanResume(asJSON) {
|
||||
opr, _ = body.New[T](pl, nil)
|
||||
} else if loc.CanResume(asJSON) {
|
||||
opr, _ = loc.New[T](pl, nil)
|
||||
} else if op.CanResume(asJSON) {
|
||||
opr, _ = op.New[T](pl, nil, "", "")
|
||||
} else {
|
||||
return nil, fmt.Errorf("unhandled poller token %s", string(raw))
|
||||
}
|
||||
if err := json.Unmarshal(raw, &opr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Poller[T]{
|
||||
op: opr,
|
||||
result: result,
|
||||
tracer: options.Tracer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PollingHandler[T] abstracts the differences among poller implementations.
|
||||
type PollingHandler[T any] interface {
|
||||
// Done returns true if the LRO has reached a terminal state.
|
||||
Done() bool
|
||||
|
||||
// Poll fetches the latest state of the LRO.
|
||||
Poll(context.Context) (*http.Response, error)
|
||||
|
||||
// Result is called once the LRO has reached a terminal state. It populates the out parameter
|
||||
// with the result of the operation.
|
||||
Result(ctx context.Context, out *T) error
|
||||
}
|
||||
|
||||
// Poller encapsulates a long-running operation, providing polling facilities until the operation reaches a terminal state.
|
||||
// Methods on this type are not safe for concurrent use.
|
||||
type Poller[T any] struct {
|
||||
op PollingHandler[T]
|
||||
resp *http.Response
|
||||
err error
|
||||
result *T
|
||||
tracer tracing.Tracer
|
||||
done bool
|
||||
}
|
||||
|
||||
// PollUntilDoneOptions contains the optional values for the Poller[T].PollUntilDone() method.
|
||||
type PollUntilDoneOptions struct {
|
||||
// Frequency is the time to wait between polling intervals in absence of a Retry-After header. Allowed minimum is one second.
|
||||
// Pass zero to accept the default value (30s).
|
||||
Frequency time.Duration
|
||||
}
|
||||
|
||||
// PollUntilDone will poll the service endpoint until a terminal state is reached, an error is received, or the context expires.
|
||||
// It internally uses Poll(), Done(), and Result() in its polling loop, sleeping for the specified duration between intervals.
|
||||
// options: pass nil to accept the default values.
|
||||
// NOTE: the default polling frequency is 30 seconds which works well for most operations. However, some operations might
|
||||
// benefit from a shorter or longer duration.
|
||||
func (p *Poller[T]) PollUntilDone(ctx context.Context, options *PollUntilDoneOptions) (res T, err error) {
|
||||
if options == nil {
|
||||
options = &PollUntilDoneOptions{}
|
||||
}
|
||||
cp := *options
|
||||
if cp.Frequency == 0 {
|
||||
cp.Frequency = 30 * time.Second
|
||||
}
|
||||
|
||||
ctx, endSpan := StartSpan(ctx, fmt.Sprintf("%s.PollUntilDone", shortenTypeName(reflect.TypeOf(*p).Name())), p.tracer, nil)
|
||||
defer func() { endSpan(err) }()
|
||||
|
||||
// skip the floor check when executing tests so they don't take so long
|
||||
if isTest := flag.Lookup("test.v"); isTest == nil && cp.Frequency < time.Second {
|
||||
err = errors.New("polling frequency minimum is one second")
|
||||
return
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
logPollUntilDoneExit := func(v any) {
|
||||
log.Writef(log.EventLRO, "END PollUntilDone() for %T: %v, total time: %s", p.op, v, time.Since(start))
|
||||
}
|
||||
log.Writef(log.EventLRO, "BEGIN PollUntilDone() for %T", p.op)
|
||||
if p.resp != nil {
|
||||
// initial check for a retry-after header existing on the initial response
|
||||
if retryAfter := shared.RetryAfter(p.resp); retryAfter > 0 {
|
||||
log.Writef(log.EventLRO, "initial Retry-After delay for %s", retryAfter.String())
|
||||
if err = shared.Delay(ctx, retryAfter); err != nil {
|
||||
logPollUntilDoneExit(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
// begin polling the endpoint until a terminal state is reached
|
||||
for {
|
||||
var resp *http.Response
|
||||
resp, err = p.Poll(ctx)
|
||||
if err != nil {
|
||||
logPollUntilDoneExit(err)
|
||||
return
|
||||
}
|
||||
if p.Done() {
|
||||
logPollUntilDoneExit("succeeded")
|
||||
res, err = p.Result(ctx)
|
||||
return
|
||||
}
|
||||
d := cp.Frequency
|
||||
if retryAfter := shared.RetryAfter(resp); retryAfter > 0 {
|
||||
log.Writef(log.EventLRO, "Retry-After delay for %s", retryAfter.String())
|
||||
d = retryAfter
|
||||
} else {
|
||||
log.Writef(log.EventLRO, "delay for %s", d.String())
|
||||
}
|
||||
if err = shared.Delay(ctx, d); err != nil {
|
||||
logPollUntilDoneExit(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Poll fetches the latest state of the LRO. It returns an HTTP response or error.
|
||||
// If Poll succeeds, the poller's state is updated and the HTTP response is returned.
|
||||
// If Poll fails, the poller's state is unmodified and the error is returned.
|
||||
// Calling Poll on an LRO that has reached a terminal state will return the last HTTP response.
|
||||
func (p *Poller[T]) Poll(ctx context.Context) (resp *http.Response, err error) {
|
||||
if p.Done() {
|
||||
// the LRO has reached a terminal state, don't poll again
|
||||
resp = p.resp
|
||||
return
|
||||
}
|
||||
|
||||
ctx, endSpan := StartSpan(ctx, fmt.Sprintf("%s.Poll", shortenTypeName(reflect.TypeOf(*p).Name())), p.tracer, nil)
|
||||
defer func() { endSpan(err) }()
|
||||
|
||||
resp, err = p.op.Poll(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
p.resp = resp
|
||||
return
|
||||
}
|
||||
|
||||
// Done returns true if the LRO has reached a terminal state.
|
||||
// Once a terminal state is reached, call Result().
|
||||
func (p *Poller[T]) Done() bool {
|
||||
return p.op.Done()
|
||||
}
|
||||
|
||||
// Result returns the result of the LRO and is meant to be used in conjunction with Poll and Done.
|
||||
// If the LRO completed successfully, a populated instance of T is returned.
|
||||
// If the LRO failed or was canceled, an *azcore.ResponseError error is returned.
|
||||
// Calling this on an LRO in a non-terminal state will return an error.
|
||||
func (p *Poller[T]) Result(ctx context.Context) (res T, err error) {
|
||||
if !p.Done() {
|
||||
err = errors.New("poller is in a non-terminal state")
|
||||
return
|
||||
}
|
||||
if p.done {
|
||||
// the result has already been retrieved, return the cached value
|
||||
if p.err != nil {
|
||||
err = p.err
|
||||
return
|
||||
}
|
||||
res = *p.result
|
||||
return
|
||||
}
|
||||
|
||||
ctx, endSpan := StartSpan(ctx, fmt.Sprintf("%s.Result", shortenTypeName(reflect.TypeOf(*p).Name())), p.tracer, nil)
|
||||
defer func() { endSpan(err) }()
|
||||
|
||||
err = p.op.Result(ctx, p.result)
|
||||
var respErr *exported.ResponseError
|
||||
if errors.As(err, &respErr) {
|
||||
if pollers.IsNonTerminalHTTPStatusCode(respErr.RawResponse) {
|
||||
// the request failed in a non-terminal way.
|
||||
// don't cache the error or mark the Poller as done
|
||||
return
|
||||
}
|
||||
// the LRO failed. record the error
|
||||
p.err = err
|
||||
} else if err != nil {
|
||||
// the call to Result failed, don't cache anything in this case
|
||||
return
|
||||
}
|
||||
p.done = true
|
||||
if p.err != nil {
|
||||
err = p.err
|
||||
return
|
||||
}
|
||||
res = *p.result
|
||||
return
|
||||
}
|
||||
|
||||
// ResumeToken returns a value representing the poller that can be used to resume
|
||||
// the LRO at a later time. ResumeTokens are unique per service operation.
|
||||
// The token's format should be considered opaque and is subject to change.
|
||||
// Calling this on an LRO in a terminal state will return an error.
|
||||
func (p *Poller[T]) ResumeToken() (string, error) {
|
||||
if p.Done() {
|
||||
return "", errors.New("poller is in a terminal state")
|
||||
}
|
||||
tk, err := pollers.NewResumeToken[T](p.op)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return tk, err
|
||||
}
|
||||
|
||||
// extracts the type name from the string returned from reflect.Value.Name()
|
||||
func shortenTypeName(s string) string {
|
||||
// the value is formatted as follows
|
||||
// Poller[module/Package.Type].Method
|
||||
// we want to shorten the generic type parameter string to Type
|
||||
// anything we don't recognize will be left as-is
|
||||
begin := strings.Index(s, "[")
|
||||
end := strings.Index(s, "]")
|
||||
if begin == -1 || end == -1 {
|
||||
return s
|
||||
}
|
||||
|
||||
typeName := s[begin+1 : end]
|
||||
if i := strings.LastIndex(typeName, "."); i > -1 {
|
||||
typeName = typeName[i+1:]
|
||||
}
|
||||
return s[:begin+1] + typeName + s[end:]
|
||||
}
|
||||
@@ -1,281 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/textproto"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/uuid"
|
||||
)
|
||||
|
||||
// Base64Encoding is usesd to specify which base-64 encoder/decoder to use when
|
||||
// encoding/decoding a slice of bytes to/from a string.
|
||||
type Base64Encoding = exported.Base64Encoding
|
||||
|
||||
const (
|
||||
// Base64StdFormat uses base64.StdEncoding for encoding and decoding payloads.
|
||||
Base64StdFormat Base64Encoding = exported.Base64StdFormat
|
||||
|
||||
// Base64URLFormat uses base64.RawURLEncoding for encoding and decoding payloads.
|
||||
Base64URLFormat Base64Encoding = exported.Base64URLFormat
|
||||
)
|
||||
|
||||
// NewRequest creates a new policy.Request with the specified input.
|
||||
// The endpoint MUST be properly encoded before calling this function.
|
||||
func NewRequest(ctx context.Context, httpMethod string, endpoint string) (*policy.Request, error) {
|
||||
return exported.NewRequest(ctx, httpMethod, endpoint)
|
||||
}
|
||||
|
||||
// NewRequestFromRequest creates a new policy.Request with an existing *http.Request
|
||||
func NewRequestFromRequest(req *http.Request) (*policy.Request, error) {
|
||||
return exported.NewRequestFromRequest(req)
|
||||
}
|
||||
|
||||
// EncodeQueryParams will parse and encode any query parameters in the specified URL.
|
||||
// Any semicolons will automatically be escaped.
|
||||
func EncodeQueryParams(u string) (string, error) {
|
||||
before, after, found := strings.Cut(u, "?")
|
||||
if !found {
|
||||
return u, nil
|
||||
}
|
||||
// starting in Go 1.17, url.ParseQuery will reject semicolons in query params.
|
||||
// so, we must escape them first. note that this assumes that semicolons aren't
|
||||
// being used as query param separators which is per the current RFC.
|
||||
// for more info:
|
||||
// https://github.com/golang/go/issues/25192
|
||||
// https://github.com/golang/go/issues/50034
|
||||
qp, err := url.ParseQuery(strings.ReplaceAll(after, ";", "%3B"))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return before + "?" + qp.Encode(), nil
|
||||
}
|
||||
|
||||
// JoinPaths concatenates multiple URL path segments into one path,
|
||||
// inserting path separation characters as required. JoinPaths will preserve
|
||||
// query parameters in the root path
|
||||
func JoinPaths(root string, paths ...string) string {
|
||||
if len(paths) == 0 {
|
||||
return root
|
||||
}
|
||||
|
||||
qps := ""
|
||||
if strings.Contains(root, "?") {
|
||||
splitPath := strings.Split(root, "?")
|
||||
root, qps = splitPath[0], splitPath[1]
|
||||
}
|
||||
|
||||
p := path.Join(paths...)
|
||||
// path.Join will remove any trailing slashes.
|
||||
// if one was provided, preserve it.
|
||||
if strings.HasSuffix(paths[len(paths)-1], "/") && !strings.HasSuffix(p, "/") {
|
||||
p += "/"
|
||||
}
|
||||
|
||||
if qps != "" {
|
||||
p = p + "?" + qps
|
||||
}
|
||||
|
||||
if strings.HasSuffix(root, "/") && strings.HasPrefix(p, "/") {
|
||||
root = root[:len(root)-1]
|
||||
} else if !strings.HasSuffix(root, "/") && !strings.HasPrefix(p, "/") {
|
||||
p = "/" + p
|
||||
}
|
||||
return root + p
|
||||
}
|
||||
|
||||
// EncodeByteArray will base-64 encode the byte slice v.
|
||||
func EncodeByteArray(v []byte, format Base64Encoding) string {
|
||||
return exported.EncodeByteArray(v, format)
|
||||
}
|
||||
|
||||
// MarshalAsByteArray will base-64 encode the byte slice v, then calls SetBody.
|
||||
// The encoded value is treated as a JSON string.
|
||||
func MarshalAsByteArray(req *policy.Request, v []byte, format Base64Encoding) error {
|
||||
// send as a JSON string
|
||||
encode := fmt.Sprintf("\"%s\"", EncodeByteArray(v, format))
|
||||
// tsp generated code can set Content-Type so we must prefer that
|
||||
return exported.SetBody(req, exported.NopCloser(strings.NewReader(encode)), shared.ContentTypeAppJSON, false)
|
||||
}
|
||||
|
||||
// MarshalAsJSON calls json.Marshal() to get the JSON encoding of v then calls SetBody.
|
||||
func MarshalAsJSON(req *policy.Request, v any) error {
|
||||
b, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error marshalling type %T: %s", v, err)
|
||||
}
|
||||
// tsp generated code can set Content-Type so we must prefer that
|
||||
return exported.SetBody(req, exported.NopCloser(bytes.NewReader(b)), shared.ContentTypeAppJSON, false)
|
||||
}
|
||||
|
||||
// MarshalAsXML calls xml.Marshal() to get the XML encoding of v then calls SetBody.
|
||||
func MarshalAsXML(req *policy.Request, v any) error {
|
||||
b, err := xml.Marshal(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error marshalling type %T: %s", v, err)
|
||||
}
|
||||
// inclue the XML header as some services require it
|
||||
b = []byte(xml.Header + string(b))
|
||||
return req.SetBody(exported.NopCloser(bytes.NewReader(b)), shared.ContentTypeAppXML)
|
||||
}
|
||||
|
||||
// SetMultipartFormData writes the specified keys/values as multi-part form fields with the specified value.
|
||||
// File content must be specified as an [io.ReadSeekCloser] or [streaming.MultipartContent].
|
||||
// Byte slices will be treated as JSON. All other values are treated as string values.
|
||||
func SetMultipartFormData(req *policy.Request, formData map[string]any) error {
|
||||
body := bytes.Buffer{}
|
||||
writer := multipart.NewWriter(&body)
|
||||
|
||||
writeContent := func(fieldname, filename string, src io.Reader) error {
|
||||
fd, err := writer.CreateFormFile(fieldname, filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// copy the data to the form file
|
||||
if _, err = io.Copy(fd, src); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
quoteEscaper := strings.NewReplacer("\\", "\\\\", `"`, "\\\"")
|
||||
|
||||
writeMultipartContent := func(fieldname string, mpc streaming.MultipartContent) error {
|
||||
if mpc.Body == nil {
|
||||
return errors.New("streaming.MultipartContent.Body cannot be nil")
|
||||
}
|
||||
|
||||
// use fieldname for the file name when unspecified
|
||||
filename := fieldname
|
||||
|
||||
if mpc.ContentType == "" && mpc.Filename == "" {
|
||||
return writeContent(fieldname, filename, mpc.Body)
|
||||
}
|
||||
if mpc.Filename != "" {
|
||||
filename = mpc.Filename
|
||||
}
|
||||
// this is pretty much copied from multipart.Writer.CreateFormFile
|
||||
// but lets us set the caller provided Content-Type and filename
|
||||
h := make(textproto.MIMEHeader)
|
||||
h.Set("Content-Disposition",
|
||||
fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
|
||||
quoteEscaper.Replace(fieldname), quoteEscaper.Replace(filename)))
|
||||
contentType := "application/octet-stream"
|
||||
if mpc.ContentType != "" {
|
||||
contentType = mpc.ContentType
|
||||
}
|
||||
h.Set("Content-Type", contentType)
|
||||
fd, err := writer.CreatePart(h)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// copy the data to the form file
|
||||
if _, err = io.Copy(fd, mpc.Body); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// the same as multipart.Writer.WriteField but lets us specify the Content-Type
|
||||
writeField := func(fieldname, contentType string, value string) error {
|
||||
h := make(textproto.MIMEHeader)
|
||||
h.Set("Content-Disposition",
|
||||
fmt.Sprintf(`form-data; name="%s"`, quoteEscaper.Replace(fieldname)))
|
||||
h.Set("Content-Type", contentType)
|
||||
fd, err := writer.CreatePart(h)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = fd.Write([]byte(value)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
for k, v := range formData {
|
||||
if rsc, ok := v.(io.ReadSeekCloser); ok {
|
||||
if err := writeContent(k, k, rsc); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
} else if rscs, ok := v.([]io.ReadSeekCloser); ok {
|
||||
for _, rsc := range rscs {
|
||||
if err := writeContent(k, k, rsc); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
} else if mpc, ok := v.(streaming.MultipartContent); ok {
|
||||
if err := writeMultipartContent(k, mpc); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
} else if mpcs, ok := v.([]streaming.MultipartContent); ok {
|
||||
for _, mpc := range mpcs {
|
||||
if err := writeMultipartContent(k, mpc); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
var content string
|
||||
contentType := shared.ContentTypeTextPlain
|
||||
switch tt := v.(type) {
|
||||
case []byte:
|
||||
// JSON, don't quote it
|
||||
content = string(tt)
|
||||
contentType = shared.ContentTypeAppJSON
|
||||
case string:
|
||||
content = tt
|
||||
default:
|
||||
// ensure the value is in string format
|
||||
content = fmt.Sprintf("%v", v)
|
||||
}
|
||||
|
||||
if err := writeField(k, contentType, content); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := writer.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return req.SetBody(exported.NopCloser(bytes.NewReader(body.Bytes())), writer.FormDataContentType())
|
||||
}
|
||||
|
||||
// SkipBodyDownload will disable automatic downloading of the response body.
|
||||
func SkipBodyDownload(req *policy.Request) {
|
||||
req.SetOperationValue(bodyDownloadPolicyOpValues{Skip: true})
|
||||
}
|
||||
|
||||
// CtxAPINameKey is used as a context key for adding/retrieving the API name.
|
||||
type CtxAPINameKey = shared.CtxAPINameKey
|
||||
|
||||
// NewUUID returns a new UUID using the RFC4122 algorithm.
|
||||
func NewUUID() (string, error) {
|
||||
u, err := uuid.New()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return u.String(), nil
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
azexported "github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/exported"
|
||||
)
|
||||
|
||||
// Payload reads and returns the response body or an error.
|
||||
// On a successful read, the response body is cached.
|
||||
// Subsequent reads will access the cached value.
|
||||
func Payload(resp *http.Response) ([]byte, error) {
|
||||
return exported.Payload(resp, nil)
|
||||
}
|
||||
|
||||
// HasStatusCode returns true if the Response's status code is one of the specified values.
|
||||
func HasStatusCode(resp *http.Response, statusCodes ...int) bool {
|
||||
return exported.HasStatusCode(resp, statusCodes...)
|
||||
}
|
||||
|
||||
// UnmarshalAsByteArray will base-64 decode the received payload and place the result into the value pointed to by v.
|
||||
func UnmarshalAsByteArray(resp *http.Response, v *[]byte, format Base64Encoding) error {
|
||||
p, err := Payload(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return DecodeByteArray(string(p), v, format)
|
||||
}
|
||||
|
||||
// UnmarshalAsJSON calls json.Unmarshal() to unmarshal the received payload into the value pointed to by v.
|
||||
func UnmarshalAsJSON(resp *http.Response, v any) error {
|
||||
payload, err := Payload(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: verify early exit is correct
|
||||
if len(payload) == 0 {
|
||||
return nil
|
||||
}
|
||||
err = removeBOM(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(payload, v)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("unmarshalling type %T: %s", v, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// UnmarshalAsXML calls xml.Unmarshal() to unmarshal the received payload into the value pointed to by v.
|
||||
func UnmarshalAsXML(resp *http.Response, v any) error {
|
||||
payload, err := Payload(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: verify early exit is correct
|
||||
if len(payload) == 0 {
|
||||
return nil
|
||||
}
|
||||
err = removeBOM(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = xml.Unmarshal(payload, v)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("unmarshalling type %T: %s", v, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Drain reads the response body to completion then closes it. The bytes read are discarded.
|
||||
func Drain(resp *http.Response) {
|
||||
if resp != nil && resp.Body != nil {
|
||||
_, _ = io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// removeBOM removes any byte-order mark prefix from the payload if present.
|
||||
func removeBOM(resp *http.Response) error {
|
||||
_, err := exported.Payload(resp, &exported.PayloadOptions{
|
||||
BytesModifier: func(b []byte) []byte {
|
||||
// UTF8
|
||||
return bytes.TrimPrefix(b, []byte("\xef\xbb\xbf"))
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DecodeByteArray will base-64 decode the provided string into v.
|
||||
func DecodeByteArray(s string, v *[]byte, format Base64Encoding) error {
|
||||
return azexported.DecodeByteArray(s, v, format)
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
//go:build !wasm
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
)
|
||||
|
||||
func defaultTransportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) {
|
||||
return dialer.DialContext
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
//go:build (js && wasm) || wasip1
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
)
|
||||
|
||||
func defaultTransportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) {
|
||||
return nil
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/http2"
|
||||
)
|
||||
|
||||
var defaultHTTPClient *http.Client
|
||||
|
||||
func init() {
|
||||
defaultTransport := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: defaultTransportDialContext(&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}),
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
MaxIdleConnsPerHost: 10,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
TLSClientConfig: &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
Renegotiation: tls.RenegotiateFreelyAsClient,
|
||||
},
|
||||
}
|
||||
// TODO: evaluate removing this once https://github.com/golang/go/issues/59690 has been fixed
|
||||
if http2Transport, err := http2.ConfigureTransports(defaultTransport); err == nil {
|
||||
// if the connection has been idle for 10 seconds, send a ping frame for a health check
|
||||
http2Transport.ReadIdleTimeout = 10 * time.Second
|
||||
// if there's no response to the ping within the timeout, the connection will be closed
|
||||
http2Transport.PingTimeout = 5 * time.Second
|
||||
}
|
||||
defaultHTTPClient = &http.Client{
|
||||
Transport: defaultTransport,
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
||||
// Use of this source code is governed by an MIT
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package streaming contains helpers for streaming IO operations and progress reporting.
|
||||
package streaming
|
||||
@@ -1,89 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package streaming
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported"
|
||||
)
|
||||
|
||||
type progress struct {
|
||||
rc io.ReadCloser
|
||||
rsc io.ReadSeekCloser
|
||||
pr func(bytesTransferred int64)
|
||||
offset int64
|
||||
}
|
||||
|
||||
// NopCloser returns a ReadSeekCloser with a no-op close method wrapping the provided io.ReadSeeker.
|
||||
// In addition to adding a Close method to an io.ReadSeeker, this can also be used to wrap an
|
||||
// io.ReadSeekCloser with a no-op Close method to allow explicit control of when the io.ReedSeekCloser
|
||||
// has its underlying stream closed.
|
||||
func NopCloser(rs io.ReadSeeker) io.ReadSeekCloser {
|
||||
return exported.NopCloser(rs)
|
||||
}
|
||||
|
||||
// NewRequestProgress adds progress reporting to an HTTP request's body stream.
|
||||
func NewRequestProgress(body io.ReadSeekCloser, pr func(bytesTransferred int64)) io.ReadSeekCloser {
|
||||
return &progress{
|
||||
rc: body,
|
||||
rsc: body,
|
||||
pr: pr,
|
||||
offset: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// NewResponseProgress adds progress reporting to an HTTP response's body stream.
|
||||
func NewResponseProgress(body io.ReadCloser, pr func(bytesTransferred int64)) io.ReadCloser {
|
||||
return &progress{
|
||||
rc: body,
|
||||
rsc: nil,
|
||||
pr: pr,
|
||||
offset: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// Read reads a block of data from an inner stream and reports progress
|
||||
func (p *progress) Read(b []byte) (n int, err error) {
|
||||
n, err = p.rc.Read(b)
|
||||
if err != nil && err != io.EOF {
|
||||
return
|
||||
}
|
||||
p.offset += int64(n)
|
||||
// Invokes the user's callback method to report progress
|
||||
p.pr(p.offset)
|
||||
return
|
||||
}
|
||||
|
||||
// Seek only expects a zero or from beginning.
|
||||
func (p *progress) Seek(offset int64, whence int) (int64, error) {
|
||||
// This should only ever be called with offset = 0 and whence = io.SeekStart
|
||||
n, err := p.rsc.Seek(offset, whence)
|
||||
if err == nil {
|
||||
p.offset = int64(n)
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
// requestBodyProgress supports Close but the underlying stream may not; if it does, Close will close it.
|
||||
func (p *progress) Close() error {
|
||||
return p.rc.Close()
|
||||
}
|
||||
|
||||
// MultipartContent contains streaming content used in multipart/form payloads.
|
||||
type MultipartContent struct {
|
||||
// Body contains the required content body.
|
||||
Body io.ReadSeekCloser
|
||||
|
||||
// ContentType optionally specifies the HTTP Content-Type for this Body.
|
||||
// The default value is application/octet-stream.
|
||||
ContentType string
|
||||
|
||||
// Filename optionally specifies the filename for this Body.
|
||||
// The default value is the field name for the multipart/form section.
|
||||
Filename string
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright 2017 Microsoft Corporation. All rights reserved.
|
||||
// Use of this source code is governed by an MIT
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package to contains various type-conversion helper functions.
|
||||
package to
|
||||
@@ -1,21 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package to
|
||||
|
||||
// Ptr returns a pointer to the provided value.
|
||||
func Ptr[T any](v T) *T {
|
||||
return &v
|
||||
}
|
||||
|
||||
// SliceOfPtrs returns a slice of *T from the specified values.
|
||||
func SliceOfPtrs[T any](vv ...T) []*T {
|
||||
slc := make([]*T, len(vv))
|
||||
for i := range vv {
|
||||
slc[i] = Ptr(vv[i])
|
||||
}
|
||||
return slc
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package tracing
|
||||
|
||||
// SpanKind represents the role of a Span inside a Trace. Often, this defines how a Span will be processed and visualized by various backends.
|
||||
type SpanKind int
|
||||
|
||||
const (
|
||||
// SpanKindInternal indicates the span represents an internal operation within an application.
|
||||
SpanKindInternal SpanKind = 1
|
||||
|
||||
// SpanKindServer indicates the span covers server-side handling of a request.
|
||||
SpanKindServer SpanKind = 2
|
||||
|
||||
// SpanKindClient indicates the span describes a request to a remote service.
|
||||
SpanKindClient SpanKind = 3
|
||||
|
||||
// SpanKindProducer indicates the span was created by a messaging producer.
|
||||
SpanKindProducer SpanKind = 4
|
||||
|
||||
// SpanKindConsumer indicates the span was created by a messaging consumer.
|
||||
SpanKindConsumer SpanKind = 5
|
||||
)
|
||||
|
||||
// SpanStatus represents the status of a span.
|
||||
type SpanStatus int
|
||||
|
||||
const (
|
||||
// SpanStatusUnset is the default status code.
|
||||
SpanStatusUnset SpanStatus = 0
|
||||
|
||||
// SpanStatusError indicates the operation contains an error.
|
||||
SpanStatusError SpanStatus = 1
|
||||
|
||||
// SpanStatusOK indicates the operation completed successfully.
|
||||
SpanStatusOK SpanStatus = 2
|
||||
)
|
||||
@@ -1,191 +0,0 @@
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
// Package tracing contains the definitions needed to support distributed tracing.
|
||||
package tracing
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
// ProviderOptions contains the optional values when creating a Provider.
|
||||
type ProviderOptions struct {
|
||||
// for future expansion
|
||||
}
|
||||
|
||||
// NewProvider creates a new Provider with the specified values.
|
||||
// - newTracerFn is the underlying implementation for creating Tracer instances
|
||||
// - options contains optional values; pass nil to accept the default value
|
||||
func NewProvider(newTracerFn func(name, version string) Tracer, options *ProviderOptions) Provider {
|
||||
return Provider{
|
||||
newTracerFn: newTracerFn,
|
||||
}
|
||||
}
|
||||
|
||||
// Provider is the factory that creates Tracer instances.
|
||||
// It defaults to a no-op provider.
|
||||
type Provider struct {
|
||||
newTracerFn func(name, version string) Tracer
|
||||
}
|
||||
|
||||
// NewTracer creates a new Tracer for the specified module name and version.
|
||||
// - module - the fully qualified name of the module
|
||||
// - version - the version of the module
|
||||
func (p Provider) NewTracer(module, version string) (tracer Tracer) {
|
||||
if p.newTracerFn != nil {
|
||||
tracer = p.newTracerFn(module, version)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TracerOptions contains the optional values when creating a Tracer.
|
||||
type TracerOptions struct {
|
||||
// SpanFromContext contains the implementation for the Tracer.SpanFromContext method.
|
||||
SpanFromContext func(context.Context) Span
|
||||
}
|
||||
|
||||
// NewTracer creates a Tracer with the specified values.
|
||||
// - newSpanFn is the underlying implementation for creating Span instances
|
||||
// - options contains optional values; pass nil to accept the default value
|
||||
func NewTracer(newSpanFn func(ctx context.Context, spanName string, options *SpanOptions) (context.Context, Span), options *TracerOptions) Tracer {
|
||||
if options == nil {
|
||||
options = &TracerOptions{}
|
||||
}
|
||||
return Tracer{
|
||||
newSpanFn: newSpanFn,
|
||||
spanFromContextFn: options.SpanFromContext,
|
||||
}
|
||||
}
|
||||
|
||||
// Tracer is the factory that creates Span instances.
|
||||
type Tracer struct {
|
||||
attrs []Attribute
|
||||
newSpanFn func(ctx context.Context, spanName string, options *SpanOptions) (context.Context, Span)
|
||||
spanFromContextFn func(ctx context.Context) Span
|
||||
}
|
||||
|
||||
// Start creates a new span and a context.Context that contains it.
|
||||
// - ctx is the parent context for this span. If it contains a Span, the newly created span will be a child of that span, else it will be a root span
|
||||
// - spanName identifies the span within a trace, it's typically the fully qualified API name
|
||||
// - options contains optional values for the span, pass nil to accept any defaults
|
||||
func (t Tracer) Start(ctx context.Context, spanName string, options *SpanOptions) (context.Context, Span) {
|
||||
if t.newSpanFn != nil {
|
||||
opts := SpanOptions{}
|
||||
if options != nil {
|
||||
opts = *options
|
||||
}
|
||||
opts.Attributes = append(opts.Attributes, t.attrs...)
|
||||
return t.newSpanFn(ctx, spanName, &opts)
|
||||
}
|
||||
return ctx, Span{}
|
||||
}
|
||||
|
||||
// SetAttributes sets attrs to be applied to each Span. If a key from attrs
|
||||
// already exists for an attribute of the Span it will be overwritten with
|
||||
// the value contained in attrs.
|
||||
func (t *Tracer) SetAttributes(attrs ...Attribute) {
|
||||
t.attrs = append(t.attrs, attrs...)
|
||||
}
|
||||
|
||||
// Enabled returns true if this Tracer is capable of creating Spans.
|
||||
func (t Tracer) Enabled() bool {
|
||||
return t.newSpanFn != nil
|
||||
}
|
||||
|
||||
// SpanFromContext returns the Span associated with the current context.
|
||||
// If the provided context has no Span, false is returned.
|
||||
func (t Tracer) SpanFromContext(ctx context.Context) Span {
|
||||
if t.spanFromContextFn != nil {
|
||||
return t.spanFromContextFn(ctx)
|
||||
}
|
||||
return Span{}
|
||||
}
|
||||
|
||||
// SpanOptions contains optional settings for creating a span.
|
||||
type SpanOptions struct {
|
||||
// Kind indicates the kind of Span.
|
||||
Kind SpanKind
|
||||
|
||||
// Attributes contains key-value pairs of attributes for the span.
|
||||
Attributes []Attribute
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// SpanImpl abstracts the underlying implementation for Span,
|
||||
// allowing it to work with various tracing implementations.
|
||||
// Any zero-values will have their default, no-op behavior.
|
||||
type SpanImpl struct {
|
||||
// End contains the implementation for the Span.End method.
|
||||
End func()
|
||||
|
||||
// SetAttributes contains the implementation for the Span.SetAttributes method.
|
||||
SetAttributes func(...Attribute)
|
||||
|
||||
// AddEvent contains the implementation for the Span.AddEvent method.
|
||||
AddEvent func(string, ...Attribute)
|
||||
|
||||
// SetStatus contains the implementation for the Span.SetStatus method.
|
||||
SetStatus func(SpanStatus, string)
|
||||
}
|
||||
|
||||
// NewSpan creates a Span with the specified implementation.
|
||||
func NewSpan(impl SpanImpl) Span {
|
||||
return Span{
|
||||
impl: impl,
|
||||
}
|
||||
}
|
||||
|
||||
// Span is a single unit of a trace. A trace can contain multiple spans.
|
||||
// A zero-value Span provides a no-op implementation.
|
||||
type Span struct {
|
||||
impl SpanImpl
|
||||
}
|
||||
|
||||
// End terminates the span and MUST be called before the span leaves scope.
|
||||
// Any further updates to the span will be ignored after End is called.
|
||||
func (s Span) End() {
|
||||
if s.impl.End != nil {
|
||||
s.impl.End()
|
||||
}
|
||||
}
|
||||
|
||||
// SetAttributes sets the specified attributes on the Span.
|
||||
// Any existing attributes with the same keys will have their values overwritten.
|
||||
func (s Span) SetAttributes(attrs ...Attribute) {
|
||||
if s.impl.SetAttributes != nil {
|
||||
s.impl.SetAttributes(attrs...)
|
||||
}
|
||||
}
|
||||
|
||||
// AddEvent adds a named event with an optional set of attributes to the span.
|
||||
func (s Span) AddEvent(name string, attrs ...Attribute) {
|
||||
if s.impl.AddEvent != nil {
|
||||
s.impl.AddEvent(name, attrs...)
|
||||
}
|
||||
}
|
||||
|
||||
// SetStatus sets the status on the span along with a description.
|
||||
func (s Span) SetStatus(code SpanStatus, desc string) {
|
||||
if s.impl.SetStatus != nil {
|
||||
s.impl.SetStatus(code, desc)
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Attribute is a key-value pair.
|
||||
type Attribute struct {
|
||||
// Key is the name of the attribute.
|
||||
Key string
|
||||
|
||||
// Value is the attribute's value.
|
||||
// Types that are natively supported include int64, float64, int, bool, string.
|
||||
// Any other type will be formatted per rules of fmt.Sprintf("%v").
|
||||
Value any
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
# live test artifacts
|
||||
Dockerfile
|
||||
k8s.yaml
|
||||
sshkey*
|
||||
@@ -1,20 +0,0 @@
|
||||
# Breaking Changes
|
||||
|
||||
## v1.8.0
|
||||
|
||||
### New errors from `NewManagedIdentityCredential` in some environments
|
||||
|
||||
`NewManagedIdentityCredential` now returns an error when `ManagedIdentityCredentialOptions.ID` is set in a hosting environment whose managed identity API doesn't support user-assigned identities. `ManagedIdentityCredential.GetToken()` formerly logged a warning in these cases. Returning an error instead prevents the credential authenticating an unexpected identity. The affected hosting environments are:
|
||||
* Azure Arc
|
||||
* Azure ML (when a resource or object ID is specified; client IDs are supported)
|
||||
* Cloud Shell
|
||||
* Service Fabric
|
||||
|
||||
## v1.6.0
|
||||
|
||||
### Behavioral change to `DefaultAzureCredential` in IMDS managed identity scenarios
|
||||
|
||||
As of `azidentity` v1.6.0, `DefaultAzureCredential` makes a minor behavioral change when it uses IMDS managed
|
||||
identity. It sends its first request to IMDS without the "Metadata" header, to expedite validating whether the endpoint
|
||||
is available. This precedes the credential's first token request and is guaranteed to fail with a 400 error. This error
|
||||
response can appear in logs but doesn't indicate authentication failed.
|
||||
@@ -1,641 +0,0 @@
|
||||
# Release History
|
||||
|
||||
## 1.8.2 (2025-02-12)
|
||||
|
||||
### Other Changes
|
||||
* Upgraded dependencies
|
||||
|
||||
## 1.8.1 (2025-01-15)
|
||||
|
||||
### Bugs Fixed
|
||||
* User credential types inconsistently log access token scopes
|
||||
* `DefaultAzureCredential` skips managed identity in Azure Container Instances
|
||||
* Credentials having optional tenant IDs such as `AzureCLICredential` and
|
||||
`InteractiveBrowserCredential` require setting `AdditionallyAllowedTenants`
|
||||
when used with some clients
|
||||
|
||||
### Other Changes
|
||||
* `ChainedTokenCredential` and `DefaultAzureCredential` continue to their next
|
||||
credential after `ManagedIdentityCredential` receives an unexpected response
|
||||
from IMDS, indicating the response is from something else such as a proxy
|
||||
|
||||
## 1.8.0 (2024-10-08)
|
||||
|
||||
### Other Changes
|
||||
* `AzurePipelinesCredential` sets an additional OIDC request header so that it
|
||||
receives a 401 instead of a 302 after presenting an invalid system access token
|
||||
* Allow logging of debugging headers for `AzurePipelinesCredential` and include
|
||||
them in error messages
|
||||
|
||||
## 1.8.0-beta.3 (2024-09-17)
|
||||
|
||||
### Features Added
|
||||
* Added `ObjectID` type for `ManagedIdentityCredentialOptions.ID`
|
||||
|
||||
### Other Changes
|
||||
* Removed redundant content from error messages
|
||||
|
||||
## 1.8.0-beta.2 (2024-08-06)
|
||||
|
||||
### Breaking Changes
|
||||
* `NewManagedIdentityCredential` now returns an error when a user-assigned identity
|
||||
is specified on a platform whose managed identity API doesn't support that.
|
||||
`ManagedIdentityCredential.GetToken()` formerly logged a warning in these cases.
|
||||
Returning an error instead prevents the credential authenticating an unexpected
|
||||
identity, causing a client to act with unexpected privileges. The affected
|
||||
platforms are:
|
||||
* Azure Arc
|
||||
* Azure ML (when a resource ID is specified; client IDs are supported)
|
||||
* Cloud Shell
|
||||
* Service Fabric
|
||||
|
||||
### Other Changes
|
||||
* If `DefaultAzureCredential` receives a non-JSON response when probing IMDS before
|
||||
attempting to authenticate a managed identity, it continues to the next credential
|
||||
in the chain instead of immediately returning an error.
|
||||
|
||||
## 1.8.0-beta.1 (2024-07-17)
|
||||
|
||||
### Features Added
|
||||
* Restored persistent token caching feature
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against a beta version such as v1.7.0-beta.1
|
||||
* Redesigned the persistent caching API. Encryption is now required in all cases
|
||||
and persistent cache construction is separate from credential construction.
|
||||
The `PersistentUserAuthentication` example in the package docs has been updated
|
||||
to demonstrate the new API.
|
||||
|
||||
## 1.7.0 (2024-06-20)
|
||||
|
||||
### Features Added
|
||||
* `AzurePipelinesCredential` authenticates an Azure Pipelines service connection with
|
||||
workload identity federation
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against a beta version such as v1.7.0-beta.1
|
||||
* Removed the persistent token caching API. It will return in v1.8.0-beta.1
|
||||
|
||||
## 1.7.0-beta.1 (2024-06-10)
|
||||
|
||||
### Features Added
|
||||
* Restored `AzurePipelinesCredential` and persistent token caching API
|
||||
|
||||
## Breaking Changes
|
||||
> These changes affect only code written against a beta version such as v1.6.0-beta.4
|
||||
* Values which `NewAzurePipelinesCredential` read from environment variables in
|
||||
prior versions are now parameters
|
||||
* Renamed `AzurePipelinesServiceConnectionCredentialOptions` to `AzurePipelinesCredentialOptions`
|
||||
|
||||
### Bugs Fixed
|
||||
* Managed identity bug fixes
|
||||
|
||||
## 1.6.0 (2024-06-10)
|
||||
|
||||
### Features Added
|
||||
* `NewOnBehalfOfCredentialWithClientAssertions` creates an on-behalf-of credential
|
||||
that authenticates with client assertions such as federated credentials
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against a beta version such as v1.6.0-beta.4
|
||||
* Removed `AzurePipelinesCredential` and the persistent token caching API.
|
||||
They will return in v1.7.0-beta.1
|
||||
|
||||
### Bugs Fixed
|
||||
* Managed identity bug fixes
|
||||
|
||||
## 1.6.0-beta.4 (2024-05-14)
|
||||
|
||||
### Features Added
|
||||
* `AzurePipelinesCredential` authenticates an Azure Pipeline service connection with
|
||||
workload identity federation
|
||||
|
||||
## 1.6.0-beta.3 (2024-04-09)
|
||||
|
||||
### Breaking Changes
|
||||
* `DefaultAzureCredential` now sends a probe request with no retries for IMDS managed identity
|
||||
environments to avoid excessive retry delays when the IMDS endpoint is not available. This
|
||||
should improve credential chain resolution for local development scenarios.
|
||||
|
||||
### Bugs Fixed
|
||||
* `ManagedIdentityCredential` now specifies resource IDs correctly for Azure Container Instances
|
||||
|
||||
## 1.5.2 (2024-04-09)
|
||||
|
||||
### Bugs Fixed
|
||||
* `ManagedIdentityCredential` now specifies resource IDs correctly for Azure Container Instances
|
||||
|
||||
### Other Changes
|
||||
* Restored v1.4.0 error behavior for empty tenant IDs
|
||||
* Upgraded dependencies
|
||||
|
||||
## 1.6.0-beta.2 (2024-02-06)
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against a beta version such as v1.6.0-beta.1
|
||||
* Replaced `ErrAuthenticationRequired` with `AuthenticationRequiredError`, a struct
|
||||
type that carries the `TokenRequestOptions` passed to the `GetToken` call which
|
||||
returned the error.
|
||||
|
||||
### Bugs Fixed
|
||||
* Fixed more cases in which credential chains like `DefaultAzureCredential`
|
||||
should try their next credential after attempting managed identity
|
||||
authentication in a Docker Desktop container
|
||||
|
||||
### Other Changes
|
||||
* `AzureCLICredential` uses the CLI's `expires_on` value for token expiration
|
||||
|
||||
## 1.6.0-beta.1 (2024-01-17)
|
||||
|
||||
### Features Added
|
||||
* Restored persistent token caching API first added in v1.5.0-beta.1
|
||||
* Added `AzureCLICredentialOptions.Subscription`
|
||||
|
||||
## 1.5.1 (2024-01-17)
|
||||
|
||||
### Bugs Fixed
|
||||
* `InteractiveBrowserCredential` handles `AdditionallyAllowedTenants` correctly
|
||||
|
||||
## 1.5.0 (2024-01-16)
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against a beta version such as v1.5.0-beta.1
|
||||
* Removed persistent token caching. It will return in v1.6.0-beta.1
|
||||
|
||||
### Bugs Fixed
|
||||
* Credentials now preserve MSAL headers e.g. X-Client-Sku
|
||||
|
||||
### Other Changes
|
||||
* Upgraded dependencies
|
||||
|
||||
## 1.5.0-beta.2 (2023-11-07)
|
||||
|
||||
### Features Added
|
||||
* `DefaultAzureCredential` and `ManagedIdentityCredential` support Azure ML managed identity
|
||||
* Added spans for distributed tracing.
|
||||
|
||||
## 1.5.0-beta.1 (2023-10-10)
|
||||
|
||||
### Features Added
|
||||
* Optional persistent token caching for most credentials. Set `TokenCachePersistenceOptions`
|
||||
on a credential's options to enable and configure this. See the package documentation for
|
||||
this version and [TOKEN_CACHING.md](https://aka.ms/azsdk/go/identity/caching) for more
|
||||
details.
|
||||
* `AzureDeveloperCLICredential` authenticates with the Azure Developer CLI (`azd`). This
|
||||
credential is also part of the `DefaultAzureCredential` authentication flow.
|
||||
|
||||
## 1.4.0 (2023-10-10)
|
||||
|
||||
### Bugs Fixed
|
||||
* `ManagedIdentityCredential` will now retry when IMDS responds 410 or 503
|
||||
|
||||
## 1.4.0-beta.5 (2023-09-12)
|
||||
|
||||
### Features Added
|
||||
* Service principal credentials can request CAE tokens
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against a beta version such as v1.4.0-beta.4
|
||||
* Whether `GetToken` requests a CAE token is now determined by `TokenRequestOptions.EnableCAE`. Azure
|
||||
SDK clients which support CAE will set this option automatically. Credentials no longer request CAE
|
||||
tokens by default or observe the environment variable "AZURE_IDENTITY_DISABLE_CP1".
|
||||
|
||||
### Bugs Fixed
|
||||
* Credential chains such as `DefaultAzureCredential` now try their next credential, if any, when
|
||||
managed identity authentication fails in a Docker Desktop container
|
||||
([#21417](https://github.com/Azure/azure-sdk-for-go/issues/21417))
|
||||
|
||||
## 1.4.0-beta.4 (2023-08-16)
|
||||
|
||||
### Other Changes
|
||||
* Upgraded dependencies
|
||||
|
||||
## 1.3.1 (2023-08-16)
|
||||
|
||||
### Other Changes
|
||||
* Upgraded dependencies
|
||||
|
||||
## 1.4.0-beta.3 (2023-08-08)
|
||||
|
||||
### Bugs Fixed
|
||||
* One invocation of `AzureCLICredential.GetToken()` and `OnBehalfOfCredential.GetToken()`
|
||||
can no longer make two authentication attempts
|
||||
|
||||
## 1.4.0-beta.2 (2023-07-14)
|
||||
|
||||
### Other Changes
|
||||
* `DefaultAzureCredentialOptions.TenantID` applies to workload identity authentication
|
||||
* Upgraded dependencies
|
||||
|
||||
## 1.4.0-beta.1 (2023-06-06)
|
||||
|
||||
### Other Changes
|
||||
* Re-enabled CAE support as in v1.3.0-beta.3
|
||||
|
||||
## 1.3.0 (2023-05-09)
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against a beta version such as v1.3.0-beta.5
|
||||
* Renamed `NewOnBehalfOfCredentialFromCertificate` to `NewOnBehalfOfCredentialWithCertificate`
|
||||
* Renamed `NewOnBehalfOfCredentialFromSecret` to `NewOnBehalfOfCredentialWithSecret`
|
||||
|
||||
### Other Changes
|
||||
* Upgraded to MSAL v1.0.0
|
||||
|
||||
## 1.3.0-beta.5 (2023-04-11)
|
||||
|
||||
### Breaking Changes
|
||||
> These changes affect only code written against a beta version such as v1.3.0-beta.4
|
||||
* Moved `NewWorkloadIdentityCredential()` parameters into `WorkloadIdentityCredentialOptions`.
|
||||
The constructor now reads default configuration from environment variables set by the Azure
|
||||
workload identity webhook by default.
|
||||
([#20478](https://github.com/Azure/azure-sdk-for-go/pull/20478))
|
||||
* Removed CAE support. It will return in v1.4.0-beta.1
|
||||
([#20479](https://github.com/Azure/azure-sdk-for-go/pull/20479))
|
||||
|
||||
### Bugs Fixed
|
||||
* Fixed an issue in `DefaultAzureCredential` that could cause the managed identity endpoint check to fail in rare circumstances.
|
||||
|
||||
## 1.3.0-beta.4 (2023-03-08)
|
||||
|
||||
### Features Added
|
||||
* Added `WorkloadIdentityCredentialOptions.AdditionallyAllowedTenants` and `.DisableInstanceDiscovery`
|
||||
|
||||
### Bugs Fixed
|
||||
* Credentials now synchronize within `GetToken()` so a single instance can be shared among goroutines
|
||||
([#20044](https://github.com/Azure/azure-sdk-for-go/issues/20044))
|
||||
|
||||
### Other Changes
|
||||
* Upgraded dependencies
|
||||
|
||||
## 1.2.2 (2023-03-07)
|
||||
|
||||
### Other Changes
|
||||
* Upgraded dependencies
|
||||
|
||||
## 1.3.0-beta.3 (2023-02-07)
|
||||
|
||||
### Features Added
|
||||
* By default, credentials set client capability "CP1" to enable support for
|
||||
[Continuous Access Evaluation (CAE)](https://learn.microsoft.com/entra/identity-platform/app-resilience-continuous-access-evaluation).
|
||||
This indicates to Microsoft Entra ID that your application can handle CAE claims challenges.
|
||||
You can disable this behavior by setting the environment variable "AZURE_IDENTITY_DISABLE_CP1" to "true".
|
||||
* `InteractiveBrowserCredentialOptions.LoginHint` enables pre-populating the login
|
||||
prompt with a username ([#15599](https://github.com/Azure/azure-sdk-for-go/pull/15599))
|
||||
* Service principal and user credentials support ADFS authentication on Azure Stack.
|
||||
Specify "adfs" as the credential's tenant.
|
||||
* Applications running in private or disconnected clouds can prevent credentials from
|
||||
requesting Microsoft Entra instance metadata by setting the `DisableInstanceDiscovery`
|
||||
field on credential options.
|
||||
* Many credentials can now be configured to authenticate in multiple tenants. The
|
||||
options types for these credentials have an `AdditionallyAllowedTenants` field
|
||||
that specifies additional tenants in which the credential may authenticate.
|
||||
|
||||
## 1.3.0-beta.2 (2023-01-10)
|
||||
|
||||
### Features Added
|
||||
* Added `OnBehalfOfCredential` to support the on-behalf-of flow
|
||||
([#16642](https://github.com/Azure/azure-sdk-for-go/issues/16642))
|
||||
|
||||
### Bugs Fixed
|
||||
* `AzureCLICredential` reports token expiration in local time (should be UTC)
|
||||
|
||||
### Other Changes
|
||||
* `AzureCLICredential` imposes its default timeout only when the `Context`
|
||||
passed to `GetToken()` has no deadline
|
||||
* Added `NewCredentialUnavailableError()`. This function constructs an error indicating
|
||||
a credential can't authenticate and an encompassing `ChainedTokenCredential` should
|
||||
try its next credential, if any.
|
||||
|
||||
## 1.3.0-beta.1 (2022-12-13)
|
||||
|
||||
### Features Added
|
||||
* `WorkloadIdentityCredential` and `DefaultAzureCredential` support
|
||||
Workload Identity Federation on Kubernetes. `DefaultAzureCredential`
|
||||
support requires environment variable configuration as set by the
|
||||
Workload Identity webhook.
|
||||
([#15615](https://github.com/Azure/azure-sdk-for-go/issues/15615))
|
||||
|
||||
## 1.2.0 (2022-11-08)
|
||||
|
||||
### Other Changes
|
||||
* This version includes all fixes and features from 1.2.0-beta.*
|
||||
|
||||
## 1.2.0-beta.3 (2022-10-11)
|
||||
|
||||
### Features Added
|
||||
* `ManagedIdentityCredential` caches tokens in memory
|
||||
|
||||
### Bugs Fixed
|
||||
* `ClientCertificateCredential` sends only the leaf cert for SNI authentication
|
||||
|
||||
## 1.2.0-beta.2 (2022-08-10)
|
||||
|
||||
### Features Added
|
||||
* Added `ClientAssertionCredential` to enable applications to authenticate
|
||||
with custom client assertions
|
||||
|
||||
### Other Changes
|
||||
* Updated AuthenticationFailedError with links to TROUBLESHOOTING.md for relevant errors
|
||||
* Upgraded `microsoft-authentication-library-for-go` requirement to v0.6.0
|
||||
|
||||
## 1.2.0-beta.1 (2022-06-07)
|
||||
|
||||
### Features Added
|
||||
* `EnvironmentCredential` reads certificate passwords from `AZURE_CLIENT_CERTIFICATE_PASSWORD`
|
||||
([#17099](https://github.com/Azure/azure-sdk-for-go/pull/17099))
|
||||
|
||||
## 1.1.0 (2022-06-07)
|
||||
|
||||
### Features Added
|
||||
* `ClientCertificateCredential` and `ClientSecretCredential` support ESTS-R. First-party
|
||||
applications can set environment variable `AZURE_REGIONAL_AUTHORITY_NAME` with a
|
||||
region name.
|
||||
([#15605](https://github.com/Azure/azure-sdk-for-go/issues/15605))
|
||||
|
||||
## 1.0.1 (2022-06-07)
|
||||
|
||||
### Other Changes
|
||||
* Upgrade `microsoft-authentication-library-for-go` requirement to v0.5.1
|
||||
([#18176](https://github.com/Azure/azure-sdk-for-go/issues/18176))
|
||||
|
||||
## 1.0.0 (2022-05-12)
|
||||
|
||||
### Features Added
|
||||
* `DefaultAzureCredential` reads environment variable `AZURE_CLIENT_ID` for the
|
||||
client ID of a user-assigned managed identity
|
||||
([#17293](https://github.com/Azure/azure-sdk-for-go/pull/17293))
|
||||
|
||||
### Breaking Changes
|
||||
* Removed `AuthorizationCodeCredential`. Use `InteractiveBrowserCredential` instead
|
||||
to authenticate a user with the authorization code flow.
|
||||
* Instances of `AuthenticationFailedError` are now returned by pointer.
|
||||
* `GetToken()` returns `azcore.AccessToken` by value
|
||||
|
||||
### Bugs Fixed
|
||||
* `AzureCLICredential` panics after receiving an unexpected error type
|
||||
([#17490](https://github.com/Azure/azure-sdk-for-go/issues/17490))
|
||||
|
||||
### Other Changes
|
||||
* `GetToken()` returns an error when the caller specifies no scope
|
||||
* Updated to the latest versions of `golang.org/x/crypto`, `azcore` and `internal`
|
||||
|
||||
## 0.14.0 (2022-04-05)
|
||||
|
||||
### Breaking Changes
|
||||
* This module now requires Go 1.18
|
||||
* Removed `AuthorityHost`. Credentials are now configured for sovereign or private
|
||||
clouds with the API in `azcore/cloud`, for example:
|
||||
```go
|
||||
// before
|
||||
opts := azidentity.ClientSecretCredentialOptions{AuthorityHost: azidentity.AzureGovernment}
|
||||
cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, secret, &opts)
|
||||
|
||||
// after
|
||||
import "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
|
||||
|
||||
opts := azidentity.ClientSecretCredentialOptions{}
|
||||
opts.Cloud = cloud.AzureGovernment
|
||||
cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, secret, &opts)
|
||||
```
|
||||
|
||||
## 0.13.2 (2022-03-08)
|
||||
|
||||
### Bugs Fixed
|
||||
* Prevented a data race in `DefaultAzureCredential` and `ChainedTokenCredential`
|
||||
([#17144](https://github.com/Azure/azure-sdk-for-go/issues/17144))
|
||||
|
||||
### Other Changes
|
||||
* Upgraded App Service managed identity version from 2017-09-01 to 2019-08-01
|
||||
([#17086](https://github.com/Azure/azure-sdk-for-go/pull/17086))
|
||||
|
||||
## 0.13.1 (2022-02-08)
|
||||
|
||||
### Features Added
|
||||
* `EnvironmentCredential` supports certificate SNI authentication when
|
||||
`AZURE_CLIENT_SEND_CERTIFICATE_CHAIN` is "true".
|
||||
([#16851](https://github.com/Azure/azure-sdk-for-go/pull/16851))
|
||||
|
||||
### Bugs Fixed
|
||||
* `ManagedIdentityCredential.GetToken()` now returns an error when configured for
|
||||
a user assigned identity in Azure Cloud Shell (which doesn't support such identities)
|
||||
([#16946](https://github.com/Azure/azure-sdk-for-go/pull/16946))
|
||||
|
||||
### Other Changes
|
||||
* `NewDefaultAzureCredential()` logs non-fatal errors. These errors are also included in the
|
||||
error returned by `DefaultAzureCredential.GetToken()` when it's unable to acquire a token
|
||||
from any source. ([#15923](https://github.com/Azure/azure-sdk-for-go/issues/15923))
|
||||
|
||||
## 0.13.0 (2022-01-11)
|
||||
|
||||
### Breaking Changes
|
||||
* Replaced `AuthenticationFailedError.RawResponse()` with a field having the same name
|
||||
* Unexported `CredentialUnavailableError`
|
||||
* Instances of `ChainedTokenCredential` will now skip looping through the list of source credentials and re-use the first successful credential on subsequent calls to `GetToken`.
|
||||
* If `ChainedTokenCredentialOptions.RetrySources` is true, `ChainedTokenCredential` will continue to try all of the originally provided credentials each time the `GetToken` method is called.
|
||||
* `ChainedTokenCredential.successfulCredential` will contain a reference to the last successful credential.
|
||||
* `DefaultAzureCredenial` will also re-use the first successful credential on subsequent calls to `GetToken`.
|
||||
* `DefaultAzureCredential.chain.successfulCredential` will also contain a reference to the last successful credential.
|
||||
|
||||
### Other Changes
|
||||
* `ManagedIdentityCredential` no longer probes IMDS before requesting a token
|
||||
from it. Also, an error response from IMDS no longer disables a credential
|
||||
instance. Following an error, a credential instance will continue to send
|
||||
requests to IMDS as necessary.
|
||||
* Adopted MSAL for user and service principal authentication
|
||||
* Updated `azcore` requirement to 0.21.0
|
||||
|
||||
## 0.12.0 (2021-11-02)
|
||||
### Breaking Changes
|
||||
* Raised minimum go version to 1.16
|
||||
* Removed `NewAuthenticationPolicy()` from credentials. Clients should instead use azcore's
|
||||
`runtime.NewBearerTokenPolicy()` to construct a bearer token authorization policy.
|
||||
* The `AuthorityHost` field in credential options structs is now a custom type,
|
||||
`AuthorityHost`, with underlying type `string`
|
||||
* `NewChainedTokenCredential` has a new signature to accommodate a placeholder
|
||||
options struct:
|
||||
```go
|
||||
// before
|
||||
cred, err := NewChainedTokenCredential(credA, credB)
|
||||
|
||||
// after
|
||||
cred, err := NewChainedTokenCredential([]azcore.TokenCredential{credA, credB}, nil)
|
||||
```
|
||||
* Removed `ExcludeAzureCLICredential`, `ExcludeEnvironmentCredential`, and `ExcludeMSICredential`
|
||||
from `DefaultAzureCredentialOptions`
|
||||
* `NewClientCertificateCredential` requires a `[]*x509.Certificate` and `crypto.PrivateKey` instead of
|
||||
a path to a certificate file. Added `ParseCertificates` to simplify getting these in common cases:
|
||||
```go
|
||||
// before
|
||||
cred, err := NewClientCertificateCredential("tenant", "client-id", "/cert.pem", nil)
|
||||
|
||||
// after
|
||||
certData, err := os.ReadFile("/cert.pem")
|
||||
certs, key, err := ParseCertificates(certData, password)
|
||||
cred, err := NewClientCertificateCredential(tenantID, clientID, certs, key, nil)
|
||||
```
|
||||
* Removed `InteractiveBrowserCredentialOptions.ClientSecret` and `.Port`
|
||||
* Removed `AADAuthenticationFailedError`
|
||||
* Removed `id` parameter of `NewManagedIdentityCredential()`. User assigned identities are now
|
||||
specified by `ManagedIdentityCredentialOptions.ID`:
|
||||
```go
|
||||
// before
|
||||
cred, err := NewManagedIdentityCredential("client-id", nil)
|
||||
// or, for a resource ID
|
||||
opts := &ManagedIdentityCredentialOptions{ID: ResourceID}
|
||||
cred, err := NewManagedIdentityCredential("/subscriptions/...", opts)
|
||||
|
||||
// after
|
||||
clientID := ClientID("7cf7db0d-...")
|
||||
opts := &ManagedIdentityCredentialOptions{ID: clientID}
|
||||
// or, for a resource ID
|
||||
resID: ResourceID("/subscriptions/...")
|
||||
opts := &ManagedIdentityCredentialOptions{ID: resID}
|
||||
cred, err := NewManagedIdentityCredential(opts)
|
||||
```
|
||||
* `DeviceCodeCredentialOptions.UserPrompt` has a new type: `func(context.Context, DeviceCodeMessage) error`
|
||||
* Credential options structs now embed `azcore.ClientOptions`. In addition to changing literal initialization
|
||||
syntax, this change renames `HTTPClient` fields to `Transport`.
|
||||
* Renamed `LogCredential` to `EventCredential`
|
||||
* `AzureCLICredential` no longer reads the environment variable `AZURE_CLI_PATH`
|
||||
* `NewManagedIdentityCredential` no longer reads environment variables `AZURE_CLIENT_ID` and
|
||||
`AZURE_RESOURCE_ID`. Use `ManagedIdentityCredentialOptions.ID` instead.
|
||||
* Unexported `AuthenticationFailedError` and `CredentialUnavailableError` structs. In their place are two
|
||||
interfaces having the same names.
|
||||
|
||||
### Bugs Fixed
|
||||
* `AzureCLICredential.GetToken` no longer mutates its `opts.Scopes`
|
||||
|
||||
### Features Added
|
||||
* Added connection configuration options to `DefaultAzureCredentialOptions`
|
||||
* `AuthenticationFailedError.RawResponse()` returns the HTTP response motivating the error,
|
||||
if available
|
||||
|
||||
### Other Changes
|
||||
* `NewDefaultAzureCredential()` returns `*DefaultAzureCredential` instead of `*ChainedTokenCredential`
|
||||
* Added `TenantID` field to `DefaultAzureCredentialOptions` and `AzureCLICredentialOptions`
|
||||
|
||||
## 0.11.0 (2021-09-08)
|
||||
### Breaking Changes
|
||||
* Unexported `AzureCLICredentialOptions.TokenProvider` and its type,
|
||||
`AzureCLITokenProvider`
|
||||
|
||||
### Bug Fixes
|
||||
* `ManagedIdentityCredential.GetToken` returns `CredentialUnavailableError`
|
||||
when IMDS has no assigned identity, signaling `DefaultAzureCredential` to
|
||||
try other credentials
|
||||
|
||||
|
||||
## 0.10.0 (2021-08-30)
|
||||
### Breaking Changes
|
||||
* Update based on `azcore` refactor [#15383](https://github.com/Azure/azure-sdk-for-go/pull/15383)
|
||||
|
||||
## 0.9.3 (2021-08-20)
|
||||
|
||||
### Bugs Fixed
|
||||
* `ManagedIdentityCredential.GetToken` no longer mutates its `opts.Scopes`
|
||||
|
||||
### Other Changes
|
||||
* Bumps version of `azcore` to `v0.18.1`
|
||||
|
||||
|
||||
## 0.9.2 (2021-07-23)
|
||||
### Features Added
|
||||
* Adding support for Service Fabric environment in `ManagedIdentityCredential`
|
||||
* Adding an option for using a resource ID instead of client ID in `ManagedIdentityCredential`
|
||||
|
||||
|
||||
## 0.9.1 (2021-05-24)
|
||||
### Features Added
|
||||
* Add LICENSE.txt and bump version information
|
||||
|
||||
|
||||
## 0.9.0 (2021-05-21)
|
||||
### Features Added
|
||||
* Add support for authenticating in Azure Stack environments
|
||||
* Enable user assigned identities for the IMDS scenario in `ManagedIdentityCredential`
|
||||
* Add scope to resource conversion in `GetToken()` on `ManagedIdentityCredential`
|
||||
|
||||
|
||||
## 0.8.0 (2021-01-20)
|
||||
### Features Added
|
||||
* Updating documentation
|
||||
|
||||
|
||||
## 0.7.1 (2021-01-04)
|
||||
### Features Added
|
||||
* Adding port option to `InteractiveBrowserCredential`
|
||||
|
||||
|
||||
## 0.7.0 (2020-12-11)
|
||||
### Features Added
|
||||
* Add `redirectURI` parameter back to authentication code flow
|
||||
|
||||
|
||||
## 0.6.1 (2020-12-09)
|
||||
### Features Added
|
||||
* Updating query parameter in `ManagedIdentityCredential` and updating datetime string for parsing managed identity access tokens.
|
||||
|
||||
|
||||
## 0.6.0 (2020-11-16)
|
||||
### Features Added
|
||||
* Remove `RedirectURL` parameter from auth code flow to align with the MSAL implementation which relies on the native client redirect URL.
|
||||
|
||||
|
||||
## 0.5.0 (2020-10-30)
|
||||
### Features Added
|
||||
* Flattening credential options
|
||||
|
||||
|
||||
## 0.4.3 (2020-10-21)
|
||||
### Features Added
|
||||
* Adding Azure Arc support in `ManagedIdentityCredential`
|
||||
|
||||
|
||||
## 0.4.2 (2020-10-16)
|
||||
### Features Added
|
||||
* Typo fixes
|
||||
|
||||
|
||||
## 0.4.1 (2020-10-16)
|
||||
### Features Added
|
||||
* Ensure authority hosts are only HTTPs
|
||||
|
||||
|
||||
## 0.4.0 (2020-10-16)
|
||||
### Features Added
|
||||
* Adding options structs for credentials
|
||||
|
||||
|
||||
## 0.3.0 (2020-10-09)
|
||||
### Features Added
|
||||
* Update `DeviceCodeCredential` callback
|
||||
|
||||
|
||||
## 0.2.2 (2020-10-09)
|
||||
### Features Added
|
||||
* Add `AuthorizationCodeCredential`
|
||||
|
||||
|
||||
## 0.2.1 (2020-10-06)
|
||||
### Features Added
|
||||
* Add `InteractiveBrowserCredential`
|
||||
|
||||
|
||||
## 0.2.0 (2020-09-11)
|
||||
### Features Added
|
||||
* Refactor `azidentity` on top of `azcore` refactor
|
||||
* Updated policies to conform to `policy.Policy` interface changes.
|
||||
* Updated non-retriable errors to conform to `azcore.NonRetriableError`.
|
||||
* Fixed calls to `Request.SetBody()` to include content type.
|
||||
* Switched endpoints to string types and removed extra parsing code.
|
||||
|
||||
|
||||
## 0.1.1 (2020-09-02)
|
||||
### Features Added
|
||||
* Add `AzureCLICredential` to `DefaultAzureCredential` chain
|
||||
|
||||
|
||||
## 0.1.0 (2020-07-23)
|
||||
### Features Added
|
||||
* Initial Release. Azure Identity library that provides Microsoft Entra token authentication support for the SDK.
|
||||
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
@@ -1,307 +0,0 @@
|
||||
# Migrating from autorest/adal to azidentity
|
||||
|
||||
`azidentity` provides Microsoft Entra ID ([formerly Azure Active Directory](https://learn.microsoft.com/entra/fundamentals/new-name)) authentication for the newest Azure SDK modules (`github.com/azure-sdk-for-go/sdk/...`). Older Azure SDK packages (`github.com/azure-sdk-for-go/services/...`) use types from `github.com/go-autorest/autorest/adal` instead.
|
||||
|
||||
This guide shows common authentication code using `autorest/adal` and its equivalent using `azidentity`.
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [Acquire a token](#acquire-a-token)
|
||||
- [Client certificate authentication](#client-certificate-authentication)
|
||||
- [Client secret authentication](#client-secret-authentication)
|
||||
- [Configuration](#configuration)
|
||||
- [Device code authentication](#device-code-authentication)
|
||||
- [Managed identity](#managed-identity)
|
||||
- [Use azidentity credentials with older packages](#use-azidentity-credentials-with-older-packages)
|
||||
|
||||
## Configuration
|
||||
|
||||
### `autorest/adal`
|
||||
|
||||
Token providers require a token audience (resource identifier) and an instance of `adal.OAuthConfig`, which requires a Microsoft Entra endpoint and tenant:
|
||||
|
||||
```go
|
||||
import "github.com/Azure/go-autorest/autorest/adal"
|
||||
|
||||
oauthCfg, err := adal.NewOAuthConfig("https://login.chinacloudapi.cn", tenantID)
|
||||
handle(err)
|
||||
|
||||
spt, err := adal.NewServicePrincipalTokenWithSecret(
|
||||
*oauthCfg, clientID, "https://management.chinacloudapi.cn/", &adal.ServicePrincipalTokenSecret{ClientSecret: secret},
|
||||
)
|
||||
```
|
||||
|
||||
### `azidentity`
|
||||
|
||||
A credential instance can acquire tokens for any audience. The audience for each token is determined by the client requesting it. Credentials require endpoint configuration only for sovereign or private clouds. The `azcore/cloud` package has predefined configuration for sovereign clouds such as Azure China:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
)
|
||||
|
||||
clientOpts := azcore.ClientOptions{Cloud: cloud.AzureChina}
|
||||
|
||||
cred, err := azidentity.NewClientSecretCredential(
|
||||
tenantID, clientID, secret, &azidentity.ClientSecretCredentialOptions{ClientOptions: clientOpts},
|
||||
)
|
||||
handle(err)
|
||||
```
|
||||
|
||||
## Client secret authentication
|
||||
|
||||
### `autorest/adal`
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-06-01/subscriptions"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
)
|
||||
|
||||
oauthCfg, err := adal.NewOAuthConfig("https://login.microsoftonline.com", tenantID)
|
||||
handle(err)
|
||||
spt, err := adal.NewServicePrincipalTokenWithSecret(
|
||||
*oauthCfg, clientID, "https://management.azure.com/", &adal.ServicePrincipalTokenSecret{ClientSecret: secret},
|
||||
)
|
||||
handle(err)
|
||||
|
||||
client := subscriptions.NewClient()
|
||||
client.Authorizer = autorest.NewBearerAuthorizer(spt)
|
||||
```
|
||||
|
||||
### `azidentity`
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions"
|
||||
)
|
||||
|
||||
cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, secret, nil)
|
||||
handle(err)
|
||||
|
||||
client, err := armsubscriptions.NewClient(cred, nil)
|
||||
handle(err)
|
||||
```
|
||||
|
||||
## Client certificate authentication
|
||||
|
||||
### `autorest/adal`
|
||||
|
||||
```go
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-06-01/subscriptions"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
)
|
||||
certData, err := os.ReadFile("./example.pfx")
|
||||
handle(err)
|
||||
|
||||
certificate, rsaPrivateKey, err := decodePkcs12(certData, "")
|
||||
handle(err)
|
||||
|
||||
oauthCfg, err := adal.NewOAuthConfig("https://login.microsoftonline.com", tenantID)
|
||||
handle(err)
|
||||
|
||||
spt, err := adal.NewServicePrincipalTokenFromCertificate(
|
||||
*oauthConfig, clientID, certificate, rsaPrivateKey, "https://management.azure.com/",
|
||||
)
|
||||
|
||||
client := subscriptions.NewClient()
|
||||
client.Authorizer = autorest.NewBearerAuthorizer(spt)
|
||||
```
|
||||
|
||||
### `azidentity`
|
||||
|
||||
```go
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions"
|
||||
)
|
||||
|
||||
certData, err := os.ReadFile("./example.pfx")
|
||||
handle(err)
|
||||
|
||||
certs, key, err := azidentity.ParseCertificates(certData, nil)
|
||||
handle(err)
|
||||
|
||||
cred, err = azidentity.NewClientCertificateCredential(tenantID, clientID, certs, key, nil)
|
||||
handle(err)
|
||||
|
||||
client, err := armsubscriptions.NewClient(cred, nil)
|
||||
handle(err)
|
||||
```
|
||||
|
||||
## Managed identity
|
||||
|
||||
### `autorest/adal`
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-06-01/subscriptions"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
)
|
||||
|
||||
spt, err := adal.NewServicePrincipalTokenFromManagedIdentity("https://management.azure.com/", nil)
|
||||
handle(err)
|
||||
|
||||
client := subscriptions.NewClient()
|
||||
client.Authorizer = autorest.NewBearerAuthorizer(spt)
|
||||
```
|
||||
|
||||
### `azidentity`
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions"
|
||||
)
|
||||
|
||||
cred, err := azidentity.NewManagedIdentityCredential(nil)
|
||||
handle(err)
|
||||
|
||||
client, err := armsubscriptions.NewClient(cred, nil)
|
||||
handle(err)
|
||||
```
|
||||
|
||||
### User-assigned identities
|
||||
|
||||
`autorest/adal`:
|
||||
|
||||
```go
|
||||
import "github.com/Azure/go-autorest/autorest/adal"
|
||||
|
||||
opts := &adal.ManagedIdentityOptions{ClientID: "..."}
|
||||
spt, err := adal.NewServicePrincipalTokenFromManagedIdentity("https://management.azure.com/")
|
||||
handle(err)
|
||||
```
|
||||
|
||||
`azidentity`:
|
||||
|
||||
```go
|
||||
import "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
|
||||
opts := azidentity.ManagedIdentityCredentialOptions{ID: azidentity.ClientID("...")}
|
||||
cred, err := azidentity.NewManagedIdentityCredential(&opts)
|
||||
handle(err)
|
||||
```
|
||||
|
||||
## Device code authentication
|
||||
|
||||
### `autorest/adal`
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-06-01/subscriptions"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
)
|
||||
|
||||
oauthClient := &http.Client{}
|
||||
oauthCfg, err := adal.NewOAuthConfig("https://login.microsoftonline.com", tenantID)
|
||||
handle(err)
|
||||
resource := "https://management.azure.com/"
|
||||
deviceCode, err := adal.InitiateDeviceAuth(oauthClient, *oauthCfg, clientID, resource)
|
||||
handle(err)
|
||||
|
||||
// display instructions, wait for the user to authenticate
|
||||
fmt.Println(*deviceCode.Message)
|
||||
token, err := adal.WaitForUserCompletion(oauthClient, deviceCode)
|
||||
handle(err)
|
||||
|
||||
spt, err := adal.NewServicePrincipalTokenFromManualToken(*oauthCfg, clientID, resource, *token)
|
||||
handle(err)
|
||||
|
||||
client := subscriptions.NewClient()
|
||||
client.Authorizer = autorest.NewBearerAuthorizer(spt)
|
||||
```
|
||||
|
||||
### `azidentity`
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions"
|
||||
)
|
||||
|
||||
cred, err := azidentity.NewDeviceCodeCredential(nil)
|
||||
handle(err)
|
||||
|
||||
client, err := armsubscriptions.NewSubscriptionsClient(cred, nil)
|
||||
handle(err)
|
||||
```
|
||||
|
||||
`azidentity.DeviceCodeCredential` will guide a user through authentication, printing instructions to the console by default. The user prompt is customizable. For more information, see the [package documentation](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#DeviceCodeCredential).
|
||||
|
||||
## Acquire a token
|
||||
|
||||
### `autorest/adal`
|
||||
|
||||
```go
|
||||
import "github.com/Azure/go-autorest/autorest/adal"
|
||||
|
||||
oauthCfg, err := adal.NewOAuthConfig("https://login.microsoftonline.com", tenantID)
|
||||
handle(err)
|
||||
|
||||
spt, err := adal.NewServicePrincipalTokenWithSecret(
|
||||
*oauthCfg, clientID, "https://vault.azure.net", &adal.ServicePrincipalTokenSecret{ClientSecret: secret},
|
||||
)
|
||||
|
||||
err = spt.Refresh()
|
||||
if err == nil {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
### `azidentity`
|
||||
|
||||
In ordinary usage, application code doesn't need to request tokens from credentials directly. Azure SDK clients handle token acquisition and refreshing internally. However, applications may call `GetToken()` to do so. All credential types have this method.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
)
|
||||
|
||||
cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, secret, nil)
|
||||
handle(err)
|
||||
|
||||
tk, err := cred.GetToken(
|
||||
context.TODO(), policy.TokenRequestOptions{Scopes: []string{"https://vault.azure.net/.default"}},
|
||||
)
|
||||
if err == nil {
|
||||
token := tk.Token
|
||||
}
|
||||
```
|
||||
|
||||
Note that `azidentity` credentials use the Microsoft Entra endpoint, which requires OAuth 2 scopes instead of the resource identifiers `autorest/adal` expects. For more information, see [Microsoft Entra ID documentation](https://learn.microsoft.com/entra/identity-platform/permissions-consent-overview).
|
||||
|
||||
## Use azidentity credentials with older packages
|
||||
|
||||
The [azidext module](https://pkg.go.dev/github.com/jongio/azidext/go/azidext) provides an adapter for `azidentity` credential types. The adapter enables using the credential types with older Azure SDK clients. For example:
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-06-01/subscriptions"
|
||||
"github.com/jongio/azidext/go/azidext"
|
||||
)
|
||||
|
||||
cred, err := azidentity.NewClientSecretCredential(tenantID, clientID, secret, nil)
|
||||
handle(err)
|
||||
|
||||
client := subscriptions.NewClient()
|
||||
client.Authorizer = azidext.NewTokenCredentialAdapter(cred, []string{"https://management.azure.com//.default"})
|
||||
```
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user