Update dependencies

This commit is contained in:
github-actions 2024-02-09 07:28:15 +00:00
parent 54344d0c7e
commit bc33010062
172 changed files with 12857 additions and 7053 deletions

48
go.mod
View File

@ -4,20 +4,20 @@ go 1.21
require (
cloud.google.com/go/compute/metadata v0.2.3
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3 v3.0.0-beta.2
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute v1.0.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.1
github.com/MakeNowJust/heredoc/v2 v2.0.1
github.com/Masterminds/sprig/v3 v3.2.3
github.com/apparentlymart/go-cidr v1.1.0
github.com/aws/amazon-ec2-instance-selector/v2 v2.4.1
github.com/aws/aws-sdk-go v1.50.10
github.com/aws/aws-sdk-go v1.50.14
github.com/blang/semver/v4 v4.0.0
github.com/cert-manager/cert-manager v1.14.1
github.com/cert-manager/cert-manager v1.14.2
github.com/digitalocean/godo v1.108.0
github.com/go-ini/ini v1.67.0
github.com/go-logr/logr v1.4.1
@ -34,7 +34,7 @@ require (
github.com/pelletier/go-toml v1.9.5
github.com/pkg/sftp v1.13.6
github.com/prometheus/client_golang v1.18.0
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.23
github.com/sergi/go-diff v1.3.1
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
@ -42,20 +42,20 @@ require (
github.com/spotinst/spotinst-sdk-go v1.171.0
github.com/stretchr/testify v1.8.4
github.com/weaveworks/mesh v0.0.0-20191105120815-58dbcc3e8e63
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0
go.opentelemetry.io/otel v1.22.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0
go.opentelemetry.io/otel/sdk v1.22.0
go.opentelemetry.io/otel/trace v1.22.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0
go.opentelemetry.io/otel v1.23.1
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.23.1
go.opentelemetry.io/otel/sdk v1.23.1
go.opentelemetry.io/otel/trace v1.23.1
go.opentelemetry.io/proto/otlp v1.1.0
go.uber.org/multierr v1.11.0
golang.org/x/crypto v0.18.0
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
golang.org/x/net v0.20.0
golang.org/x/oauth2 v0.16.0
golang.org/x/crypto v0.19.0
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3
golang.org/x/net v0.21.0
golang.org/x/oauth2 v0.17.0
golang.org/x/sync v0.6.0
golang.org/x/sys v0.16.0
google.golang.org/api v0.161.0
golang.org/x/sys v0.17.0
google.golang.org/api v0.163.0
google.golang.org/grpc v1.61.0
google.golang.org/protobuf v1.32.0
gopkg.in/gcfg.v1 v1.2.3
@ -83,9 +83,9 @@ require (
require (
cloud.google.com/go/compute v1.23.3 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 // indirect
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.25.0 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
@ -124,7 +124,7 @@ require (
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/swag v0.22.7 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/golang-jwt/jwt/v5 v5.2.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.0.1 // indirect
@ -195,7 +195,7 @@ require (
github.com/pborman/uuid v1.2.1 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
@ -216,17 +216,17 @@ require (
github.com/vbatts/tar-split v0.11.3 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel/metric v1.22.0 // indirect
go.opentelemetry.io/otel/metric v1.23.1 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/term v0.16.0 // indirect
golang.org/x/term v0.17.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.17.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect

105
go.sum
View File

@ -5,30 +5,34 @@ cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGB
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 h1:lGlwhPtrX6EVml1hO0ivjkUxsSyl4dsiw9qcA1k/3IQ=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1/go.mod h1:RKUqNu35KJYcVG/fqTRqmuXJZYNhYkBrnC/hX7yGbTA=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 h1:6oNBlSdi1QqM1PNW7FPA6xOGA5UNsXnkaYZz9vdPGhA=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2 h1:c4k2FIYIh4xtwqrQwV0Ct1v5+ehlNXj5NI/MWVsiTkQ=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2/go.mod h1:5FDJtLEO/GxwNgUxbwrY3LP0pEoThTQJtk2oysdXHxM=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3 v3.0.0-beta.2 h1:qiir/pptnHqp6hV8QwV+IExYIf6cPsXBfUDUXQ27t2Y=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v3 v3.0.0-beta.2/go.mod h1:jVRrRDLCOuif95HDYC23ADTMlvahB7tMdl519m9Iyjc=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute v1.0.0 h1:/Di3vB4sNeQ+7A8efjUVENvyB945Wruvstucqp7ZArg=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute v1.0.0/go.mod h1:gM3K25LQlsET3QR+4V74zxCsFAy0r6xMNN9n80SZn+4=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.0.0 h1:lMW1lD/17LUA5z1XTURo7LcVG2ICBPlyMHjIUrcFZNQ=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.0.0/go.mod h1:ceIuwmxDWptoW3eCqSXlnPsZFKh4X+R38dWPv7GS9Vs=
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/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/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/resources/armresources v1.0.0 h1:ECsQtyERDVz3NP3kvDOTLvbQhqWp/x9EsGKtb4ogUr8=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0/go.mod h1:s1tW/At+xHqjNFvWU4G0c0Qv33KOhvbGNj0RCTQDV8s=
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/storage/armstorage v1.5.0 h1:AifHbc4mg0x9zW52WOpKbsHaDKuRhlI7TVl47thgQ70=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0/go.mod h1:T5RfihdXtBDxt1Ch2wobif3TvzTdumDy29kahv6AV9A=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.1 h1:AMf7YbZOZIW5b66cXNHMWWT/zkjhz5+a+k/3x40EO7E=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.1/go.mod h1:uwfk06ZBcvL/g4VHNjurPfVln9NMbsk2XIZxJ+hu81k=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 h1:WpB/QDNLpMw72xHJc34BNNykqSOeEJDAWkhf0u12/Jk=
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
@ -67,8 +71,8 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aws/amazon-ec2-instance-selector/v2 v2.4.1 h1:DmxtwV+pkakkVRhxKcAgnLbxCxvT7k8DBG271dfKPZ8=
github.com/aws/amazon-ec2-instance-selector/v2 v2.4.1/go.mod h1:AEJrtkLkCkfIBIazidrVrgZqaXl+9dxI/wRgjdw+7G0=
github.com/aws/aws-sdk-go v1.50.10 h1:H3NQvqRUKG+9oysCKTIyylpkqfPA7MiBtzTnu/cIGqE=
github.com/aws/aws-sdk-go v1.50.10/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go v1.50.14 h1:m1bxKtd1lJpNnl+Owah0+UPRuS9f3GFvxBPgc8RiodE=
github.com/aws/aws-sdk-go v1.50.14/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@ -85,8 +89,8 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0Bsq
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cert-manager/cert-manager v1.14.1 h1:i5sJHfEucqpAfVjkCe3n4sO5S+6YBaN2Yu18+l/1ZMw=
github.com/cert-manager/cert-manager v1.14.1/go.mod h1:pik7K6jXfgh++lfVJ/i1HzEnDluSUtTVLXSHikj8Lho=
github.com/cert-manager/cert-manager v1.14.2 h1:C/uci6yxiCRO04PWomBbSX+T4JT58FIIpDj5SZ6Ks6I=
github.com/cert-manager/cert-manager v1.14.2/go.mod h1:pik7K6jXfgh++lfVJ/i1HzEnDluSUtTVLXSHikj8Lho=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@ -206,8 +210,8 @@ github.com/gogo/protobuf v0.0.0-20171007142547-342cbe0a0415/go.mod h1:r8qH/GZQm5
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
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/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
@ -475,8 +479,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
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.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -527,8 +531,8 @@ github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6g
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22 h1:wJrcTdddKOI8TFxs8cemnhKP2EmKy3yfUKHj3ZdfzYo=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.22/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.23 h1:zr2sP1pxJ+iPAmZipnwz+uXmpvMEJOndD9Y+F0Dn42A=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.23/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
@ -593,18 +597,18 @@ github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw=
go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y=
go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 h1:9M3+rhx7kZCIQQhQRYaZCdNu1V73tm4TvXs2ntl98C4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0/go.mod h1:noq80iT8rrHP1SfybmPiRGc9dc5M8RPmGvtwo7Oo7tc=
go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg=
go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY=
go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw=
go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0=
go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 h1:doUP+ExOpH3spVTLS0FcWGLnQrPct/hD/bCPbDRUEAU=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0/go.mod h1:rdENBZMT2OE6Ne/KLwpiXudnAsbdrdBaqBvTN8M8BgA=
go.opentelemetry.io/otel v1.23.1 h1:Za4UzOqJYS+MUczKI320AtqZHZb7EqxO00jAHE0jmQY=
go.opentelemetry.io/otel v1.23.1/go.mod h1:Td0134eafDLcTS4y+zQ26GE8u3dEuRBiBCTUIRHaikA=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.23.1 h1:o8iWeVFa1BcLtVEV0LzrCxV2/55tB3xLxADr6Kyoey4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.23.1/go.mod h1:SEVfdK4IoBnbT2FXNM/k8yC08MrfbhWk3U4ljM8B3HE=
go.opentelemetry.io/otel/metric v1.23.1 h1:PQJmqJ9u2QaJLBOELl1cxIdPcpbwzbkjfEyelTl2rlo=
go.opentelemetry.io/otel/metric v1.23.1/go.mod h1:mpG2QPlAfnK8yNhNJAxDZruU9Y1/HubbC+KyH8FaCWI=
go.opentelemetry.io/otel/sdk v1.23.1 h1:O7JmZw0h76if63LQdsBMKQDWNb5oEcOThG9IrxscV+E=
go.opentelemetry.io/otel/sdk v1.23.1/go.mod h1:LzdEVR5am1uKOOwfBWFef2DCi1nu3SA8XQxx2IerWFk=
go.opentelemetry.io/otel/trace v1.23.1 h1:4LrmmEd8AU2rFvU1zegmvqW7+kWarxtNOPyeL6HmYY8=
go.opentelemetry.io/otel/trace v1.23.1/go.mod h1:4IpnpJFwr1mo/6HL8XIPJaE9y0+u1KcVmuW7dwFSVrI=
go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI=
go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY=
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY=
@ -626,11 +630,11 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo=
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@ -658,11 +662,11 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ=
golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -690,7 +694,6 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/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-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -702,15 +705,15 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.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.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@ -741,8 +744,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
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/api v0.161.0 h1:oYzk/bs26WN10AV7iU7MVJVXBH8oCPS2hHyBiEeFoSU=
google.golang.org/api v0.161.0/go.mod h1:0mu0TpK33qnydLvWqbImq2b1eQ5FHRSDCBzAxX9ZHyw=
google.golang.org/api v0.163.0 h1:4BBDpPaSH+H28NhnX+WwjXxbRLQ7TWuEKp4BQyEjxvk=
google.golang.org/api v0.163.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
@ -750,12 +753,12 @@ google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJ
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg=
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0=
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac h1:ZL/Teoy/ZGnzyrqK/Optxxp2pmVh+fmJ97slxSRyzUg=
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k=
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM=
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe h1:bQnxqljG/wqi4NTXu2+DJ3n7APcEA882QZ1JvhQAq9o=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=

View File

@ -12,7 +12,7 @@ require (
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/octago/sflags v0.2.0
github.com/spf13/pflag v1.0.5
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3
k8s.io/api v0.29.1
k8s.io/apimachinery v0.29.1
k8s.io/client-go v0.29.1
@ -35,9 +35,9 @@ require (
filippo.io/edwards25519 v1.0.0 // indirect
github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo/helper v0.2.0 // indirect
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.1 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.29 // indirect
@ -47,7 +47,7 @@ require (
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 // indirect
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.25.0 // indirect
github.com/MakeNowJust/heredoc v1.0.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
@ -68,7 +68,7 @@ require (
github.com/aliyun/credentials-go v1.2.3 // indirect
github.com/apparentlymart/go-cidr v1.1.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go v1.50.10 // indirect
github.com/aws/aws-sdk-go v1.50.14 // indirect
github.com/aws/aws-sdk-go-v2 v1.18.1 // indirect
github.com/aws/aws-sdk-go-v2/config v1.18.27 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.13.26 // indirect
@ -140,7 +140,7 @@ require (
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
github.com/golang-jwt/jwt/v5 v5.2.0 // indirect
github.com/golang/glog v1.1.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
@ -204,7 +204,7 @@ require (
github.com/pborman/uuid v1.2.1 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.13.6 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
@ -256,31 +256,31 @@ require (
go.mongodb.org/mongo-driver v1.11.3 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect
go.opentelemetry.io/otel v1.22.0 // indirect
go.opentelemetry.io/otel/metric v1.22.0 // indirect
go.opentelemetry.io/otel/trace v1.22.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 // indirect
go.opentelemetry.io/otel v1.23.1 // indirect
go.opentelemetry.io/otel/metric v1.23.1 // indirect
go.opentelemetry.io/otel/trace v1.23.1 // indirect
go.step.sm/crypto v0.32.2 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.24.0 // indirect
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/crypto v0.19.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/oauth2 v0.16.0 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/oauth2 v0.17.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/term v0.16.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/term v0.17.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.17.0 // indirect
golang.org/x/tools/go/vcs v0.1.0-deprecated // indirect
google.golang.org/api v0.161.0 // indirect
google.golang.org/api v0.163.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 // indirect
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect
google.golang.org/grpc v1.61.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
gopkg.in/gcfg.v1 v1.2.3 // indirect

View File

@ -41,12 +41,12 @@ github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/alibabacloudsdkgo
github.com/Azure/azure-sdk-for-go v46.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
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.9.1 h1:lGlwhPtrX6EVml1hO0ivjkUxsSyl4dsiw9qcA1k/3IQ=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1/go.mod h1:RKUqNu35KJYcVG/fqTRqmuXJZYNhYkBrnC/hX7yGbTA=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 h1:6oNBlSdi1QqM1PNW7FPA6xOGA5UNsXnkaYZz9vdPGhA=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2 h1:c4k2FIYIh4xtwqrQwV0Ct1v5+ehlNXj5NI/MWVsiTkQ=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2/go.mod h1:5FDJtLEO/GxwNgUxbwrY3LP0pEoThTQJtk2oysdXHxM=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0 h1:AifHbc4mg0x9zW52WOpKbsHaDKuRhlI7TVl47thgQ70=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.5.0/go.mod h1:T5RfihdXtBDxt1Ch2wobif3TvzTdumDy29kahv6AV9A=
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v0.12.0 h1:4Kynh6Hn2ekyIsBgNQJb3dn1+/MyvzfUJebti2emB/A=
@ -84,8 +84,8 @@ github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+Z
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/AzureAD/microsoft-authentication-library-for-go v1.1.1 h1:WpB/QDNLpMw72xHJc34BNNykqSOeEJDAWkhf0u12/Jk=
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@ -166,8 +166,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
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/aws/aws-sdk-go v1.50.10 h1:H3NQvqRUKG+9oysCKTIyylpkqfPA7MiBtzTnu/cIGqE=
github.com/aws/aws-sdk-go v1.50.10/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go v1.50.14 h1:m1bxKtd1lJpNnl+Owah0+UPRuS9f3GFvxBPgc8RiodE=
github.com/aws/aws-sdk-go v1.50.14/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/aws/aws-sdk-go-v2 v1.7.1/go.mod h1:L5LuPC1ZgDr2xQS7AmIec/Jlc7O/Y1u2KxJyNVab250=
github.com/aws/aws-sdk-go-v2 v1.14.0/go.mod h1:ZA3Y8V0LrlWj63MQAnRHgKf/5QB//LSZCPNWlWrNGLU=
github.com/aws/aws-sdk-go-v2 v1.18.1 h1:+tefE750oAb7ZQGzla6bLkOwfcQCEtC5y2RqoqCeqKo=
@ -477,8 +477,8 @@ github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo=
github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ=
@ -806,8 +806,8 @@ github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
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.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -1044,16 +1044,16 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw=
go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y=
go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI=
go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg=
go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY=
go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw=
go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0=
go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0 h1:doUP+ExOpH3spVTLS0FcWGLnQrPct/hD/bCPbDRUEAU=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.48.0/go.mod h1:rdENBZMT2OE6Ne/KLwpiXudnAsbdrdBaqBvTN8M8BgA=
go.opentelemetry.io/otel v1.23.1 h1:Za4UzOqJYS+MUczKI320AtqZHZb7EqxO00jAHE0jmQY=
go.opentelemetry.io/otel v1.23.1/go.mod h1:Td0134eafDLcTS4y+zQ26GE8u3dEuRBiBCTUIRHaikA=
go.opentelemetry.io/otel/metric v1.23.1 h1:PQJmqJ9u2QaJLBOELl1cxIdPcpbwzbkjfEyelTl2rlo=
go.opentelemetry.io/otel/metric v1.23.1/go.mod h1:mpG2QPlAfnK8yNhNJAxDZruU9Y1/HubbC+KyH8FaCWI=
go.opentelemetry.io/otel/sdk v1.23.1 h1:O7JmZw0h76if63LQdsBMKQDWNb5oEcOThG9IrxscV+E=
go.opentelemetry.io/otel/sdk v1.23.1/go.mod h1:LzdEVR5am1uKOOwfBWFef2DCi1nu3SA8XQxx2IerWFk=
go.opentelemetry.io/otel/trace v1.23.1 h1:4LrmmEd8AU2rFvU1zegmvqW7+kWarxtNOPyeL6HmYY8=
go.opentelemetry.io/otel/trace v1.23.1/go.mod h1:4IpnpJFwr1mo/6HL8XIPJaE9y0+u1KcVmuW7dwFSVrI=
go.step.sm/crypto v0.32.2 h1:EhJpFRNgU3RaNEO3WZ62Kn2gF9NWNglNG4DvSPeuiTs=
go.step.sm/crypto v0.32.2/go.mod h1:JwarCq+Sn6N8IbRSKfSJfjUNKfO8c4N1mcNxYXuxXzc=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@ -1093,8 +1093,8 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -1103,8 +1103,8 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 h1:/RIbNt/Zr7rVhIkQhooTxCxFcdWLGIKnZA4IXNFSrvo=
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -1165,15 +1165,15 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ=
golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -1227,7 +1227,6 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/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-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -1242,8 +1241,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -1252,8 +1251,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1332,8 +1331,8 @@ google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.161.0 h1:oYzk/bs26WN10AV7iU7MVJVXBH8oCPS2hHyBiEeFoSU=
google.golang.org/api v0.161.0/go.mod h1:0mu0TpK33qnydLvWqbImq2b1eQ5FHRSDCBzAxX9ZHyw=
google.golang.org/api v0.163.0 h1:4BBDpPaSH+H28NhnX+WwjXxbRLQ7TWuEKp4BQyEjxvk=
google.golang.org/api v0.163.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -1355,12 +1354,12 @@ google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvx
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917 h1:nz5NESFLZbJGPFxDT/HCn+V1mZ8JGNoY4nUpmW/Y2eg=
google.golang.org/genproto v0.0.0-20240102182953-50ed04b92917/go.mod h1:pZqR+glSb11aJ+JQcczCvgf47+duRuzNSKqE8YAQnV0=
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac h1:ZL/Teoy/ZGnzyrqK/Optxxp2pmVh+fmJ97slxSRyzUg=
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k=
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM=
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe h1:bQnxqljG/wqi4NTXu2+DJ3n7APcEA882QZ1JvhQAq9o=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=

View File

@ -1,5 +1,15 @@
# Release History
## 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

View File

@ -125,46 +125,11 @@ func (req *Request) OperationValue(value interface{}) bool {
// 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.
// 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 {
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 {
req.req.Header.Set(shared.HeaderContentType, contentType)
}
return nil
// 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.
@ -211,3 +176,48 @@ type PolicyFunc func(*Request) (*http.Response, error)
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
}

View File

@ -40,5 +40,5 @@ const (
Module = "azcore"
// Version is the semantic version (see http://semver.org) of this module.
Version = "v1.9.1"
Version = "v1.9.2"
)

View File

@ -97,7 +97,8 @@ func EncodeByteArray(v []byte, format Base64Encoding) string {
func MarshalAsByteArray(req *policy.Request, v []byte, format Base64Encoding) error {
// send as a JSON string
encode := fmt.Sprintf("\"%s\"", EncodeByteArray(v, format))
return req.SetBody(exported.NopCloser(strings.NewReader(encode)), shared.ContentTypeAppJSON)
// 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.
@ -106,7 +107,8 @@ func MarshalAsJSON(req *policy.Request, v interface{}) error {
if err != nil {
return fmt.Errorf("error marshalling type %T: %s", v, err)
}
return req.SetBody(exported.NopCloser(bytes.NewReader(b)), shared.ContentTypeAppJSON)
// 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.

View File

@ -1,5 +1,38 @@
# Release History
## 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
@ -94,14 +127,14 @@
### Features Added
* By default, credentials set client capability "CP1" to enable support for
[Continuous Access Evaluation (CAE)](https://docs.microsoft.com/azure/active-directory/develop/app-resilience-continuous-access-evaluation).
This indicates to Azure Active Directory that your application can handle CAE claims challenges.
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 Azure AD instance metadata by setting the `DisableInstanceDiscovery`
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
@ -454,4 +487,4 @@
## 0.1.0 (2020-07-23)
### Features Added
* Initial Release. Azure Identity library that provides Azure Active Directory token authentication support for the SDK.
* Initial Release. Azure Identity library that provides Microsoft Entra token authentication support for the SDK.

View File

@ -1,6 +1,6 @@
# Migrating from autorest/adal to azidentity
`azidentity` provides Azure Active Directory (Azure AD) 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.
`azidentity` provides Microsoft Entra ID ([formerly Azure Active Directory](https://learn.microsoft.com/azure/active-directory/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`.
@ -18,7 +18,7 @@ This guide shows common authentication code using `autorest/adal` and its equiva
### `autorest/adal`
Token providers require a token audience (resource identifier) and an instance of `adal.OAuthConfig`, which requires an Azure AD endpoint and tenant:
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"
@ -284,7 +284,7 @@ if err == nil {
}
```
Note that `azidentity` credentials use the Azure AD v2.0 endpoint, which requires OAuth 2 scopes instead of the resource identifiers `autorest/adal` expects. For more information, see [Azure AD documentation](https://docs.microsoft.com/azure/active-directory/develop/v2-permissions-and-consent).
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/azure/active-directory/develop/permissions-consent-overview).
## Use azidentity credentials with older packages

View File

@ -1,9 +1,9 @@
# Azure Identity Client Module for Go
The Azure Identity module provides Azure Active Directory (Azure AD) token authentication support across the Azure SDK. It includes a set of `TokenCredential` implementations, which can be used with Azure SDK clients supporting token authentication.
The Azure Identity module provides Microsoft Entra ID ([formerly Azure Active Directory](https://learn.microsoft.com/azure/active-directory/fundamentals/new-name)) token authentication support across the Azure SDK. It includes a set of `TokenCredential` implementations, which can be used with Azure SDK clients supporting token authentication.
[![PkgGoDev](https://pkg.go.dev/badge/github.com/Azure/azure-sdk-for-go/sdk/azidentity)](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity)
| [Azure Active Directory documentation](https://docs.microsoft.com/azure/active-directory/)
| [Microsoft Entra ID documentation](https://learn.microsoft.com/azure/active-directory/)
| [Source code](https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/azidentity)
# Getting started
@ -35,6 +35,12 @@ signed in to the [Azure CLI](https://docs.microsoft.com/cli/azure). To sign in t
When no default browser is available, `az login` will use the device code
authentication flow. This can also be selected manually by running `az login --use-device-code`.
#### Authenticate via the Azure Developer CLI
Developers coding outside of an IDE can also use the [Azure Developer CLI](https://aka.ms/azure-dev) to authenticate. Applications using the `DefaultAzureCredential` or the `AzureDeveloperCLICredential` can use the account logged in to the Azure Developer CLI to authenticate calls in their application when running locally.
To authenticate with the Azure Developer CLI, run `azd auth login`. On a system with a default web browser, `azd` will launch the browser to authenticate. On systems without a default web browser, run `azd auth login --use-device-code` to use the device code authentication flow.
## Key concepts
### Credentials
@ -44,9 +50,7 @@ service client to authenticate requests. Service clients across the Azure SDK
accept a credential instance when they are constructed, and use that credential
to authenticate requests.
The `azidentity` module focuses on OAuth authentication with Azure Active
Directory (AAD). It offers a variety of credential types capable of acquiring
an Azure AD access token. See [Credential Types](#credential-types "Credential Types") for a list of this module's credential types.
The `azidentity` module focuses on OAuth authentication with Microsoft Entra ID. It offers a variety of credential types capable of acquiring a Microsoft Entra access token. See [Credential Types](#credential-types "Credential Types") for a list of this module's credential types.
### DefaultAzureCredential
@ -58,6 +62,7 @@ an Azure AD access token. See [Credential Types](#credential-types "Credential T
1. **Workload Identity** - If the app is deployed on Kubernetes with environment variables set by the workload identity webhook, `DefaultAzureCredential` will authenticate the configured identity.
1. **Managed Identity** - If the app is deployed to an Azure host with managed identity enabled, `DefaultAzureCredential` will authenticate with it.
1. **Azure CLI** - If a user or service principal has authenticated via the Azure CLI `az login` command, `DefaultAzureCredential` will authenticate that identity.
1. **Azure Developer CLI** - If the developer has authenticated via the Azure Developer CLI `azd auth login` command, the `DefaultAzureCredential` will authenticate with that account.
> Note: `DefaultAzureCredential` is intended to simplify getting started with the SDK by handling common scenarios with reasonable default behaviors. Developers who want more control or whose scenario isn't served by the default settings should use other credential types.
@ -152,6 +157,7 @@ client := armresources.NewResourceGroupsClient("subscription ID", chain, nil)
|Credential|Usage
|-|-
|[AzureCLICredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#AzureCLICredential)|Authenticate as the user signed in to the Azure CLI
|[`AzureDeveloperCLICredential`](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#AzureDeveloperCLICredential)|Authenticates as the user signed in to the Azure Developer CLI
## Environment Variables
@ -161,16 +167,16 @@ client := armresources.NewResourceGroupsClient("subscription ID", chain, nil)
|variable name|value
|-|-
|`AZURE_CLIENT_ID`|ID of an Azure Active Directory application
|`AZURE_TENANT_ID`|ID of the application's Azure Active Directory tenant
|`AZURE_CLIENT_ID`|ID of a Microsoft Entra application
|`AZURE_TENANT_ID`|ID of the application's Microsoft Entra tenant
|`AZURE_CLIENT_SECRET`|one of the application's client secrets
#### Service principal with certificate
|variable name|value
|-|-
|`AZURE_CLIENT_ID`|ID of an Azure Active Directory application
|`AZURE_TENANT_ID`|ID of the application's Azure Active Directory tenant
|`AZURE_CLIENT_ID`|ID of a Microsoft Entra application
|`AZURE_TENANT_ID`|ID of the application's Microsoft Entra tenant
|`AZURE_CLIENT_CERTIFICATE_PATH`|path to a certificate file including private key
|`AZURE_CLIENT_CERTIFICATE_PASSWORD`|password of the certificate file, if any
@ -178,22 +184,30 @@ client := armresources.NewResourceGroupsClient("subscription ID", chain, nil)
|variable name|value
|-|-
|`AZURE_CLIENT_ID`|ID of an Azure Active Directory application
|`AZURE_CLIENT_ID`|ID of a Microsoft Entra application
|`AZURE_USERNAME`|a username (usually an email address)
|`AZURE_PASSWORD`|that user's password
Configuration is attempted in the above order. For example, if values for a
client secret and certificate are both present, the client secret will be used.
## Token caching
Token caching is an `azidentity` feature that allows apps to:
* Cache tokens in memory (default) or on disk (opt-in).
* Improve resilience and performance.
* Reduce the number of requests made to Microsoft Entra ID to obtain access tokens.
For more details, see the [token caching documentation](https://aka.ms/azsdk/go/identity/caching).
## Troubleshooting
### Error Handling
Credentials return an `error` when they fail to authenticate or lack data they require to authenticate. For guidance on resolving errors from specific credential types, see the [troubleshooting guide](https://aka.ms/azsdk/go/identity/troubleshoot).
For more details on handling specific Azure Active Directory errors please refer to the
Azure Active Directory
[error code documentation](https://docs.microsoft.com/azure/active-directory/develop/reference-aadsts-error-codes).
For more details on handling specific Microsoft Entra errors, see the Microsoft Entra [error code documentation](https://learn.microsoft.com/azure/active-directory/develop/reference-error-codes).
### Logging

View File

@ -0,0 +1,70 @@
## Token caching in the Azure Identity client module
*Token caching* is a feature provided by the Azure Identity library that allows apps to:
- Improve their resilience and performance.
- Reduce the number of requests made to Microsoft Entra ID to obtain access tokens.
- Reduce the number of times the user is prompted to authenticate.
When an app needs to access a protected Azure resource, it typically needs to obtain an access token from Entra ID. Obtaining that token involves sending a request to Entra ID and may also involve prompting the user. Entra ID then validates the credentials provided in the request and issues an access token.
Token caching, via the Azure Identity library, allows the app to store this access token [in memory](#in-memory-token-caching), where it's accessible to the current process, or [on disk](#persistent-token-caching) where it can be accessed across application or process invocations. The token can then be retrieved quickly and easily the next time the app needs to access the same resource. The app can avoid making another request to Entra ID, which reduces network traffic and improves resilience. Additionally, in scenarios where the app is authenticating users, token caching also avoids prompting the user each time new tokens are requested.
### In-memory token caching
*In-memory token caching* is the default option provided by the Azure Identity library. This caching approach allows apps to store access tokens in memory. With in-memory token caching, the library first determines if a valid access token for the requested resource is already stored in memory. If a valid token is found, it's returned to the app without the need to make another request to Entra ID. If a valid token isn't found, the library will automatically acquire a token by sending a request to Entra ID. The in-memory token cache provided by the Azure Identity library is thread-safe.
**Note:** When Azure Identity library credentials are used with Azure service libraries (for example, Azure Blob Storage), the in-memory token caching is active in the `Pipeline` layer as well. All `TokenCredential` implementations are supported there, including custom implementations external to the Azure Identity library.
#### Caching cannot be disabled
As there are many levels of caching, it's not possible disable in-memory caching. However, the in-memory cache may be cleared by creating a new credential instance.
### Persistent token caching
> Only azidentity v1.5.0-beta versions support persistent token caching
*Persistent disk token caching* is an opt-in feature in the Azure Identity library. The feature allows apps to cache access tokens in an encrypted, persistent storage mechanism. As indicated in the following table, the storage mechanism differs across operating systems.
| Operating system | Storage mechanism |
|------------------|---------------------------------------|
| Linux | kernel key retention service (keyctl) |
| macOS | Keychain |
| Windows | DPAPI |
By default the token cache will protect any data which is persisted using the user data protection APIs available on the current platform.
However, there are cases where no data protection is available, and applications may choose to allow storing the token cache in an unencrypted state by setting `TokenCachePersistenceOptions.AllowUnencryptedStorage` to `true`. This allows a credential to fall back to unencrypted storage if it can't encrypt the cache. However, we do not recommend using this storage method due to its significantly lower security measures. In addition, tokens are not encrypted solely to the current user, which could potentially allow unauthorized access to the cache by individuals with machine access.
With persistent disk token caching enabled, the library first determines if a valid access token for the requested resource is already stored in the persistent cache. If a valid token is found, it's returned to the app without the need to make another request to Entra ID. Additionally, the tokens are preserved across app runs, which:
- Makes the app more resilient to failures.
- Ensures the app can continue to function during an Entra ID outage or disruption.
- Avoids having to prompt users to authenticate each time the process is restarted.
>IMPORTANT! The token cache contains sensitive data and **MUST** be protected to prevent compromising accounts. All application decisions regarding the persistence of the token cache must consider that a breach of its content will fully compromise all the accounts it contains.
#### Example code
See the [package documentation](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity@v1.5.0-beta.1#pkg-overview) for code examples demonstrating how to configure persistent caching and access cached data.
### Credentials supporting token caching
The following table indicates the state of in-memory and persistent caching in each credential type.
**Note:** In-memory caching is activated by default. Persistent token caching needs to be enabled as shown in [this example](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity@v1.5.0-beta.1#example-package-PersistentCache).
| Credential | In-memory token caching | Persistent token caching |
|--------------------------------|---------------------------------------------------------------------|--------------------------|
| `AzureCLICredential` | Not Supported | Not Supported |
| `AzureDeveloperCLICredential` | Not Supported | Not Supported |
| `ClientAssertionCredential` | Supported | Supported |
| `ClientCertificateCredential` | Supported | Supported |
| `ClientSecretCredential` | Supported | Supported |
| `DefaultAzureCredential` | Supported if the target credential in the default chain supports it | Not Supported |
| `DeviceCodeCredential` | Supported | Supported |
| `EnvironmentCredential` | Supported | Not Supported |
| `InteractiveBrowserCredential` | Supported | Supported |
| `ManagedIdentityCredential` | Supported | Not Supported |
| `OnBehalfOfCredential` | Supported | Supported |
| `UsernamePasswordCredential` | Supported | Supported |
| `WorkloadIdentityCredential` | Supported | Supported |

View File

@ -8,7 +8,8 @@ This troubleshooting guide covers failure investigation techniques, common error
- [Permission issues](#permission-issues)
- [Find relevant information in errors](#find-relevant-information-in-errors)
- [Enable and configure logging](#enable-and-configure-logging)
- [Troubleshoot AzureCliCredential authentication issues](#troubleshoot-azureclicredential-authentication-issues)
- [Troubleshoot AzureCLICredential authentication issues](#troubleshoot-azureclicredential-authentication-issues)
- [Troubleshoot AzureDeveloperCLICredential authentication issues](#troubleshoot-azuredeveloperclicredential-authentication-issues)
- [Troubleshoot ClientCertificateCredential authentication issues](#troubleshoot-clientcertificatecredential-authentication-issues)
- [Troubleshoot ClientSecretCredential authentication issues](#troubleshoot-clientsecretcredential-authentication-issues)
- [Troubleshoot DefaultAzureCredential authentication issues](#troubleshoot-defaultazurecredential-authentication-issues)
@ -23,7 +24,7 @@ This troubleshooting guide covers failure investigation techniques, common error
## Handle azidentity errors
Any service client method that makes a request to the service may return an error due to authentication failure. This is because the credential authenticates on the first call to the service and on any subsequent call that needs to refresh an access token. Authentication errors include a description of the failure and possibly an error message from Azure Active Directory (Azure AD). Depending on the application, these errors may or may not be recoverable.
Any service client method that makes a request to the service may return an error due to authentication failure. This is because the credential authenticates on the first call to the service and on any subsequent call that needs to refresh an access token. Authentication errors include a description of the failure and possibly an error message from Microsoft Entra ID. Depending on the application, these errors may or may not be recoverable.
### Permission issues
@ -31,7 +32,7 @@ Service client errors with a status code of 401 or 403 often indicate that authe
## Find relevant information in errors
Authentication errors can include responses from Azure AD and often contain information helpful in diagnosis. Consider the following error message:
Authentication errors can include responses from Microsoft Entra ID and often contain information helpful in diagnosis. Consider the following error message:
```
ClientSecretCredential authentication failed
@ -57,9 +58,9 @@ This error contains several pieces of information:
- __Failing Credential Type__: The type of credential that failed to authenticate. This can be helpful when diagnosing issues with chained credential types such as `DefaultAzureCredential` or `ChainedTokenCredential`.
- __Azure AD Error Code and Message__: The error code and message returned by Azure AD. This can give insight into the specific reason the request failed. For instance, in this case authentication failed because the provided client secret is incorrect. [Azure AD documentation](https://docs.microsoft.com/azure/active-directory/develop/reference-aadsts-error-codes#aadsts-error-codes) has more information on AADSTS error codes.
- __Microsoft Entra ID Error Code and Message__: The error code and message returned by Microsoft Entra ID. This can give insight into the specific reason the request failed. For instance, in this case authentication failed because the provided client secret is incorrect. [Microsoft Entra ID documentation](https://learn.microsoft.com/azure/active-directory/develop/reference-error-codes#aadsts-error-codes) has more information on AADSTS error codes.
- __Correlation ID and Timestamp__: The correlation ID and timestamp identify the request in server-side logs. This information can be useful to support engineers diagnosing unexpected Azure AD failures.
- __Correlation ID and Timestamp__: The correlation ID and timestamp identify the request in server-side logs. This information can be useful to support engineers diagnosing unexpected Microsoft Entra failures.
### Enable and configure logging
@ -96,17 +97,17 @@ azlog.SetEvents(azidentity.EventAuthentication)
| Error Code | Issue | Mitigation |
|---|---|---|
|AADSTS7000215|An invalid client secret was provided.|Ensure the secret provided to the credential constructor is valid. If unsure, create a new client secret using the Azure portal. Details on creating a new client secret are in [Azure AD documentation](https://docs.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal#option-2-create-a-new-application-secret).|
|AADSTS7000222|An expired client secret was provided.|Create a new client secret using the Azure portal. Details on creating a new client secret are in [Azure AD documentation](https://docs.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal#option-2-create-a-new-application-secret).|
|AADSTS700016|The specified application wasn't found in the specified tenant.|Ensure the client and tenant IDs provided to the credential constructor are correct for your application registration. For multi-tenant apps, ensure the application has been added to the desired tenant by a tenant admin. To add a new application in the desired tenant, follow the [Azure AD instructions](https://docs.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal).|
|AADSTS7000215|An invalid client secret was provided.|Ensure the secret provided to the credential constructor is valid. If unsure, create a new client secret using the Azure portal. Details on creating a new client secret are in [Microsoft Entra ID documentation](https://learn.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal#option-2-create-a-new-application-secret).|
|AADSTS7000222|An expired client secret was provided.|Create a new client secret using the Azure portal. Details on creating a new client secret are in [Microsoft Entra ID documentation](https://learn.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal#option-2-create-a-new-application-secret).|
|AADSTS700016|The specified application wasn't found in the specified tenant.|Ensure the client and tenant IDs provided to the credential constructor are correct for your application registration. For multi-tenant apps, ensure the application has been added to the desired tenant by a tenant admin. To add a new application in the desired tenant, follow the [Microsoft Entra ID instructions](https://learn.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal).|
<a id="client-cert"></a>
## Troubleshoot ClientCertificateCredential authentication issues
| Error Code | Description | Mitigation |
|---|---|---|
|AADSTS700027|Client assertion contains an invalid signature.|Ensure the specified certificate has been uploaded to the application registration as described in [Azure AD documentation](https://docs.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal#option-1-upload-a-certificate).|
|AADSTS700016|The specified application wasn't found in the specified tenant.|Ensure the client and tenant IDs provided to the credential constructor are correct for your application registration. For multi-tenant apps, ensure the application has been added to the desired tenant by a tenant admin. To add a new application in the desired tenant, follow the [Azure AD instructions](https://docs.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal).|
|AADSTS700027|Client assertion contains an invalid signature.|Ensure the specified certificate has been uploaded to the application registration as described in [Microsoft Entra ID documentation](https://learn.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal#option-1-upload-a-certificate).|
|AADSTS700016|The specified application wasn't found in the specified tenant.|Ensure the client and tenant IDs provided to the credential constructor are correct for your application registration. For multi-tenant apps, ensure the application has been added to the desired tenant by a tenant admin. To add a new application in the desired tenant, follow the [Microsoft Entra ID instructions](https://learn.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal).|
<a id="username-password"></a>
## Troubleshoot UsernamePasswordCredential authentication issues
@ -172,7 +173,7 @@ curl "$IDENTITY_ENDPOINT?resource=https://management.core.windows.net&api-versio
|"no azure identity found for request clientID"|The application attempted to authenticate before an identity was assigned to its pod|Verify the pod is labeled correctly. This also occurs when a correctly labeled pod authenticates before the identity is ready. To prevent initialization races, configure NMI to set the Retry-After header in its responses as described in [Pod Identity documentation](https://azure.github.io/aad-pod-identity/docs/configure/feature_flags/#set-retry-after-header-in-nmi-response).
<a id="azure-cli"></a>
## Troubleshoot AzureCliCredential authentication issues
## Troubleshoot AzureCLICredential authentication issues
| Error Message |Description| Mitigation |
|---|---|---|
@ -195,6 +196,29 @@ az account get-access-token --output json --resource https://management.core.win
> This command's output will contain an access token and SHOULD NOT BE SHARED, to avoid compromising account security.
<a id="azd"></a>
## Troubleshoot AzureDeveloperCLICredential authentication issues
| Error Message |Description| Mitigation |
|---|---|---|
|Azure Developer CLI not found on path|The Azure Developer CLI isn't installed or couldn't be found.|<ul><li>Ensure the Azure Developer CLI is properly installed. See the installation instructions at [Install or update the Azure Developer CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd).</li><li>Validate the installation location has been added to the `PATH` environment variable.</li></ul>|
|Please run "azd auth login"|No account is logged into the Azure Developer CLI, or the login has expired.|<ul><li>Log in to the Azure Developer CLI using the `azd login` command.</li><li>Validate that the Azure Developer CLI can obtain tokens. For instructions, see [Verify the Azure Developer CLI can obtain tokens](#verify-the-azure-developer-cli-can-obtain-tokens).</li></ul>|
#### Verify the Azure Developer CLI can obtain tokens
You can manually verify that the Azure Developer CLI is properly authenticated and can obtain tokens. First, use the `config` command to verify the account that is currently logged in to the Azure Developer CLI.
```sh
azd config list
```
Once you've verified the Azure Developer CLI is using correct account, you can validate that it's able to obtain tokens for this account.
```sh
azd auth token --output json --scope https://management.core.windows.net/.default
```
>Note that output of this command will contain a valid access token, and SHOULD NOT BE SHARED to avoid compromising account security.
<a id="workload"></a>
## Troubleshoot `WorkloadIdentityCredential` authentication issues

View File

@ -2,5 +2,5 @@
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "go",
"TagPrefix": "go/azidentity",
"Tag": "go/azidentity_6225ab0470"
"Tag": "go/azidentity_db4a26f583"
}

View File

@ -0,0 +1,95 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package azidentity
import (
"encoding/json"
"errors"
"fmt"
"net/url"
"strings"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/public"
)
var supportedAuthRecordVersions = []string{"1.0"}
// authenticationRecord is non-secret account information about an authenticated user that user credentials such as
// [DeviceCodeCredential] and [InteractiveBrowserCredential] can use to access previously cached authentication
// data. Call these credentials' Authenticate method to get an authenticationRecord for a user.
type authenticationRecord struct {
// Authority is the URL of the authority that issued the token.
Authority string `json:"authority"`
// ClientID is the ID of the application that authenticated the user.
ClientID string `json:"clientId"`
// HomeAccountID uniquely identifies the account.
HomeAccountID string `json:"homeAccountId"`
// TenantID identifies the tenant in which the user authenticated.
TenantID string `json:"tenantId"`
// Username is the user's preferred username.
Username string `json:"username"`
// Version of the AuthenticationRecord.
Version string `json:"version"`
}
// UnmarshalJSON implements json.Unmarshaler for AuthenticationRecord
func (a *authenticationRecord) UnmarshalJSON(b []byte) error {
// Default unmarshaling is fine but we want to return an error if the record's version isn't supported i.e., we
// want to inspect the unmarshalled values before deciding whether to return an error. Unmarshaling a formally
// different type enables this by assigning all the fields without recursing into this method.
type r authenticationRecord
err := json.Unmarshal(b, (*r)(a))
if err != nil {
return err
}
if a.Version == "" {
return errors.New("AuthenticationRecord must have a version")
}
for _, v := range supportedAuthRecordVersions {
if a.Version == v {
return nil
}
}
return fmt.Errorf("unsupported AuthenticationRecord version %q. This module supports %v", a.Version, supportedAuthRecordVersions)
}
// account returns the AuthenticationRecord as an MSAL Account. The account is zero-valued when the AuthenticationRecord is zero-valued.
func (a *authenticationRecord) account() public.Account {
return public.Account{
Environment: a.Authority,
HomeAccountID: a.HomeAccountID,
PreferredUsername: a.Username,
}
}
func newAuthenticationRecord(ar public.AuthResult) (authenticationRecord, error) {
u, err := url.Parse(ar.IDToken.Issuer)
if err != nil {
return authenticationRecord{}, fmt.Errorf("Authenticate expected a URL issuer but got %q", ar.IDToken.Issuer)
}
tenant := ar.IDToken.TenantID
if tenant == "" {
tenant = strings.Trim(u.Path, "/")
}
username := ar.IDToken.PreferredUsername
if username == "" {
username = ar.IDToken.UPN
}
return authenticationRecord{
Authority: fmt.Sprintf("%s://%s", u.Scheme, u.Host),
ClientID: ar.IDToken.Audience,
HomeAccountID: ar.Account.HomeAccountID,
TenantID: tenant,
Username: username,
Version: "1.0",
}, nil
}

View File

@ -15,12 +15,12 @@ import (
"net/http"
"net/url"
"os"
"regexp"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity/internal"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/public"
)
@ -41,6 +41,10 @@ const (
organizationsTenantID = "organizations"
developerSignOnClientID = "04b07795-8ddb-461a-bbee-02f9e1bf7b46"
defaultSuffix = "/.default"
traceNamespace = "Microsoft.Entra"
traceOpGetToken = "GetToken"
traceOpAuthenticate = "Authenticate"
)
var (
@ -49,6 +53,9 @@ var (
errInvalidTenantID = errors.New("invalid tenantID. You can locate your tenantID by following the instructions listed here: https://learn.microsoft.com/partner-center/find-ids-and-domain-names")
)
// tokenCachePersistenceOptions contains options for persistent token caching
type tokenCachePersistenceOptions = internal.TokenCachePersistenceOptions
// setAuthorityHost initializes the authority host for credentials. Precedence is:
// 1. cloud.Configuration.ActiveDirectoryAuthorityHost value set by user
// 2. value of AZURE_AUTHORITY_HOST
@ -109,29 +116,20 @@ func resolveTenant(defaultTenant, specified, credName string, additionalTenants
return "", fmt.Errorf(`%s isn't configured to acquire tokens for tenant %q. To enable acquiring tokens for this tenant add it to the AdditionallyAllowedTenants on the credential options, or add "*" to allow acquiring tokens for any tenant`, credName, specified)
}
// validTenantID return true is it receives a valid tenantID, returns false otherwise
func alphanumeric(r rune) bool {
return ('0' <= r && r <= '9') || ('a' <= r && r <= 'z') || ('A' <= r && r <= 'Z')
}
func validTenantID(tenantID string) bool {
match, err := regexp.MatchString("^[0-9a-zA-Z-.]+$", tenantID)
if err != nil {
return false
for _, r := range tenantID {
if !(alphanumeric(r) || r == '.' || r == '-') {
return false
}
}
return match
return true
}
func newPipelineAdapter(opts *azcore.ClientOptions) pipelineAdapter {
pl := runtime.NewPipeline(component, version, runtime.PipelineOptions{}, opts)
return pipelineAdapter{pl: pl}
}
type pipelineAdapter struct {
pl runtime.Pipeline
}
func (p pipelineAdapter) CloseIdleConnections() {
// do nothing
}
func (p pipelineAdapter) Do(r *http.Request) (*http.Response, error) {
func doForClient(client *azcore.Client, r *http.Request) (*http.Response, error) {
req, err := runtime.NewRequest(r.Context(), r.Method, r.URL.String())
if err != nil {
return nil, err
@ -153,7 +151,18 @@ func (p pipelineAdapter) Do(r *http.Request) (*http.Response, error) {
return nil, err
}
}
resp, err := p.pl.Do(req)
// copy headers to the new request, ignoring any for which the new request has a value
h := req.Raw().Header
for key, vals := range r.Header {
if _, has := h[key]; !has {
for _, val := range vals {
h.Add(key, val)
}
}
}
resp, err := client.Pipeline().Do(req)
if err != nil {
return nil, err
}

View File

@ -14,7 +14,6 @@ import (
"fmt"
"os"
"os/exec"
"regexp"
"runtime"
"strings"
"sync"
@ -25,13 +24,9 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
)
const (
credNameAzureCLI = "AzureCLICredential"
timeoutCLIRequest = 10 * time.Second
)
const credNameAzureCLI = "AzureCLICredential"
// used by tests to fake invoking the CLI
type azureCLITokenProvider func(ctx context.Context, resource string, tenantID string) ([]byte, error)
type azTokenProvider func(ctx context.Context, scopes []string, tenant, subscription string) ([]byte, error)
// AzureCLICredentialOptions contains optional parameters for AzureCLICredential.
type AzureCLICredentialOptions struct {
@ -39,17 +34,25 @@ type AzureCLICredentialOptions struct {
// to TenantID. Add the wildcard value "*" to allow the credential to acquire tokens for any tenant the
// logged in account can access.
AdditionallyAllowedTenants []string
// subscription is the name or ID of a subscription. Set this to acquire tokens for an account other
// than the Azure CLI's current account.
subscription string
// TenantID identifies the tenant the credential should authenticate in.
// Defaults to the CLI's default tenant, which is typically the home tenant of the logged in user.
TenantID string
tokenProvider azureCLITokenProvider
// inDefaultChain is true when the credential is part of DefaultAzureCredential
inDefaultChain bool
// tokenProvider is used by tests to fake invoking az
tokenProvider azTokenProvider
}
// init returns an instance of AzureCLICredentialOptions initialized with default values.
func (o *AzureCLICredentialOptions) init() {
if o.tokenProvider == nil {
o.tokenProvider = defaultTokenProvider
o.tokenProvider = defaultAzTokenProvider
}
}
@ -65,6 +68,14 @@ func NewAzureCLICredential(options *AzureCLICredentialOptions) (*AzureCLICredent
if options != nil {
cp = *options
}
for _, r := range cp.subscription {
if !(alphanumeric(r) || r == '-' || r == '_' || r == ' ' || r == '.') {
return nil, fmt.Errorf("%s: invalid Subscription %q", credNameAzureCLI, cp.subscription)
}
}
if cp.TenantID != "" && !validTenantID(cp.TenantID) {
return nil, errInvalidTenantID
}
cp.init()
cp.AdditionallyAllowedTenants = resolveAdditionalTenants(cp.AdditionallyAllowedTenants)
return &AzureCLICredential{mu: &sync.Mutex{}, opts: cp}, nil
@ -73,50 +84,51 @@ func NewAzureCLICredential(options *AzureCLICredentialOptions) (*AzureCLICredent
// GetToken requests a token from the Azure CLI. This credential doesn't cache tokens, so every call invokes the CLI.
// This method is called automatically by Azure SDK clients.
func (c *AzureCLICredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
at := azcore.AccessToken{}
if len(opts.Scopes) != 1 {
return azcore.AccessToken{}, errors.New(credNameAzureCLI + ": GetToken() requires exactly one scope")
return at, errors.New(credNameAzureCLI + ": GetToken() requires exactly one scope")
}
if !validScope(opts.Scopes[0]) {
return at, fmt.Errorf("%s.GetToken(): invalid scope %q", credNameAzureCLI, opts.Scopes[0])
}
tenant, err := resolveTenant(c.opts.TenantID, opts.TenantID, credNameAzureCLI, c.opts.AdditionallyAllowedTenants)
if err != nil {
return azcore.AccessToken{}, err
return at, err
}
// pass the CLI an AAD v1 resource because we don't know which CLI version is installed and older ones don't support v2 scopes
opts.Scopes = []string{strings.TrimSuffix(opts.Scopes[0], defaultSuffix)}
c.mu.Lock()
defer c.mu.Unlock()
b, err := c.opts.tokenProvider(ctx, opts.Scopes[0], tenant)
if err != nil {
return azcore.AccessToken{}, err
b, err := c.opts.tokenProvider(ctx, opts.Scopes, tenant, c.opts.subscription)
if err == nil {
at, err = c.createAccessToken(b)
}
at, err := c.createAccessToken(b)
if err != nil {
return azcore.AccessToken{}, err
err = unavailableIfInChain(err, c.opts.inDefaultChain)
return at, err
}
msg := fmt.Sprintf("%s.GetToken() acquired a token for scope %q", credNameAzureCLI, strings.Join(opts.Scopes, ", "))
log.Write(EventAuthentication, msg)
return at, nil
}
var defaultTokenProvider azureCLITokenProvider = func(ctx context.Context, resource string, tenantID string) ([]byte, error) {
match, err := regexp.MatchString("^[0-9a-zA-Z-.:/]+$", resource)
if err != nil {
return nil, err
}
if !match {
return nil, fmt.Errorf(`%s: unexpected scope "%s". Only alphanumeric characters and ".", ";", "-", and "/" are allowed`, credNameAzureCLI, resource)
}
// defaultAzTokenProvider invokes the Azure CLI to acquire a token. It assumes
// callers have verified that all string arguments are safe to pass to the CLI.
var defaultAzTokenProvider azTokenProvider = func(ctx context.Context, scopes []string, tenantID, subscription string) ([]byte, error) {
// pass the CLI a Microsoft Entra ID v1 resource because we don't know which CLI version is installed and older ones don't support v2 scopes
resource := strings.TrimSuffix(scopes[0], defaultSuffix)
// set a default timeout for this authentication iff the application hasn't done so already
var cancel context.CancelFunc
if _, hasDeadline := ctx.Deadline(); !hasDeadline {
ctx, cancel = context.WithTimeout(ctx, timeoutCLIRequest)
ctx, cancel = context.WithTimeout(ctx, cliTimeout)
defer cancel()
}
commandLine := "az account get-access-token -o json --resource " + resource
if tenantID != "" {
commandLine += " --tenant " + tenantID
}
if subscription != "" {
// subscription needs quotes because it may contain spaces
commandLine += ` --subscription "` + subscription + `"`
}
var cliCmd *exec.Cmd
if runtime.GOOS == "windows" {
dir := os.Getenv("SYSTEMROOT")

View File

@ -0,0 +1,169 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package azidentity
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"os"
"os/exec"
"runtime"
"strings"
"sync"
"time"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
)
const credNameAzureDeveloperCLI = "AzureDeveloperCLICredential"
type azdTokenProvider func(ctx context.Context, scopes []string, tenant string) ([]byte, error)
// AzureDeveloperCLICredentialOptions contains optional parameters for AzureDeveloperCLICredential.
type AzureDeveloperCLICredentialOptions struct {
// AdditionallyAllowedTenants specifies tenants for which the credential may acquire tokens, in addition
// to TenantID. Add the wildcard value "*" to allow the credential to acquire tokens for any tenant the
// logged in account can access.
AdditionallyAllowedTenants []string
// TenantID identifies the tenant the credential should authenticate in. Defaults to the azd environment,
// which is the tenant of the selected Azure subscription.
TenantID string
// inDefaultChain is true when the credential is part of DefaultAzureCredential
inDefaultChain bool
// tokenProvider is used by tests to fake invoking azd
tokenProvider azdTokenProvider
}
// AzureDeveloperCLICredential authenticates as the identity logged in to the [Azure Developer CLI].
//
// [Azure Developer CLI]: https://learn.microsoft.com/azure/developer/azure-developer-cli/overview
type AzureDeveloperCLICredential struct {
mu *sync.Mutex
opts AzureDeveloperCLICredentialOptions
}
// NewAzureDeveloperCLICredential constructs an AzureDeveloperCLICredential. Pass nil to accept default options.
func NewAzureDeveloperCLICredential(options *AzureDeveloperCLICredentialOptions) (*AzureDeveloperCLICredential, error) {
cp := AzureDeveloperCLICredentialOptions{}
if options != nil {
cp = *options
}
if cp.TenantID != "" && !validTenantID(cp.TenantID) {
return nil, errInvalidTenantID
}
if cp.tokenProvider == nil {
cp.tokenProvider = defaultAzdTokenProvider
}
return &AzureDeveloperCLICredential{mu: &sync.Mutex{}, opts: cp}, nil
}
// GetToken requests a token from the Azure Developer CLI. This credential doesn't cache tokens, so every call invokes azd.
// This method is called automatically by Azure SDK clients.
func (c *AzureDeveloperCLICredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
at := azcore.AccessToken{}
if len(opts.Scopes) == 0 {
return at, errors.New(credNameAzureDeveloperCLI + ": GetToken() requires at least one scope")
}
for _, scope := range opts.Scopes {
if !validScope(scope) {
return at, fmt.Errorf("%s.GetToken(): invalid scope %q", credNameAzureDeveloperCLI, scope)
}
}
tenant, err := resolveTenant(c.opts.TenantID, opts.TenantID, credNameAzureDeveloperCLI, c.opts.AdditionallyAllowedTenants)
if err != nil {
return at, err
}
c.mu.Lock()
defer c.mu.Unlock()
b, err := c.opts.tokenProvider(ctx, opts.Scopes, tenant)
if err == nil {
at, err = c.createAccessToken(b)
}
if err != nil {
err = unavailableIfInChain(err, c.opts.inDefaultChain)
return at, err
}
msg := fmt.Sprintf("%s.GetToken() acquired a token for scope %q", credNameAzureDeveloperCLI, strings.Join(opts.Scopes, ", "))
log.Write(EventAuthentication, msg)
return at, nil
}
// defaultAzTokenProvider invokes the Azure Developer CLI to acquire a token. It assumes
// callers have verified that all string arguments are safe to pass to the CLI.
var defaultAzdTokenProvider azdTokenProvider = func(ctx context.Context, scopes []string, tenant string) ([]byte, error) {
// set a default timeout for this authentication iff the application hasn't done so already
var cancel context.CancelFunc
if _, hasDeadline := ctx.Deadline(); !hasDeadline {
ctx, cancel = context.WithTimeout(ctx, cliTimeout)
defer cancel()
}
commandLine := "azd auth token -o json"
if tenant != "" {
commandLine += " --tenant-id " + tenant
}
for _, scope := range scopes {
commandLine += " --scope " + scope
}
var cliCmd *exec.Cmd
if runtime.GOOS == "windows" {
dir := os.Getenv("SYSTEMROOT")
if dir == "" {
return nil, newCredentialUnavailableError(credNameAzureDeveloperCLI, "environment variable 'SYSTEMROOT' has no value")
}
cliCmd = exec.CommandContext(ctx, "cmd.exe", "/c", commandLine)
cliCmd.Dir = dir
} else {
cliCmd = exec.CommandContext(ctx, "/bin/sh", "-c", commandLine)
cliCmd.Dir = "/bin"
}
cliCmd.Env = os.Environ()
var stderr bytes.Buffer
cliCmd.Stderr = &stderr
output, err := cliCmd.Output()
if err != nil {
msg := stderr.String()
var exErr *exec.ExitError
if errors.As(err, &exErr) && exErr.ExitCode() == 127 || strings.HasPrefix(msg, "'azd' is not recognized") {
msg = "Azure Developer CLI not found on path"
} else if strings.Contains(msg, "azd auth login") {
msg = `please run "azd auth login" from a command prompt to authenticate before using this credential`
}
if msg == "" {
msg = err.Error()
}
return nil, newCredentialUnavailableError(credNameAzureDeveloperCLI, msg)
}
return output, nil
}
func (c *AzureDeveloperCLICredential) createAccessToken(tk []byte) (azcore.AccessToken, error) {
t := struct {
AccessToken string `json:"token"`
ExpiresOn string `json:"expiresOn"`
}{}
err := json.Unmarshal(tk, &t)
if err != nil {
return azcore.AccessToken{}, err
}
exp, err := time.Parse("2006-01-02T15:04:05Z", t.ExpiresOn)
if err != nil {
return azcore.AccessToken{}, fmt.Errorf("error parsing token expiration time %q: %v", t.ExpiresOn, err)
}
return azcore.AccessToken{
ExpiresOn: exp.UTC(),
Token: t.AccessToken,
}, nil
}
var _ azcore.TokenCredential = (*AzureDeveloperCLICredential)(nil)

View File

@ -25,6 +25,7 @@ stages:
- template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml
parameters:
RunLiveTests: true
UsePipelineProxy: false
ServiceDirectory: 'azidentity'
CloudConfig:
Public:

View File

@ -12,6 +12,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential"
)
@ -20,9 +21,9 @@ const credNameAssertion = "ClientAssertionCredential"
// ClientAssertionCredential authenticates an application with assertions provided by a callback function.
// This credential is for advanced scenarios. [ClientCertificateCredential] has a more convenient API for
// the most common assertion scenario, authenticating a service principal with a certificate. See
// [Azure AD documentation] for details of the assertion format.
// [Microsoft Entra ID documentation] for details of the assertion format.
//
// [Azure AD documentation]: https://docs.microsoft.com/azure/active-directory/develop/active-directory-certificate-credentials#assertion-format
// [Microsoft Entra ID documentation]: https://learn.microsoft.com/azure/active-directory/develop/active-directory-certificate-credentials#assertion-format
type ClientAssertionCredential struct {
client *confidentialClient
}
@ -35,11 +36,15 @@ type ClientAssertionCredentialOptions struct {
// Add the wildcard value "*" to allow the credential to acquire tokens for any tenant in which the
// application is registered.
AdditionallyAllowedTenants []string
// DisableInstanceDiscovery should be set true only by applications authenticating in disconnected clouds, or
// private clouds such as Azure Stack. It determines whether the credential requests Azure AD instance metadata
// private clouds such as Azure Stack. It determines whether the credential requests Microsoft Entra instance metadata
// from https://login.microsoft.com before authenticating. Setting this to true will skip this request, making
// the application responsible for ensuring the configured authority is valid and trustworthy.
DisableInstanceDiscovery bool
// tokenCachePersistenceOptions enables persistent token caching when not nil.
tokenCachePersistenceOptions *tokenCachePersistenceOptions
}
// NewClientAssertionCredential constructs a ClientAssertionCredential. The getAssertion function must be thread safe. Pass nil for options to accept defaults.
@ -56,9 +61,10 @@ func NewClientAssertionCredential(tenantID, clientID string, getAssertion func(c
},
)
msalOpts := confidentialClientOptions{
AdditionallyAllowedTenants: options.AdditionallyAllowedTenants,
ClientOptions: options.ClientOptions,
DisableInstanceDiscovery: options.DisableInstanceDiscovery,
AdditionallyAllowedTenants: options.AdditionallyAllowedTenants,
ClientOptions: options.ClientOptions,
DisableInstanceDiscovery: options.DisableInstanceDiscovery,
tokenCachePersistenceOptions: options.tokenCachePersistenceOptions,
}
c, err := newConfidentialClient(tenantID, clientID, credNameAssertion, cred, msalOpts)
if err != nil {
@ -67,9 +73,13 @@ func NewClientAssertionCredential(tenantID, clientID string, getAssertion func(c
return &ClientAssertionCredential{client: c}, nil
}
// GetToken requests an access token from Azure Active Directory. This method is called automatically by Azure SDK clients.
// GetToken requests an access token from Microsoft Entra ID. This method is called automatically by Azure SDK clients.
func (c *ClientAssertionCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
return c.client.GetToken(ctx, opts)
var err error
ctx, endSpan := runtime.StartSpan(ctx, credNameAssertion+"."+traceOpGetToken, c.client.azClient.Tracer(), nil)
defer func() { endSpan(err) }()
tk, err := c.client.GetToken(ctx, opts)
return tk, err
}
var _ azcore.TokenCredential = (*ClientAssertionCredential)(nil)

View File

@ -15,6 +15,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential"
"golang.org/x/crypto/pkcs12"
)
@ -29,15 +30,20 @@ type ClientCertificateCredentialOptions struct {
// Add the wildcard value "*" to allow the credential to acquire tokens for any tenant in which the
// application is registered.
AdditionallyAllowedTenants []string
// DisableInstanceDiscovery should be set true only by applications authenticating in disconnected clouds, or
// private clouds such as Azure Stack. It determines whether the credential requests Azure AD instance metadata
// private clouds such as Azure Stack. It determines whether the credential requests Microsoft Entra instance metadata
// from https://login.microsoft.com before authenticating. Setting this to true will skip this request, making
// the application responsible for ensuring the configured authority is valid and trustworthy.
DisableInstanceDiscovery bool
// SendCertificateChain controls whether the credential sends the public certificate chain in the x5c
// header of each token request's JWT. This is required for Subject Name/Issuer (SNI) authentication.
// Defaults to False.
SendCertificateChain bool
// tokenCachePersistenceOptions enables persistent token caching when not nil.
tokenCachePersistenceOptions *tokenCachePersistenceOptions
}
// ClientCertificateCredential authenticates a service principal with a certificate.
@ -58,10 +64,11 @@ func NewClientCertificateCredential(tenantID string, clientID string, certs []*x
return nil, err
}
msalOpts := confidentialClientOptions{
AdditionallyAllowedTenants: options.AdditionallyAllowedTenants,
ClientOptions: options.ClientOptions,
DisableInstanceDiscovery: options.DisableInstanceDiscovery,
SendX5C: options.SendCertificateChain,
AdditionallyAllowedTenants: options.AdditionallyAllowedTenants,
ClientOptions: options.ClientOptions,
DisableInstanceDiscovery: options.DisableInstanceDiscovery,
SendX5C: options.SendCertificateChain,
tokenCachePersistenceOptions: options.tokenCachePersistenceOptions,
}
c, err := newConfidentialClient(tenantID, clientID, credNameCert, cred, msalOpts)
if err != nil {
@ -70,9 +77,13 @@ func NewClientCertificateCredential(tenantID string, clientID string, certs []*x
return &ClientCertificateCredential{client: c}, nil
}
// GetToken requests an access token from Azure Active Directory. This method is called automatically by Azure SDK clients.
// GetToken requests an access token from Microsoft Entra ID. This method is called automatically by Azure SDK clients.
func (c *ClientCertificateCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
return c.client.GetToken(ctx, opts)
var err error
ctx, endSpan := runtime.StartSpan(ctx, credNameCert+"."+traceOpGetToken, c.client.azClient.Tracer(), nil)
defer func() { endSpan(err) }()
tk, err := c.client.GetToken(ctx, opts)
return tk, err
}
// ParseCertificates loads certificates and a private key, in PEM or PKCS12 format, for use with NewClientCertificateCredential.

View File

@ -11,6 +11,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential"
)
@ -24,11 +25,15 @@ type ClientSecretCredentialOptions struct {
// Add the wildcard value "*" to allow the credential to acquire tokens for any tenant in which the
// application is registered.
AdditionallyAllowedTenants []string
// DisableInstanceDiscovery should be set true only by applications authenticating in disconnected clouds, or
// private clouds such as Azure Stack. It determines whether the credential requests Azure AD instance metadata
// private clouds such as Azure Stack. It determines whether the credential requests Microsoft Entra instance metadata
// from https://login.microsoft.com before authenticating. Setting this to true will skip this request, making
// the application responsible for ensuring the configured authority is valid and trustworthy.
DisableInstanceDiscovery bool
// tokenCachePersistenceOptions enables persistent token caching when not nil.
tokenCachePersistenceOptions *tokenCachePersistenceOptions
}
// ClientSecretCredential authenticates an application with a client secret.
@ -46,20 +51,25 @@ func NewClientSecretCredential(tenantID string, clientID string, clientSecret st
return nil, err
}
msalOpts := confidentialClientOptions{
AdditionallyAllowedTenants: options.AdditionallyAllowedTenants,
ClientOptions: options.ClientOptions,
DisableInstanceDiscovery: options.DisableInstanceDiscovery,
AdditionallyAllowedTenants: options.AdditionallyAllowedTenants,
ClientOptions: options.ClientOptions,
DisableInstanceDiscovery: options.DisableInstanceDiscovery,
tokenCachePersistenceOptions: options.tokenCachePersistenceOptions,
}
c, err := newConfidentialClient(tenantID, clientID, credNameSecret, cred, msalOpts)
if err != nil {
return nil, err
}
return &ClientSecretCredential{c}, nil
return &ClientSecretCredential{client: c}, nil
}
// GetToken requests an access token from Azure Active Directory. This method is called automatically by Azure SDK clients.
// GetToken requests an access token from Microsoft Entra ID. This method is called automatically by Azure SDK clients.
func (c *ClientSecretCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
return c.client.GetToken(ctx, opts)
var err error
ctx, endSpan := runtime.StartSpan(ctx, credNameSecret+"."+traceOpGetToken, c.client.azClient.Tracer(), nil)
defer func() { endSpan(err) }()
tk, err := c.client.GetToken(ctx, opts)
return tk, err
}
var _ azcore.TokenCredential = (*ClientSecretCredential)(nil)

View File

@ -10,6 +10,7 @@ import (
"context"
"errors"
"fmt"
"net/http"
"os"
"strings"
"sync"
@ -17,6 +18,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"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/azidentity/internal"
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential"
)
@ -28,6 +30,7 @@ type confidentialClientOptions struct {
// Assertion for on-behalf-of authentication
Assertion string
DisableInstanceDiscovery, SendX5C bool
tokenCachePersistenceOptions *tokenCachePersistenceOptions
}
// confidentialClient wraps the MSAL confidential client
@ -40,6 +43,7 @@ type confidentialClient struct {
name string
opts confidentialClientOptions
region string
azClient *azcore.Client
}
func newConfidentialClient(tenantID, clientID, name string, cred confidential.Credential, opts confidentialClientOptions) (*confidentialClient, error) {
@ -50,6 +54,14 @@ func newConfidentialClient(tenantID, clientID, name string, cred confidential.Cr
if err != nil {
return nil, err
}
client, err := azcore.NewClient(module, version, runtime.PipelineOptions{
Tracing: runtime.TracingOptions{
Namespace: traceNamespace,
},
}, &opts.ClientOptions)
if err != nil {
return nil, err
}
opts.AdditionallyAllowedTenants = resolveAdditionalTenants(opts.AdditionallyAllowedTenants)
return &confidentialClient{
caeMu: &sync.Mutex{},
@ -62,6 +74,7 @@ func newConfidentialClient(tenantID, clientID, name string, cred confidential.Cr
opts: opts,
region: os.Getenv(azureRegionalAuthorityName),
tenantID: tenantID,
azClient: client,
}, nil
}
@ -132,10 +145,15 @@ func (c *confidentialClient) client(ctx context.Context, tro policy.TokenRequest
}
func (c *confidentialClient) newMSALClient(enableCAE bool) (msalConfidentialClient, error) {
cache, err := internal.NewCache(c.opts.tokenCachePersistenceOptions, enableCAE)
if err != nil {
return nil, err
}
authority := runtime.JoinPaths(c.host, c.tenantID)
o := []confidential.Option{
confidential.WithAzureRegion(c.region),
confidential.WithHTTPClient(newPipelineAdapter(&c.opts.ClientOptions)),
confidential.WithCache(cache),
confidential.WithHTTPClient(c),
}
if enableCAE {
o = append(o, confidential.WithClientCapabilities(cp1))
@ -149,8 +167,18 @@ func (c *confidentialClient) newMSALClient(enableCAE bool) (msalConfidentialClie
return confidential.New(authority, c.clientID, c.cred, o...)
}
// resolveTenant returns the correct tenant for a token request given the client's
// resolveTenant returns the correct WithTenantID() argument for a token request given the client's
// configuration, or an error when that configuration doesn't allow the specified tenant
func (c *confidentialClient) resolveTenant(specified string) (string, error) {
return resolveTenant(c.tenantID, specified, c.name, c.opts.AdditionallyAllowedTenants)
}
// these methods satisfy the MSAL ops.HTTPClient interface
func (c *confidentialClient) CloseIdleConnections() {
// do nothing
}
func (c *confidentialClient) Do(r *http.Request) (*http.Response, error) {
return doForClient(c.azClient, r)
}

View File

@ -30,7 +30,7 @@ type DefaultAzureCredentialOptions struct {
// set as a semicolon delimited list of tenants in the environment variable AZURE_ADDITIONALLY_ALLOWED_TENANTS.
AdditionallyAllowedTenants []string
// DisableInstanceDiscovery should be set true only by applications authenticating in disconnected clouds, or
// private clouds such as Azure Stack. It determines whether the credential requests Azure AD instance metadata
// private clouds such as Azure Stack. It determines whether the credential requests Microsoft Entra instance metadata
// from https://login.microsoft.com before authenticating. Setting this to true will skip this request, making
// the application responsible for ensuring the configured authority is valid and trustworthy.
DisableInstanceDiscovery bool
@ -49,6 +49,7 @@ type DefaultAzureCredentialOptions struct {
// more control over its configuration.
// - [ManagedIdentityCredential]
// - [AzureCLICredential]
// - [AzureDeveloperCLICredential]
//
// Consult the documentation for these credential types for more information on how they authenticate.
// Once a credential has successfully authenticated, DefaultAzureCredential will use that credential for
@ -117,6 +118,17 @@ func NewDefaultAzureCredential(options *DefaultAzureCredentialOptions) (*Default
creds = append(creds, &defaultCredentialErrorReporter{credType: credNameAzureCLI, err: err})
}
azdCred, err := NewAzureDeveloperCLICredential(&AzureDeveloperCLICredentialOptions{
AdditionallyAllowedTenants: additionalTenants,
TenantID: options.TenantID,
})
if err == nil {
creds = append(creds, azdCred)
} else {
errorMessages = append(errorMessages, credNameAzureDeveloperCLI+": "+err.Error())
creds = append(creds, &defaultCredentialErrorReporter{credType: credNameAzureDeveloperCLI, err: err})
}
if len(errorMessages) > 0 {
log.Writef(EventAuthentication, "NewDefaultAzureCredential failed to initialize some credentials:\n\t%s", strings.Join(errorMessages, "\n\t"))
}
@ -129,7 +141,7 @@ func NewDefaultAzureCredential(options *DefaultAzureCredentialOptions) (*Default
return &DefaultAzureCredential{chain: chain}, nil
}
// GetToken requests an access token from Azure Active Directory. This method is called automatically by Azure SDK clients.
// GetToken requests an access token from Microsoft Entra ID. This method is called automatically by Azure SDK clients.
func (c *DefaultAzureCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
return c.chain.GetToken(ctx, opts)
}

View File

@ -0,0 +1,38 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package azidentity
import (
"errors"
"time"
)
// cliTimeout is the default timeout for authentication attempts via CLI tools
const cliTimeout = 10 * time.Second
// unavailableIfInChain returns err or, if the credential was invoked by DefaultAzureCredential, a
// credentialUnavailableError having the same message. This ensures DefaultAzureCredential will try
// the next credential in its chain (another developer credential).
func unavailableIfInChain(err error, inDefaultChain bool) error {
if err != nil && inDefaultChain {
var unavailableErr *credentialUnavailableError
if !errors.As(err, &unavailableErr) {
err = newCredentialUnavailableError(credNameAzureDeveloperCLI, err.Error())
}
}
return err
}
// validScope is for credentials authenticating via external tools. The authority validates scopes for all other credentials.
func validScope(scope string) bool {
for _, r := range scope {
if !(alphanumeric(r) || r == '.' || r == '-' || r == '_' || r == '/' || r == ':') {
return false
}
}
return true
}

View File

@ -12,6 +12,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
)
const credNameDeviceCode = "DeviceCodeCredential"
@ -23,19 +24,34 @@ type DeviceCodeCredentialOptions struct {
// AdditionallyAllowedTenants specifies additional tenants for which the credential may acquire
// tokens. Add the wildcard value "*" to allow the credential to acquire tokens for any tenant.
AdditionallyAllowedTenants []string
// authenticationRecord returned by a call to a credential's Authenticate method. Set this option
// to enable the credential to use data from a previous authentication.
authenticationRecord authenticationRecord
// ClientID is the ID of the application users will authenticate to.
// Defaults to the ID of an Azure development application.
ClientID string
// disableAutomaticAuthentication prevents the credential from automatically prompting the user to authenticate.
// When this option is true, [DeviceCodeCredential.GetToken] will return [ErrAuthenticationRequired] when user
// interaction is necessary to acquire a token.
disableAutomaticAuthentication bool
// DisableInstanceDiscovery should be set true only by applications authenticating in disconnected clouds, or
// private clouds such as Azure Stack. It determines whether the credential requests Azure AD instance metadata
// private clouds such as Azure Stack. It determines whether the credential requests Microsoft Entra instance metadata
// from https://login.microsoft.com before authenticating. Setting this to true will skip this request, making
// the application responsible for ensuring the configured authority is valid and trustworthy.
DisableInstanceDiscovery bool
// TenantID is the Azure Active Directory tenant the credential authenticates in. Defaults to the
// TenantID is the Microsoft Entra tenant the credential authenticates in. Defaults to the
// "organizations" tenant, which can authenticate work and school accounts. Required for single-tenant
// applications.
TenantID string
// tokenCachePersistenceOptions enables persistent token caching when not nil.
tokenCachePersistenceOptions *tokenCachePersistenceOptions
// UserPrompt controls how the credential presents authentication instructions. The credential calls
// this function with authentication details when it receives a device code. By default, the credential
// prints these details to stdout.
@ -63,14 +79,14 @@ type DeviceCodeMessage struct {
UserCode string `json:"user_code"`
// VerificationURL is the URL at which the user must authenticate.
VerificationURL string `json:"verification_uri"`
// Message is user instruction from Azure Active Directory.
// Message is user instruction from Microsoft Entra ID.
Message string `json:"message"`
}
// DeviceCodeCredential acquires tokens for a user via the device code flow, which has the
// user browse to an Azure Active Directory URL, enter a code, and authenticate. It's useful
// user browse to a Microsoft Entra URL, enter a code, and authenticate. It's useful
// for authenticating a user in an environment without a web browser, such as an SSH session.
// If a web browser is available, InteractiveBrowserCredential is more convenient because it
// If a web browser is available, [InteractiveBrowserCredential] is more convenient because it
// automatically opens a browser to the login page.
type DeviceCodeCredential struct {
client *publicClient
@ -84,10 +100,13 @@ func NewDeviceCodeCredential(options *DeviceCodeCredentialOptions) (*DeviceCodeC
}
cp.init()
msalOpts := publicClientOptions{
AdditionallyAllowedTenants: cp.AdditionallyAllowedTenants,
ClientOptions: cp.ClientOptions,
DeviceCodePrompt: cp.UserPrompt,
DisableInstanceDiscovery: cp.DisableInstanceDiscovery,
AdditionallyAllowedTenants: cp.AdditionallyAllowedTenants,
ClientOptions: cp.ClientOptions,
DeviceCodePrompt: cp.UserPrompt,
DisableAutomaticAuthentication: cp.disableAutomaticAuthentication,
DisableInstanceDiscovery: cp.DisableInstanceDiscovery,
Record: cp.authenticationRecord,
TokenCachePersistenceOptions: cp.tokenCachePersistenceOptions,
}
c, err := newPublicClient(cp.TenantID, cp.ClientID, credNameDeviceCode, msalOpts)
if err != nil {
@ -97,10 +116,23 @@ func NewDeviceCodeCredential(options *DeviceCodeCredentialOptions) (*DeviceCodeC
return &DeviceCodeCredential{client: c}, nil
}
// GetToken requests an access token from Azure Active Directory. It will begin the device code flow and poll until the user completes authentication.
// Authenticate a user via the device code flow. Subsequent calls to GetToken will automatically use the returned AuthenticationRecord.
func (c *DeviceCodeCredential) authenticate(ctx context.Context, opts *policy.TokenRequestOptions) (authenticationRecord, error) {
var err error
ctx, endSpan := runtime.StartSpan(ctx, credNameDeviceCode+"."+traceOpAuthenticate, c.client.azClient.Tracer(), nil)
defer func() { endSpan(err) }()
tk, err := c.client.Authenticate(ctx, opts)
return tk, err
}
// GetToken requests an access token from Microsoft Entra ID. It will begin the device code flow and poll until the user completes authentication.
// This method is called automatically by Azure SDK clients.
func (c *DeviceCodeCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
return c.client.GetToken(ctx, opts)
var err error
ctx, endSpan := runtime.StartSpan(ctx, credNameDeviceCode+"."+traceOpGetToken, c.client.azClient.Tracer(), nil)
defer func() { endSpan(err) }()
tk, err := c.client.GetToken(ctx, opts)
return tk, err
}
var _ azcore.TokenCredential = (*DeviceCodeCredential)(nil)

View File

@ -25,7 +25,7 @@ type EnvironmentCredentialOptions struct {
azcore.ClientOptions
// DisableInstanceDiscovery should be set true only by applications authenticating in disconnected clouds, or
// private clouds such as Azure Stack. It determines whether the credential requests Azure AD instance metadata
// private clouds such as Azure Stack. It determines whether the credential requests Microsoft Entra instance metadata
// from https://login.microsoft.com before authenticating. Setting this to true will skip this request, making
// the application responsible for ensuring the configured authority is valid and trustworthy.
DisableInstanceDiscovery bool
@ -156,7 +156,7 @@ func NewEnvironmentCredential(options *EnvironmentCredentialOptions) (*Environme
return nil, errors.New("incomplete environment variable configuration. Only AZURE_TENANT_ID and AZURE_CLIENT_ID are set")
}
// GetToken requests an access token from Azure Active Directory. This method is called automatically by Azure SDK clients.
// GetToken requests an access token from Microsoft Entra ID. This method is called automatically by Azure SDK clients.
func (c *EnvironmentCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
return c.cred.GetToken(ctx, opts)
}

View File

@ -18,6 +18,10 @@ import (
msal "github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors"
)
// errAuthenticationRequired indicates a credential's Authenticate method must be called to acquire a token
// because user interaction is required and the credential is configured not to automatically prompt the user.
var errAuthenticationRequired error = &credentialUnavailableError{"can't acquire a token without user interaction. Call Authenticate to interactively authenticate a user"}
// getResponseFromError retrieves the response carried by
// an AuthenticationFailedError or MSAL CallErr, if any
func getResponseFromError(err error) *http.Response {
@ -53,7 +57,13 @@ func (e *AuthenticationFailedError) Error() string {
}
msg := &bytes.Buffer{}
fmt.Fprintf(msg, e.credType+" authentication failed\n")
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)
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 {
// this happens when the response is created from a custom HTTP transporter,
// which doesn't guarantee to bind the original request to the response
fmt.Fprintln(msg, "Request information not available")
}
fmt.Fprintln(msg, "--------------------------------------------------------------------------------")
fmt.Fprintf(msg, "RESPONSE %s\n", e.RawResponse.Status)
fmt.Fprintln(msg, "--------------------------------------------------------------------------------")
@ -74,6 +84,8 @@ func (e *AuthenticationFailedError) Error() string {
switch e.credType {
case credNameAzureCLI:
anchor = "azure-cli"
case credNameAzureDeveloperCLI:
anchor = "azd"
case credNameCert:
anchor = "client-cert"
case credNameSecret:

View File

@ -0,0 +1,6 @@
go 1.18
use (
.
./cache
)

View File

@ -0,0 +1,39 @@
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0-beta.1 h1:ODs3brnqQM99Tq1PffODpAViYv3Bf8zOg464MU7p5ew=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0-beta.1/go.mod h1:3Ug6Qzto9anB6mGlEdgYMDF5zHQ+wwhEaYR4s17PHMw=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 h1:fb8kj/Dh4CSwgsOzHeZY4Xh68cFVbzXx+ONXGMY//4w=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0/go.mod h1:uReU2sSxZExRPBAg3qKzmAucSi51+SP1OhohieR821Q=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA=
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -11,6 +11,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
)
const credNameBrowser = "InteractiveBrowserCredential"
@ -22,26 +23,40 @@ type InteractiveBrowserCredentialOptions struct {
// AdditionallyAllowedTenants specifies additional tenants for which the credential may acquire
// tokens. Add the wildcard value "*" to allow the credential to acquire tokens for any tenant.
AdditionallyAllowedTenants []string
// authenticationRecord returned by a call to a credential's Authenticate method. Set this option
// to enable the credential to use data from a previous authentication.
authenticationRecord authenticationRecord
// ClientID is the ID of the application users will authenticate to.
// Defaults to the ID of an Azure development application.
ClientID string
// disableAutomaticAuthentication prevents the credential from automatically prompting the user to authenticate.
// When this option is true, [InteractiveBrowserCredential.GetToken] will return [ErrAuthenticationRequired] when
// user interaction is necessary to acquire a token.
disableAutomaticAuthentication bool
// DisableInstanceDiscovery should be set true only by applications authenticating in disconnected clouds, or
// private clouds such as Azure Stack. It determines whether the credential requests Azure AD instance metadata
// private clouds such as Azure Stack. It determines whether the credential requests Microsoft Entra instance metadata
// from https://login.microsoft.com before authenticating. Setting this to true will skip this request, making
// the application responsible for ensuring the configured authority is valid and trustworthy.
DisableInstanceDiscovery bool
// LoginHint pre-populates the account prompt with a username. Users may choose to authenticate a different account.
LoginHint string
// RedirectURL is the URL Azure Active Directory will redirect to with the access token. This is required
// RedirectURL is the URL Microsoft Entra ID will redirect to with the access token. This is required
// only when setting ClientID, and must match a redirect URI in the application's registration.
// Applications which have registered "http://localhost" as a redirect URI need not set this option.
RedirectURL string
// TenantID is the Azure Active Directory tenant the credential authenticates in. Defaults to the
// TenantID is the Microsoft Entra tenant the credential authenticates in. Defaults to the
// "organizations" tenant, which can authenticate work and school accounts.
TenantID string
// tokenCachePersistenceOptions enables persistent token caching when not nil.
tokenCachePersistenceOptions *tokenCachePersistenceOptions
}
func (o *InteractiveBrowserCredentialOptions) init() {
@ -66,10 +81,14 @@ func NewInteractiveBrowserCredential(options *InteractiveBrowserCredentialOption
}
cp.init()
msalOpts := publicClientOptions{
ClientOptions: cp.ClientOptions,
DisableInstanceDiscovery: cp.DisableInstanceDiscovery,
LoginHint: cp.LoginHint,
RedirectURL: cp.RedirectURL,
AdditionallyAllowedTenants: cp.AdditionallyAllowedTenants,
ClientOptions: cp.ClientOptions,
DisableAutomaticAuthentication: cp.disableAutomaticAuthentication,
DisableInstanceDiscovery: cp.DisableInstanceDiscovery,
LoginHint: cp.LoginHint,
Record: cp.authenticationRecord,
RedirectURL: cp.RedirectURL,
TokenCachePersistenceOptions: cp.tokenCachePersistenceOptions,
}
c, err := newPublicClient(cp.TenantID, cp.ClientID, credNameBrowser, msalOpts)
if err != nil {
@ -78,9 +97,22 @@ func NewInteractiveBrowserCredential(options *InteractiveBrowserCredentialOption
return &InteractiveBrowserCredential{client: c}, nil
}
// GetToken requests an access token from Azure Active Directory. This method is called automatically by Azure SDK clients.
// Authenticate a user via the default browser. Subsequent calls to GetToken will automatically use the returned AuthenticationRecord.
func (c *InteractiveBrowserCredential) authenticate(ctx context.Context, opts *policy.TokenRequestOptions) (authenticationRecord, error) {
var err error
ctx, endSpan := runtime.StartSpan(ctx, credNameBrowser+"."+traceOpAuthenticate, c.client.azClient.Tracer(), nil)
defer func() { endSpan(err) }()
tk, err := c.client.Authenticate(ctx, opts)
return tk, err
}
// GetToken requests an access token from Microsoft Entra ID. This method is called automatically by Azure SDK clients.
func (c *InteractiveBrowserCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
return c.client.GetToken(ctx, opts)
var err error
ctx, endSpan := runtime.StartSpan(ctx, credNameBrowser+"."+traceOpGetToken, c.client.azClient.Tracer(), nil)
defer func() { endSpan(err) }()
tk, err := c.client.GetToken(ctx, opts)
return tk, err
}
var _ azcore.TokenCredential = (*InteractiveBrowserCredential)(nil)

View File

@ -0,0 +1,18 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package internal
// TokenCachePersistenceOptions contains options for persistent token caching
type TokenCachePersistenceOptions struct {
// AllowUnencryptedStorage controls whether the cache should fall back to storing its data in plain text
// when encryption isn't possible. Setting this true doesn't disable encryption. The cache always attempts
// encryption before falling back to plaintext storage.
AllowUnencryptedStorage bool
// Name identifies the cache. Set this to isolate data from other applications.
Name string
}

View File

@ -0,0 +1,31 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package internal
import (
"errors"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/cache"
)
var errMissingImport = errors.New("import github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache to enable persistent caching")
// NewCache constructs a persistent token cache when "o" isn't nil. Applications that intend to
// use a persistent cache must first import the cache module, which will replace this function
// with a platform-specific implementation.
var NewCache = func(o *TokenCachePersistenceOptions, enableCAE bool) (cache.ExportReplace, error) {
if o == nil {
return nil, nil
}
return nil, errMissingImport
}
// CacheFilePath returns the path to the cache file for the given name.
// Defining it in this package makes it available to azidentity tests.
var CacheFilePath = func(name string) (string, error) {
return "", errMissingImport
}

View File

@ -28,12 +28,14 @@ import (
const (
arcIMDSEndpoint = "IMDS_ENDPOINT"
defaultIdentityClientID = "DEFAULT_IDENTITY_CLIENT_ID"
identityEndpoint = "IDENTITY_ENDPOINT"
identityHeader = "IDENTITY_HEADER"
identityServerThumbprint = "IDENTITY_SERVER_THUMBPRINT"
headerMetadata = "Metadata"
imdsEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token"
msiEndpoint = "MSI_ENDPOINT"
msiSecret = "MSI_SECRET"
imdsAPIVersion = "2018-02-01"
azureArcAPIVersion = "2019-08-15"
serviceFabricAPIVersion = "2019-07-01-preview"
@ -47,6 +49,7 @@ type msiType int
const (
msiTypeAppService msiType = iota
msiTypeAzureArc
msiTypeAzureML
msiTypeCloudShell
msiTypeIMDS
msiTypeServiceFabric
@ -55,7 +58,7 @@ const (
// managedIdentityClient provides the base for authenticating in managed identity environments
// This type includes an runtime.Pipeline and TokenCredentialOptions.
type managedIdentityClient struct {
pipeline runtime.Pipeline
azClient *azcore.Client
msiType msiType
endpoint string
id ManagedIDKind
@ -135,13 +138,27 @@ func newManagedIdentityClient(options *ManagedIdentityCredentialOptions) (*manag
c.msiType = msiTypeAzureArc
}
} else if endpoint, ok := os.LookupEnv(msiEndpoint); ok {
env = "Cloud Shell"
c.endpoint = endpoint
c.msiType = msiTypeCloudShell
if _, ok := os.LookupEnv(msiSecret); ok {
env = "Azure ML"
c.msiType = msiTypeAzureML
} else {
env = "Cloud Shell"
c.msiType = msiTypeCloudShell
}
} else {
setIMDSRetryOptionDefaults(&cp.Retry)
}
c.pipeline = runtime.NewPipeline(component, version, runtime.PipelineOptions{}, &cp)
client, err := azcore.NewClient(module, version, runtime.PipelineOptions{
Tracing: runtime.TracingOptions{
Namespace: traceNamespace,
},
}, &cp)
if err != nil {
return nil, err
}
c.azClient = client
if log.Should(EventAuthentication) {
log.Writef(EventAuthentication, "Managed Identity Credential will use %s managed identity", env)
@ -168,7 +185,7 @@ func (c *managedIdentityClient) authenticate(ctx context.Context, id ManagedIDKi
return azcore.AccessToken{}, err
}
resp, err := c.pipeline.Do(msg)
resp, err := c.azClient.Pipeline().Do(msg)
if err != nil {
return azcore.AccessToken{}, newAuthenticationFailedError(credNameManagedIdentity, err.Error(), nil, err)
}
@ -247,6 +264,8 @@ func (c *managedIdentityClient) createAuthRequest(ctx context.Context, id Manage
return nil, newAuthenticationFailedError(credNameManagedIdentity, msg, nil, err)
}
return c.createAzureArcAuthRequest(ctx, id, scopes, key)
case msiTypeAzureML:
return c.createAzureMLAuthRequest(ctx, id, scopes)
case msiTypeServiceFabric:
return c.createServiceFabricAuthRequest(ctx, id, scopes)
case msiTypeCloudShell:
@ -296,6 +315,29 @@ func (c *managedIdentityClient) createAppServiceAuthRequest(ctx context.Context,
return request, nil
}
func (c *managedIdentityClient) createAzureMLAuthRequest(ctx context.Context, id ManagedIDKind, scopes []string) (*policy.Request, error) {
request, err := runtime.NewRequest(ctx, http.MethodGet, c.endpoint)
if err != nil {
return nil, err
}
request.Raw().Header.Set("secret", os.Getenv(msiSecret))
q := request.Raw().URL.Query()
q.Add("api-version", "2017-09-01")
q.Add("resource", strings.Join(scopes, " "))
q.Add("clientid", os.Getenv(defaultIdentityClientID))
if id != nil {
if id.idKind() == miResourceID {
log.Write(EventAuthentication, "WARNING: Azure ML doesn't support specifying a managed identity by resource ID")
q.Set("clientid", "")
q.Set(qpResID, id.String())
} else {
q.Set("clientid", id.String())
}
}
request.Raw().URL.RawQuery = q.Encode()
return request, nil
}
func (c *managedIdentityClient) createServiceFabricAuthRequest(ctx context.Context, id ManagedIDKind, scopes []string) (*policy.Request, error) {
request, err := runtime.NewRequest(ctx, http.MethodGet, c.endpoint)
if err != nil {
@ -330,7 +372,7 @@ func (c *managedIdentityClient) getAzureArcSecretKey(ctx context.Context, resour
q.Add("resource", strings.Join(resources, " "))
request.Raw().URL.RawQuery = q.Encode()
// send the initial request to get the short-lived secret key
response, err := c.pipeline.Do(request)
response, err := c.azClient.Pipeline().Do(request)
if err != nil {
return "", err
}

View File

@ -13,6 +13,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential"
)
@ -67,8 +68,8 @@ type ManagedIdentityCredentialOptions struct {
// ManagedIdentityCredential authenticates an Azure managed identity in any hosting environment supporting managed identities.
// This credential authenticates a system-assigned identity by default. Use ManagedIdentityCredentialOptions.ID to specify a
// user-assigned identity. See Azure Active Directory documentation for more information about managed identities:
// https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview
// user-assigned identity. See Microsoft Entra ID documentation for more information about managed identities:
// https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview
type ManagedIdentityCredential struct {
client *confidentialClient
mic *managedIdentityClient
@ -92,7 +93,9 @@ func NewManagedIdentityCredential(options *ManagedIdentityCredentialOptions) (*M
clientID = options.ID.String()
}
// similarly, it's okay to give MSAL an incorrect tenant because MSAL won't use the value
c, err := newConfidentialClient("common", clientID, credNameManagedIdentity, cred, confidentialClientOptions{})
c, err := newConfidentialClient("common", clientID, credNameManagedIdentity, cred, confidentialClientOptions{
ClientOptions: options.ClientOptions,
})
if err != nil {
return nil, err
}
@ -101,13 +104,18 @@ func NewManagedIdentityCredential(options *ManagedIdentityCredentialOptions) (*M
// GetToken requests an access token from the hosting environment. This method is called automatically by Azure SDK clients.
func (c *ManagedIdentityCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
var err error
ctx, endSpan := runtime.StartSpan(ctx, credNameManagedIdentity+"."+traceOpGetToken, c.client.azClient.Tracer(), nil)
defer func() { endSpan(err) }()
if len(opts.Scopes) != 1 {
err := fmt.Errorf("%s.GetToken() requires exactly one scope", credNameManagedIdentity)
err = fmt.Errorf("%s.GetToken() requires exactly one scope", credNameManagedIdentity)
return azcore.AccessToken{}, err
}
// managed identity endpoints require an AADv1 resource (i.e. token audience), not a v2 scope, so we remove "/.default" here
// managed identity endpoints require a Microsoft Entra ID v1 resource (i.e. token audience), not a v2 scope, so we remove "/.default" here
opts.Scopes = []string{strings.TrimSuffix(opts.Scopes[0], defaultSuffix)}
return c.client.GetToken(ctx, opts)
tk, err := c.client.GetToken(ctx, opts)
return tk, err
}
var _ azcore.TokenCredential = (*ManagedIdentityCredential)(nil)

View File

@ -13,6 +13,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential"
)
@ -21,9 +22,9 @@ const credNameOBO = "OnBehalfOfCredential"
// OnBehalfOfCredential authenticates a service principal via the on-behalf-of flow. This is typically used by
// middle-tier services that authorize requests to other services with a delegated user identity. Because this
// is not an interactive authentication flow, an application using it must have admin consent for any delegated
// permissions before requesting tokens for them. See [Azure Active Directory documentation] for more details.
// permissions before requesting tokens for them. See [Microsoft Entra ID documentation] for more details.
//
// [Azure Active Directory documentation]: https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow
// [Microsoft Entra ID documentation]: https://learn.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow
type OnBehalfOfCredential struct {
client *confidentialClient
}
@ -36,11 +37,13 @@ type OnBehalfOfCredentialOptions struct {
// Add the wildcard value "*" to allow the credential to acquire tokens for any tenant in which the
// application is registered.
AdditionallyAllowedTenants []string
// DisableInstanceDiscovery should be set true only by applications authenticating in disconnected clouds, or
// private clouds such as Azure Stack. It determines whether the credential requests Azure AD instance metadata
// private clouds such as Azure Stack. It determines whether the credential requests Microsoft Entra instance metadata
// from https://login.microsoft.com before authenticating. Setting this to true will skip this request, making
// the application responsible for ensuring the configured authority is valid and trustworthy.
DisableInstanceDiscovery bool
// SendCertificateChain applies only when the credential is configured to authenticate with a certificate.
// This setting controls whether the credential sends the public certificate chain in the x5c header of each
// token request's JWT. This is required for, and only used in, Subject Name/Issuer (SNI) authentication.
@ -84,9 +87,13 @@ func newOnBehalfOfCredential(tenantID, clientID, userAssertion string, cred conf
return &OnBehalfOfCredential{c}, nil
}
// GetToken requests an access token from Azure Active Directory. This method is called automatically by Azure SDK clients.
// GetToken requests an access token from Microsoft Entra ID. This method is called automatically by Azure SDK clients.
func (o *OnBehalfOfCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
return o.client.GetToken(ctx, opts)
var err error
ctx, endSpan := runtime.StartSpan(ctx, credNameOBO+"."+traceOpGetToken, o.client.azClient.Tracer(), nil)
defer func() { endSpan(err) }()
tk, err := o.client.GetToken(ctx, opts)
return tk, err
}
var _ azcore.TokenCredential = (*OnBehalfOfCredential)(nil)

View File

@ -8,38 +8,52 @@ package azidentity
import (
"context"
"errors"
"fmt"
"net/http"
"strings"
"sync"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
"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/azidentity/internal"
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/public"
// this import ensures well-known configurations in azcore/cloud have ARM audiences for Authenticate()
_ "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm/runtime"
)
type publicClientOptions struct {
azcore.ClientOptions
AdditionallyAllowedTenants []string
DeviceCodePrompt func(context.Context, DeviceCodeMessage) error
DisableInstanceDiscovery bool
LoginHint, RedirectURL string
Username, Password string
AdditionallyAllowedTenants []string
DeviceCodePrompt func(context.Context, DeviceCodeMessage) error
DisableAutomaticAuthentication bool
DisableInstanceDiscovery bool
LoginHint, RedirectURL string
Record authenticationRecord
TokenCachePersistenceOptions *tokenCachePersistenceOptions
Username, Password string
}
// publicClient wraps the MSAL public client
type publicClient struct {
account public.Account
cae, noCAE msalPublicClient
caeMu, noCAEMu, clientMu *sync.Mutex
clientID, tenantID string
defaultScope []string
host string
name string
opts publicClientOptions
record authenticationRecord
azClient *azcore.Client
}
var errScopeRequired = errors.New("authenticating in this environment requires specifying a scope in TokenRequestOptions")
func newPublicClient(tenantID, clientID, name string, o publicClientOptions) (*publicClient, error) {
if !validTenantID(tenantID) {
return nil, errInvalidTenantID
@ -48,19 +62,76 @@ func newPublicClient(tenantID, clientID, name string, o publicClientOptions) (*p
if err != nil {
return nil, err
}
// if the application specified a cloud configuration, use its ARM audience as the default scope for Authenticate()
audience := o.Cloud.Services[cloud.ResourceManager].Audience
if audience == "" {
// no cloud configuration, or no ARM audience, specified; try to map the host to a well-known one (all of which have a trailing slash)
if !strings.HasSuffix(host, "/") {
host += "/"
}
switch host {
case cloud.AzureChina.ActiveDirectoryAuthorityHost:
audience = cloud.AzureChina.Services[cloud.ResourceManager].Audience
case cloud.AzureGovernment.ActiveDirectoryAuthorityHost:
audience = cloud.AzureGovernment.Services[cloud.ResourceManager].Audience
case cloud.AzurePublic.ActiveDirectoryAuthorityHost:
audience = cloud.AzurePublic.Services[cloud.ResourceManager].Audience
}
}
// if we didn't come up with an audience, the application will have to specify a scope for Authenticate()
var defaultScope []string
if audience != "" {
defaultScope = []string{audience + defaultSuffix}
}
client, err := azcore.NewClient(module, version, runtime.PipelineOptions{
Tracing: runtime.TracingOptions{
Namespace: traceNamespace,
},
}, &o.ClientOptions)
if err != nil {
return nil, err
}
o.AdditionallyAllowedTenants = resolveAdditionalTenants(o.AdditionallyAllowedTenants)
return &publicClient{
caeMu: &sync.Mutex{},
clientID: clientID,
clientMu: &sync.Mutex{},
host: host,
name: name,
noCAEMu: &sync.Mutex{},
opts: o,
tenantID: tenantID,
caeMu: &sync.Mutex{},
clientID: clientID,
clientMu: &sync.Mutex{},
defaultScope: defaultScope,
host: host,
name: name,
noCAEMu: &sync.Mutex{},
opts: o,
record: o.Record,
tenantID: tenantID,
azClient: client,
}, nil
}
func (p *publicClient) Authenticate(ctx context.Context, tro *policy.TokenRequestOptions) (authenticationRecord, error) {
if tro == nil {
tro = &policy.TokenRequestOptions{}
}
if len(tro.Scopes) == 0 {
if p.defaultScope == nil {
return authenticationRecord{}, errScopeRequired
}
tro.Scopes = p.defaultScope
}
client, mu, err := p.client(*tro)
if err != nil {
return authenticationRecord{}, err
}
mu.Lock()
defer mu.Unlock()
_, err = p.reqToken(ctx, client, *tro)
if err == nil {
scope := strings.Join(tro.Scopes, ", ")
msg := fmt.Sprintf("%s.Authenticate() acquired a token for scope %q", p.name, scope)
log.Write(EventAuthentication, msg)
}
return p.record, err
}
// GetToken requests an access token from MSAL, checking the cache first.
func (p *publicClient) GetToken(ctx context.Context, tro policy.TokenRequestOptions) (azcore.AccessToken, error) {
if len(tro.Scopes) < 1 {
@ -76,10 +147,13 @@ func (p *publicClient) GetToken(ctx context.Context, tro policy.TokenRequestOpti
}
mu.Lock()
defer mu.Unlock()
ar, err := client.AcquireTokenSilent(ctx, tro.Scopes, public.WithSilentAccount(p.account), public.WithClaims(tro.Claims), public.WithTenantID(tenant))
ar, err := client.AcquireTokenSilent(ctx, tro.Scopes, public.WithSilentAccount(p.record.account()), public.WithClaims(tro.Claims), public.WithTenantID(tenant))
if err == nil {
return p.token(ar, err)
}
if p.opts.DisableAutomaticAuthentication {
return azcore.AccessToken{}, errAuthenticationRequired
}
at, err := p.reqToken(ctx, client, tro)
if err == nil {
msg := fmt.Sprintf("%s.GetToken() acquired a token for scope %q", p.name, strings.Join(ar.GrantedScopes, ", "))
@ -148,9 +222,14 @@ func (p *publicClient) client(tro policy.TokenRequestOptions) (msalPublicClient,
}
func (p *publicClient) newMSALClient(enableCAE bool) (msalPublicClient, error) {
cache, err := internal.NewCache(p.opts.TokenCachePersistenceOptions, enableCAE)
if err != nil {
return nil, err
}
o := []public.Option{
public.WithAuthority(runtime.JoinPaths(p.host, p.tenantID)),
public.WithHTTPClient(newPipelineAdapter(&p.opts.ClientOptions)),
public.WithCache(cache),
public.WithHTTPClient(p),
}
if enableCAE {
o = append(o, public.WithClientCapabilities(cp1))
@ -163,7 +242,7 @@ func (p *publicClient) newMSALClient(enableCAE bool) (msalPublicClient, error) {
func (p *publicClient) token(ar public.AuthResult, err error) (azcore.AccessToken, error) {
if err == nil {
p.account = ar.Account
p.record, err = newAuthenticationRecord(ar)
} else {
res := getResponseFromError(err)
err = newAuthenticationFailedError(p.name, err.Error(), res, err)
@ -171,8 +250,24 @@ func (p *publicClient) token(ar public.AuthResult, err error) (azcore.AccessToke
return azcore.AccessToken{Token: ar.AccessToken, ExpiresOn: ar.ExpiresOn.UTC()}, err
}
// resolveTenant returns the correct tenant for a token request given the client's
// resolveTenant returns the correct WithTenantID() argument for a token request given the client's
// configuration, or an error when that configuration doesn't allow the specified tenant
func (p *publicClient) resolveTenant(specified string) (string, error) {
return resolveTenant(p.tenantID, specified, p.name, p.opts.AdditionallyAllowedTenants)
t, err := resolveTenant(p.tenantID, specified, p.name, p.opts.AdditionallyAllowedTenants)
if t == p.tenantID {
// callers pass this value to MSAL's WithTenantID(). There's no need to redundantly specify
// the client's default tenant and doing so is an error when that tenant is "organizations"
t = ""
}
return t, err
}
// these methods satisfy the MSAL ops.HTTPClient interface
func (p *publicClient) CloseIdleConnections() {
// do nothing
}
func (p *publicClient) Do(r *http.Request) (*http.Response, error) {
return doForClient(p.azClient, r)
}

View File

@ -11,6 +11,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
)
const credNameUserPassword = "UsernamePasswordCredential"
@ -23,11 +24,19 @@ type UsernamePasswordCredentialOptions struct {
// Add the wildcard value "*" to allow the credential to acquire tokens for any tenant in which the
// application is registered.
AdditionallyAllowedTenants []string
// authenticationRecord returned by a call to a credential's Authenticate method. Set this option
// to enable the credential to use data from a previous authentication.
authenticationRecord authenticationRecord
// DisableInstanceDiscovery should be set true only by applications authenticating in disconnected clouds, or
// private clouds such as Azure Stack. It determines whether the credential requests Azure AD instance metadata
// private clouds such as Azure Stack. It determines whether the credential requests Microsoft Entra instance metadata
// from https://login.microsoft.com before authenticating. Setting this to true will skip this request, making
// the application responsible for ensuring the configured authority is valid and trustworthy.
DisableInstanceDiscovery bool
// tokenCachePersistenceOptions enables persistent token caching when not nil.
tokenCachePersistenceOptions *tokenCachePersistenceOptions
}
// UsernamePasswordCredential authenticates a user with a password. Microsoft doesn't recommend this kind of authentication,
@ -45,11 +54,13 @@ func NewUsernamePasswordCredential(tenantID string, clientID string, username st
options = &UsernamePasswordCredentialOptions{}
}
opts := publicClientOptions{
AdditionallyAllowedTenants: options.AdditionallyAllowedTenants,
ClientOptions: options.ClientOptions,
DisableInstanceDiscovery: options.DisableInstanceDiscovery,
Password: password,
Username: username,
AdditionallyAllowedTenants: options.AdditionallyAllowedTenants,
ClientOptions: options.ClientOptions,
DisableInstanceDiscovery: options.DisableInstanceDiscovery,
Password: password,
Record: options.authenticationRecord,
TokenCachePersistenceOptions: options.tokenCachePersistenceOptions,
Username: username,
}
c, err := newPublicClient(tenantID, clientID, credNameUserPassword, opts)
if err != nil {
@ -58,9 +69,22 @@ func NewUsernamePasswordCredential(tenantID string, clientID string, username st
return &UsernamePasswordCredential{client: c}, err
}
// GetToken requests an access token from Azure Active Directory. This method is called automatically by Azure SDK clients.
// Authenticate the user. Subsequent calls to GetToken will automatically use the returned AuthenticationRecord.
func (c *UsernamePasswordCredential) authenticate(ctx context.Context, opts *policy.TokenRequestOptions) (authenticationRecord, error) {
var err error
ctx, endSpan := runtime.StartSpan(ctx, credNameUserPassword+"."+traceOpAuthenticate, c.client.azClient.Tracer(), nil)
defer func() { endSpan(err) }()
tk, err := c.client.Authenticate(ctx, opts)
return tk, err
}
// GetToken requests an access token from Microsoft Entra ID. This method is called automatically by Azure SDK clients.
func (c *UsernamePasswordCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
return c.client.GetToken(ctx, opts)
var err error
ctx, endSpan := runtime.StartSpan(ctx, credNameUserPassword+"."+traceOpGetToken, c.client.azClient.Tracer(), nil)
defer func() { endSpan(err) }()
tk, err := c.client.GetToken(ctx, opts)
return tk, err
}
var _ azcore.TokenCredential = (*UsernamePasswordCredential)(nil)

View File

@ -10,6 +10,9 @@ const (
// UserAgent is the string to be used in the user agent string when making requests.
component = "azidentity"
// module is the fully qualified name of the module used in telemetry and distributed tracing.
module = "github.com/Azure/azure-sdk-for-go/sdk/" + component
// Version is the semantic version (see http://semver.org) of this module.
version = "v1.4.0"
version = "v1.5.1"
)

View File

@ -15,6 +15,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
)
const credNameWorkloadIdentity = "WorkloadIdentityCredential"
@ -41,7 +42,7 @@ type WorkloadIdentityCredentialOptions struct {
// ClientID of the service principal. Defaults to the value of the environment variable AZURE_CLIENT_ID.
ClientID string
// DisableInstanceDiscovery should be set true only by applications authenticating in disconnected clouds, or
// private clouds such as Azure Stack. It determines whether the credential requests Azure AD instance metadata
// private clouds such as Azure Stack. It determines whether the credential requests Microsoft Entra instance metadata
// from https://login.microsoft.com before authenticating. Setting this to true will skip this request, making
// the application responsible for ensuring the configured authority is valid and trustworthy.
DisableInstanceDiscovery bool
@ -93,9 +94,13 @@ func NewWorkloadIdentityCredential(options *WorkloadIdentityCredentialOptions) (
return &w, nil
}
// GetToken requests an access token from Azure Active Directory. Azure SDK clients call this method automatically.
// GetToken requests an access token from Microsoft Entra ID. Azure SDK clients call this method automatically.
func (w *WorkloadIdentityCredential) GetToken(ctx context.Context, opts policy.TokenRequestOptions) (azcore.AccessToken, error) {
return w.cred.GetToken(ctx, opts)
var err error
ctx, endSpan := runtime.StartSpan(ctx, credNameWorkloadIdentity+"."+traceOpGetToken, w.cred.client.azClient.Tracer(), nil)
defer func() { endSpan(err) }()
tk, err := w.cred.GetToken(ctx, opts)
return tk, err
}
// getAssertion returns the specified file's content, which is expected to be a Kubernetes service account token.

View File

@ -39,6 +39,11 @@ type PayloadOptions struct {
// Subsequent reads will access the cached value.
// Exported as runtime.Payload() WITHOUT the opts parameter.
func Payload(resp *http.Response, opts *PayloadOptions) ([]byte, error) {
if resp.Body == nil {
// this shouldn't happen in real-world scenarios as a
// response with no body should set it to http.NoBody
return nil, nil
}
modifyBytes := func(b []byte) []byte { return b }
if opts != nil && opts.BytesModifier != nil {
modifyBytes = opts.BytesModifier

View File

@ -11,7 +11,7 @@ The `armresources` module provides operations for working with Azure Resources.
## Prerequisites
- an [Azure subscription](https://azure.microsoft.com/free/)
- Go 1.18 or above
- Go 1.18 or above (You could download and install the latest version of Go from [here](https://go.dev/doc/install). It will replace the existing Go on your machine. If you want to install multiple Go versions on the same machine, you could refer this [doc](https://go.dev/doc/manage-install).)
## Install the package
@ -33,12 +33,12 @@ cred, err := azidentity.NewDefaultAzureCredential(nil)
For more information on authentication, please see the documentation for `azidentity` at [pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity).
## Clients
## Client Factory
Azure Resources modules consist of one or more clients. A client groups a set of related APIs, providing access to its functionality within the specified subscription. Create one or more clients to access the APIs you require using your credential.
Azure Resources module consists of one or more clients. We provide a client factory which could be used to create any client in this module.
```go
client, err := armresources.NewClient(<subscription ID>, cred, nil)
clientFactory, err := armresources.NewClientFactory(<subscription ID>, cred, nil)
```
You can use `ClientOptions` in package `github.com/Azure/azure-sdk-for-go/sdk/azcore/arm` to set endpoint to connect with public and sovereign clouds as well as Azure Stack. For more information, please see the documentation for `azcore` at [pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azcore](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azcore).
@ -49,11 +49,27 @@ options := arm.ClientOptions {
Cloud: cloud.AzureChina,
},
}
client, err := armresources.NewClient(<subscription ID>, cred, &options)
clientFactory, err := armresources.NewClientFactory(<subscription ID>, cred, &options)
```
## Clients
A client groups a set of related APIs, providing access to its functionality. Create one or more clients to access the APIs you require using client factory.
```go
client := clientFactory.NewClient()
```
## 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.
## More sample code
- [Creating a Fake](https://github.com/Azure/azure-sdk-for-go/blob/main/sdk/resourcemanager/resources/armresources/fake_example_test.go)
- [Deployment](https://aka.ms/azsdk/go/mgmt/samples?path=sdk/resourcemanager/resource/deployment)
- [Provider](https://aka.ms/azsdk/go/mgmt/samples?path=sdk/resourcemanager/resource/provider)
- [Resource Group](https://aka.ms/azsdk/go/mgmt/samples?path=sdk/resourcemanager/resource/resourcegroups)

View File

@ -0,0 +1,6 @@
{
"AssetsRepo": "Azure/azure-sdk-assets",
"AssetsRepoPrefixPath": "go",
"TagPrefix": "go/resourcemanager/resources/armresources",
"Tag": "go/resourcemanager/resources/armresources_ab8e63cc21"
}

View File

@ -8,6 +8,6 @@ require:
- https://github.com/Azure/azure-rest-api-specs/blob/4fd842fb73656039ec94ce367bcedee25a57bd18/specification/resources/resource-manager/readme.md
- https://github.com/Azure/azure-rest-api-specs/blob/4fd842fb73656039ec94ce367bcedee25a57bd18/specification/resources/resource-manager/readme.go.md
license-header: MICROSOFT_MIT_NO_VERSION
module-version: 1.0.0
module-version: 1.2.0
package-resources: true
```
```

View File

@ -2,6 +2,6 @@
// Licensed under the MIT License. See License.txt in the project root for license information.
// This file enables 'go generate' to regenerate this specific SDK
//go:generate pwsh.exe ../../../../eng/scripts/build.ps1 -skipBuild -cleanGenerated -format -tidy -generate resourcemanager/resources/armresources
//go:generate pwsh ../../../../eng/scripts/build.ps1 -skipBuild -cleanGenerated -format -tidy -generate resourcemanager/resources/armresources
package armresources

View File

@ -0,0 +1,86 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
package armresources
import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
)
// ClientFactory is a client factory used to create any client in this module.
// Don't use this type directly, use NewClientFactory instead.
type ClientFactory struct {
subscriptionID string
credential azcore.TokenCredential
options *arm.ClientOptions
}
// NewClientFactory creates a new instance of ClientFactory with the specified values.
// The parameter values will be propagated to any client created from this factory.
// - subscriptionID - The Microsoft Azure subscription ID.
// - credential - used to authorize requests. Usually a credential from azidentity.
// - options - pass nil to accept the default values.
func NewClientFactory(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*ClientFactory, error) {
_, err := arm.NewClient(moduleName, moduleVersion, credential, options)
if err != nil {
return nil, err
}
return &ClientFactory{
subscriptionID: subscriptionID, credential: credential,
options: options.Clone(),
}, nil
}
// NewClient creates a new instance of Client.
func (c *ClientFactory) NewClient() *Client {
subClient, _ := NewClient(c.subscriptionID, c.credential, c.options)
return subClient
}
// NewDeploymentOperationsClient creates a new instance of DeploymentOperationsClient.
func (c *ClientFactory) NewDeploymentOperationsClient() *DeploymentOperationsClient {
subClient, _ := NewDeploymentOperationsClient(c.subscriptionID, c.credential, c.options)
return subClient
}
// NewDeploymentsClient creates a new instance of DeploymentsClient.
func (c *ClientFactory) NewDeploymentsClient() *DeploymentsClient {
subClient, _ := NewDeploymentsClient(c.subscriptionID, c.credential, c.options)
return subClient
}
// NewOperationsClient creates a new instance of OperationsClient.
func (c *ClientFactory) NewOperationsClient() *OperationsClient {
subClient, _ := NewOperationsClient(c.credential, c.options)
return subClient
}
// NewProviderResourceTypesClient creates a new instance of ProviderResourceTypesClient.
func (c *ClientFactory) NewProviderResourceTypesClient() *ProviderResourceTypesClient {
subClient, _ := NewProviderResourceTypesClient(c.subscriptionID, c.credential, c.options)
return subClient
}
// NewProvidersClient creates a new instance of ProvidersClient.
func (c *ClientFactory) NewProvidersClient() *ProvidersClient {
subClient, _ := NewProvidersClient(c.subscriptionID, c.credential, c.options)
return subClient
}
// NewResourceGroupsClient creates a new instance of ResourceGroupsClient.
func (c *ClientFactory) NewResourceGroupsClient() *ResourceGroupsClient {
subClient, _ := NewResourceGroupsClient(c.subscriptionID, c.credential, c.options)
return subClient
}
// NewTagsClient creates a new instance of TagsClient.
func (c *ClientFactory) NewTagsClient() *TagsClient {
subClient, _ := NewTagsClient(c.subscriptionID, c.credential, c.options)
return subClient
}

View File

@ -3,14 +3,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
package armresources
const (
moduleName = "armresources"
moduleVersion = "v1.0.0"
moduleName = "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
moduleVersion = "v1.2.0"
)
// AliasPathAttributes - The attributes of the token that the alias path is referring to.
@ -71,17 +71,17 @@ func PossibleAliasPathTokenTypeValues() []AliasPathTokenType {
type AliasPatternType string
const (
// AliasPatternTypeNotSpecified - NotSpecified is not allowed.
AliasPatternTypeNotSpecified AliasPatternType = "NotSpecified"
// AliasPatternTypeExtract - Extract is the only allowed value.
AliasPatternTypeExtract AliasPatternType = "Extract"
// AliasPatternTypeNotSpecified - NotSpecified is not allowed.
AliasPatternTypeNotSpecified AliasPatternType = "NotSpecified"
)
// PossibleAliasPatternTypeValues returns the possible values for the AliasPatternType const type.
func PossibleAliasPatternTypeValues() []AliasPatternType {
return []AliasPatternType{
AliasPatternTypeNotSpecified,
AliasPatternTypeExtract,
AliasPatternTypeNotSpecified,
}
}
@ -89,20 +89,20 @@ func PossibleAliasPatternTypeValues() []AliasPatternType {
type AliasType string
const (
// AliasTypeMask - Alias value is secret.
AliasTypeMask AliasType = "Mask"
// AliasTypeNotSpecified - Alias type is unknown (same as not providing alias type).
AliasTypeNotSpecified AliasType = "NotSpecified"
// AliasTypePlainText - Alias value is not secret.
AliasTypePlainText AliasType = "PlainText"
// AliasTypeMask - Alias value is secret.
AliasTypeMask AliasType = "Mask"
)
// PossibleAliasTypeValues returns the possible values for the AliasType const type.
func PossibleAliasTypeValues() []AliasType {
return []AliasType{
AliasTypeMask,
AliasTypeNotSpecified,
AliasTypePlainText,
AliasTypeMask,
}
}
@ -116,18 +116,18 @@ const (
// ChangeTypeDelete - The resource exists in the current state and is missing from the desired state. The resource will be
// deleted when the deployment is executed.
ChangeTypeDelete ChangeType = "Delete"
// ChangeTypeIgnore - The resource exists in the current state and is missing from the desired state. The resource will not
// be deployed or modified when the deployment is executed.
ChangeTypeIgnore ChangeType = "Ignore"
// ChangeTypeDeploy - The resource exists in the current state and the desired state and will be redeployed when the deployment
// is executed. The properties of the resource may or may not change.
ChangeTypeDeploy ChangeType = "Deploy"
// ChangeTypeNoChange - The resource exists in the current state and the desired state and will be redeployed when the deployment
// is executed. The properties of the resource will not change.
ChangeTypeNoChange ChangeType = "NoChange"
// ChangeTypeIgnore - The resource exists in the current state and is missing from the desired state. The resource will not
// be deployed or modified when the deployment is executed.
ChangeTypeIgnore ChangeType = "Ignore"
// ChangeTypeModify - The resource exists in the current state and the desired state and will be redeployed when the deployment
// is executed. The properties of the resource will change.
ChangeTypeModify ChangeType = "Modify"
// ChangeTypeNoChange - The resource exists in the current state and the desired state and will be redeployed when the deployment
// is executed. The properties of the resource will not change.
ChangeTypeNoChange ChangeType = "NoChange"
// ChangeTypeUnsupported - The resource is not supported by What-If.
ChangeTypeUnsupported ChangeType = "Unsupported"
)
@ -137,10 +137,10 @@ func PossibleChangeTypeValues() []ChangeType {
return []ChangeType{
ChangeTypeCreate,
ChangeTypeDelete,
ChangeTypeIgnore,
ChangeTypeDeploy,
ChangeTypeNoChange,
ChangeTypeIgnore,
ChangeTypeModify,
ChangeTypeNoChange,
ChangeTypeUnsupported,
}
}
@ -153,15 +153,15 @@ func PossibleChangeTypeValues() []ChangeType {
type DeploymentMode string
const (
DeploymentModeIncremental DeploymentMode = "Incremental"
DeploymentModeComplete DeploymentMode = "Complete"
DeploymentModeIncremental DeploymentMode = "Incremental"
)
// PossibleDeploymentModeValues returns the possible values for the DeploymentMode const type.
func PossibleDeploymentModeValues() []DeploymentMode {
return []DeploymentMode{
DeploymentModeIncremental,
DeploymentModeComplete,
DeploymentModeIncremental,
}
}
@ -218,6 +218,8 @@ func PossibleOnErrorDeploymentTypeValues() []OnErrorDeploymentType {
type PropertyChangeType string
const (
// PropertyChangeTypeArray - The property is an array and contains nested changes.
PropertyChangeTypeArray PropertyChangeType = "Array"
// PropertyChangeTypeCreate - The property does not exist in the current state but is present in the desired state. The property
// will be created when the deployment is executed.
PropertyChangeTypeCreate PropertyChangeType = "Create"
@ -227,8 +229,6 @@ const (
// PropertyChangeTypeModify - The property exists in both current and desired state and is different. The value of the property
// will change when the deployment is executed.
PropertyChangeTypeModify PropertyChangeType = "Modify"
// PropertyChangeTypeArray - The property is an array and contains nested changes.
PropertyChangeTypeArray PropertyChangeType = "Array"
// PropertyChangeTypeNoEffect - The property will not be set or updated.
PropertyChangeTypeNoEffect PropertyChangeType = "NoEffect"
)
@ -236,10 +236,10 @@ const (
// PossiblePropertyChangeTypeValues returns the possible values for the PropertyChangeType const type.
func PossiblePropertyChangeTypeValues() []PropertyChangeType {
return []PropertyChangeType{
PropertyChangeTypeArray,
PropertyChangeTypeCreate,
PropertyChangeTypeDelete,
PropertyChangeTypeModify,
PropertyChangeTypeArray,
PropertyChangeTypeNoEffect,
}
}
@ -268,42 +268,42 @@ func PossibleProviderAuthorizationConsentStateValues() []ProviderAuthorizationCo
type ProvisioningOperation string
const (
// ProvisioningOperationNotSpecified - The provisioning operation is not specified.
ProvisioningOperationNotSpecified ProvisioningOperation = "NotSpecified"
// ProvisioningOperationAction - The provisioning operation is action.
ProvisioningOperationAction ProvisioningOperation = "Action"
// ProvisioningOperationAzureAsyncOperationWaiting - The provisioning operation is waiting Azure async operation.
ProvisioningOperationAzureAsyncOperationWaiting ProvisioningOperation = "AzureAsyncOperationWaiting"
// ProvisioningOperationCreate - The provisioning operation is create.
ProvisioningOperationCreate ProvisioningOperation = "Create"
// ProvisioningOperationDelete - The provisioning operation is delete.
ProvisioningOperationDelete ProvisioningOperation = "Delete"
// ProvisioningOperationWaiting - The provisioning operation is waiting.
ProvisioningOperationWaiting ProvisioningOperation = "Waiting"
// ProvisioningOperationAzureAsyncOperationWaiting - The provisioning operation is waiting Azure async operation.
ProvisioningOperationAzureAsyncOperationWaiting ProvisioningOperation = "AzureAsyncOperationWaiting"
// ProvisioningOperationResourceCacheWaiting - The provisioning operation is waiting for resource cache.
ProvisioningOperationResourceCacheWaiting ProvisioningOperation = "ResourceCacheWaiting"
// ProvisioningOperationAction - The provisioning operation is action.
ProvisioningOperationAction ProvisioningOperation = "Action"
// ProvisioningOperationRead - The provisioning operation is read.
ProvisioningOperationRead ProvisioningOperation = "Read"
// ProvisioningOperationEvaluateDeploymentOutput - The provisioning operation is evaluate output.
ProvisioningOperationEvaluateDeploymentOutput ProvisioningOperation = "EvaluateDeploymentOutput"
// ProvisioningOperationDeploymentCleanup - The provisioning operation is cleanup. This operation is part of the 'complete'
// mode deployment.
ProvisioningOperationDeploymentCleanup ProvisioningOperation = "DeploymentCleanup"
// ProvisioningOperationEvaluateDeploymentOutput - The provisioning operation is evaluate output.
ProvisioningOperationEvaluateDeploymentOutput ProvisioningOperation = "EvaluateDeploymentOutput"
// ProvisioningOperationNotSpecified - The provisioning operation is not specified.
ProvisioningOperationNotSpecified ProvisioningOperation = "NotSpecified"
// ProvisioningOperationRead - The provisioning operation is read.
ProvisioningOperationRead ProvisioningOperation = "Read"
// ProvisioningOperationResourceCacheWaiting - The provisioning operation is waiting for resource cache.
ProvisioningOperationResourceCacheWaiting ProvisioningOperation = "ResourceCacheWaiting"
// ProvisioningOperationWaiting - The provisioning operation is waiting.
ProvisioningOperationWaiting ProvisioningOperation = "Waiting"
)
// PossibleProvisioningOperationValues returns the possible values for the ProvisioningOperation const type.
func PossibleProvisioningOperationValues() []ProvisioningOperation {
return []ProvisioningOperation{
ProvisioningOperationNotSpecified,
ProvisioningOperationAction,
ProvisioningOperationAzureAsyncOperationWaiting,
ProvisioningOperationCreate,
ProvisioningOperationDelete,
ProvisioningOperationWaiting,
ProvisioningOperationAzureAsyncOperationWaiting,
ProvisioningOperationResourceCacheWaiting,
ProvisioningOperationAction,
ProvisioningOperationRead,
ProvisioningOperationEvaluateDeploymentOutput,
ProvisioningOperationDeploymentCleanup,
ProvisioningOperationEvaluateDeploymentOutput,
ProvisioningOperationNotSpecified,
ProvisioningOperationRead,
ProvisioningOperationResourceCacheWaiting,
ProvisioningOperationWaiting,
}
}
@ -347,19 +347,19 @@ func PossibleProvisioningStateValues() []ProvisioningState {
type ResourceIdentityType string
const (
ResourceIdentityTypeSystemAssigned ResourceIdentityType = "SystemAssigned"
ResourceIdentityTypeUserAssigned ResourceIdentityType = "UserAssigned"
ResourceIdentityTypeSystemAssignedUserAssigned ResourceIdentityType = "SystemAssigned, UserAssigned"
ResourceIdentityTypeNone ResourceIdentityType = "None"
ResourceIdentityTypeSystemAssigned ResourceIdentityType = "SystemAssigned"
ResourceIdentityTypeSystemAssignedUserAssigned ResourceIdentityType = "SystemAssigned, UserAssigned"
ResourceIdentityTypeUserAssigned ResourceIdentityType = "UserAssigned"
)
// PossibleResourceIdentityTypeValues returns the possible values for the ResourceIdentityType const type.
func PossibleResourceIdentityTypeValues() []ResourceIdentityType {
return []ResourceIdentityType{
ResourceIdentityTypeSystemAssigned,
ResourceIdentityTypeUserAssigned,
ResourceIdentityTypeSystemAssignedUserAssigned,
ResourceIdentityTypeNone,
ResourceIdentityTypeSystemAssigned,
ResourceIdentityTypeSystemAssignedUserAssigned,
ResourceIdentityTypeUserAssigned,
}
}
@ -389,14 +389,14 @@ func PossibleTagsPatchOperationValues() []TagsPatchOperation {
type WhatIfResultFormat string
const (
WhatIfResultFormatResourceIDOnly WhatIfResultFormat = "ResourceIdOnly"
WhatIfResultFormatFullResourcePayloads WhatIfResultFormat = "FullResourcePayloads"
WhatIfResultFormatResourceIDOnly WhatIfResultFormat = "ResourceIdOnly"
)
// PossibleWhatIfResultFormatValues returns the possible values for the WhatIfResultFormat const type.
func PossibleWhatIfResultFormatValues() []WhatIfResultFormat {
return []WhatIfResultFormat{
WhatIfResultFormatResourceIDOnly,
WhatIfResultFormatFullResourcePayloads,
WhatIfResultFormatResourceIDOnly,
}
}

View File

@ -3,7 +3,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
package armresources
@ -13,8 +13,6 @@ import (
"errors"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
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/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"net/http"
@ -26,56 +24,55 @@ import (
// DeploymentOperationsClient contains the methods for the DeploymentOperations group.
// Don't use this type directly, use NewDeploymentOperationsClient() instead.
type DeploymentOperationsClient struct {
host string
internal *arm.Client
subscriptionID string
pl runtime.Pipeline
}
// NewDeploymentOperationsClient creates a new instance of DeploymentOperationsClient with the specified values.
// subscriptionID - The Microsoft Azure subscription ID.
// credential - used to authorize requests. Usually a credential from azidentity.
// options - pass nil to accept the default values.
// - subscriptionID - The Microsoft Azure subscription ID.
// - credential - used to authorize requests. Usually a credential from azidentity.
// - options - pass nil to accept the default values.
func NewDeploymentOperationsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*DeploymentOperationsClient, error) {
if options == nil {
options = &arm.ClientOptions{}
}
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, credential, runtime.PipelineOptions{}, options)
cl, err := arm.NewClient(moduleName, moduleVersion, credential, options)
if err != nil {
return nil, err
}
client := &DeploymentOperationsClient{
subscriptionID: subscriptionID,
host: ep,
pl: pl,
internal: cl,
}
return client, nil
}
// Get - Gets a deployments operation.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceGroupName - The name of the resource group. The name is case insensitive.
// deploymentName - The name of the deployment.
// operationID - The ID of the operation to get.
// options - DeploymentOperationsClientGetOptions contains the optional parameters for the DeploymentOperationsClient.Get
// method.
// - resourceGroupName - The name of the resource group. The name is case insensitive.
// - deploymentName - The name of the deployment.
// - operationID - The ID of the operation to get.
// - options - DeploymentOperationsClientGetOptions contains the optional parameters for the DeploymentOperationsClient.Get
// method.
func (client *DeploymentOperationsClient) Get(ctx context.Context, resourceGroupName string, deploymentName string, operationID string, options *DeploymentOperationsClientGetOptions) (DeploymentOperationsClientGetResponse, error) {
var err error
const operationName = "DeploymentOperationsClient.Get"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.getCreateRequest(ctx, resourceGroupName, deploymentName, operationID, options)
if err != nil {
return DeploymentOperationsClientGetResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return DeploymentOperationsClientGetResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return DeploymentOperationsClientGetResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return DeploymentOperationsClientGetResponse{}, err
}
return client.getHandleResponse(resp)
resp, err := client.getHandleResponse(httpResp)
return resp, err
}
// getCreateRequest creates the Get request.
@ -97,7 +94,7 @@ func (client *DeploymentOperationsClient) getCreateRequest(ctx context.Context,
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -119,25 +116,33 @@ func (client *DeploymentOperationsClient) getHandleResponse(resp *http.Response)
// GetAtManagementGroupScope - Gets a deployments operation.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// groupID - The management group ID.
// deploymentName - The name of the deployment.
// operationID - The ID of the operation to get.
// options - DeploymentOperationsClientGetAtManagementGroupScopeOptions contains the optional parameters for the DeploymentOperationsClient.GetAtManagementGroupScope
// method.
// - groupID - The management group ID.
// - deploymentName - The name of the deployment.
// - operationID - The ID of the operation to get.
// - options - DeploymentOperationsClientGetAtManagementGroupScopeOptions contains the optional parameters for the DeploymentOperationsClient.GetAtManagementGroupScope
// method.
func (client *DeploymentOperationsClient) GetAtManagementGroupScope(ctx context.Context, groupID string, deploymentName string, operationID string, options *DeploymentOperationsClientGetAtManagementGroupScopeOptions) (DeploymentOperationsClientGetAtManagementGroupScopeResponse, error) {
var err error
const operationName = "DeploymentOperationsClient.GetAtManagementGroupScope"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.getAtManagementGroupScopeCreateRequest(ctx, groupID, deploymentName, operationID, options)
if err != nil {
return DeploymentOperationsClientGetAtManagementGroupScopeResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return DeploymentOperationsClientGetAtManagementGroupScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return DeploymentOperationsClientGetAtManagementGroupScopeResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return DeploymentOperationsClientGetAtManagementGroupScopeResponse{}, err
}
return client.getAtManagementGroupScopeHandleResponse(resp)
resp, err := client.getAtManagementGroupScopeHandleResponse(httpResp)
return resp, err
}
// getAtManagementGroupScopeCreateRequest creates the GetAtManagementGroupScope request.
@ -155,7 +160,7 @@ func (client *DeploymentOperationsClient) getAtManagementGroupScopeCreateRequest
return nil, errors.New("parameter operationID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{operationId}", url.PathEscape(operationID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -177,25 +182,33 @@ func (client *DeploymentOperationsClient) getAtManagementGroupScopeHandleRespons
// GetAtScope - Gets a deployments operation.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// scope - The resource scope.
// deploymentName - The name of the deployment.
// operationID - The ID of the operation to get.
// options - DeploymentOperationsClientGetAtScopeOptions contains the optional parameters for the DeploymentOperationsClient.GetAtScope
// method.
// - scope - The resource scope.
// - deploymentName - The name of the deployment.
// - operationID - The ID of the operation to get.
// - options - DeploymentOperationsClientGetAtScopeOptions contains the optional parameters for the DeploymentOperationsClient.GetAtScope
// method.
func (client *DeploymentOperationsClient) GetAtScope(ctx context.Context, scope string, deploymentName string, operationID string, options *DeploymentOperationsClientGetAtScopeOptions) (DeploymentOperationsClientGetAtScopeResponse, error) {
var err error
const operationName = "DeploymentOperationsClient.GetAtScope"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.getAtScopeCreateRequest(ctx, scope, deploymentName, operationID, options)
if err != nil {
return DeploymentOperationsClientGetAtScopeResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return DeploymentOperationsClientGetAtScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return DeploymentOperationsClientGetAtScopeResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return DeploymentOperationsClientGetAtScopeResponse{}, err
}
return client.getAtScopeHandleResponse(resp)
resp, err := client.getAtScopeHandleResponse(httpResp)
return resp, err
}
// getAtScopeCreateRequest creates the GetAtScope request.
@ -210,7 +223,7 @@ func (client *DeploymentOperationsClient) getAtScopeCreateRequest(ctx context.Co
return nil, errors.New("parameter operationID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{operationId}", url.PathEscape(operationID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -232,24 +245,32 @@ func (client *DeploymentOperationsClient) getAtScopeHandleResponse(resp *http.Re
// GetAtSubscriptionScope - Gets a deployments operation.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// deploymentName - The name of the deployment.
// operationID - The ID of the operation to get.
// options - DeploymentOperationsClientGetAtSubscriptionScopeOptions contains the optional parameters for the DeploymentOperationsClient.GetAtSubscriptionScope
// method.
// - deploymentName - The name of the deployment.
// - operationID - The ID of the operation to get.
// - options - DeploymentOperationsClientGetAtSubscriptionScopeOptions contains the optional parameters for the DeploymentOperationsClient.GetAtSubscriptionScope
// method.
func (client *DeploymentOperationsClient) GetAtSubscriptionScope(ctx context.Context, deploymentName string, operationID string, options *DeploymentOperationsClientGetAtSubscriptionScopeOptions) (DeploymentOperationsClientGetAtSubscriptionScopeResponse, error) {
var err error
const operationName = "DeploymentOperationsClient.GetAtSubscriptionScope"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.getAtSubscriptionScopeCreateRequest(ctx, deploymentName, operationID, options)
if err != nil {
return DeploymentOperationsClientGetAtSubscriptionScopeResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return DeploymentOperationsClientGetAtSubscriptionScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return DeploymentOperationsClientGetAtSubscriptionScopeResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return DeploymentOperationsClientGetAtSubscriptionScopeResponse{}, err
}
return client.getAtSubscriptionScopeHandleResponse(resp)
resp, err := client.getAtSubscriptionScopeHandleResponse(httpResp)
return resp, err
}
// getAtSubscriptionScopeCreateRequest creates the GetAtSubscriptionScope request.
@ -267,7 +288,7 @@ func (client *DeploymentOperationsClient) getAtSubscriptionScopeCreateRequest(ct
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -289,24 +310,32 @@ func (client *DeploymentOperationsClient) getAtSubscriptionScopeHandleResponse(r
// GetAtTenantScope - Gets a deployments operation.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// deploymentName - The name of the deployment.
// operationID - The ID of the operation to get.
// options - DeploymentOperationsClientGetAtTenantScopeOptions contains the optional parameters for the DeploymentOperationsClient.GetAtTenantScope
// method.
// - deploymentName - The name of the deployment.
// - operationID - The ID of the operation to get.
// - options - DeploymentOperationsClientGetAtTenantScopeOptions contains the optional parameters for the DeploymentOperationsClient.GetAtTenantScope
// method.
func (client *DeploymentOperationsClient) GetAtTenantScope(ctx context.Context, deploymentName string, operationID string, options *DeploymentOperationsClientGetAtTenantScopeOptions) (DeploymentOperationsClientGetAtTenantScopeResponse, error) {
var err error
const operationName = "DeploymentOperationsClient.GetAtTenantScope"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.getAtTenantScopeCreateRequest(ctx, deploymentName, operationID, options)
if err != nil {
return DeploymentOperationsClientGetAtTenantScopeResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return DeploymentOperationsClientGetAtTenantScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return DeploymentOperationsClientGetAtTenantScopeResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return DeploymentOperationsClientGetAtTenantScopeResponse{}, err
}
return client.getAtTenantScopeHandleResponse(resp)
resp, err := client.getAtTenantScopeHandleResponse(httpResp)
return resp, err
}
// getAtTenantScopeCreateRequest creates the GetAtTenantScope request.
@ -320,7 +349,7 @@ func (client *DeploymentOperationsClient) getAtTenantScopeCreateRequest(ctx cont
return nil, errors.New("parameter operationID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{operationId}", url.PathEscape(operationID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -341,37 +370,32 @@ func (client *DeploymentOperationsClient) getAtTenantScopeHandleResponse(resp *h
}
// NewListPager - Gets all deployments operations for a deployment.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceGroupName - The name of the resource group. The name is case insensitive.
// deploymentName - The name of the deployment.
// options - DeploymentOperationsClientListOptions contains the optional parameters for the DeploymentOperationsClient.List
// method.
// - resourceGroupName - The name of the resource group. The name is case insensitive.
// - deploymentName - The name of the deployment.
// - options - DeploymentOperationsClientListOptions contains the optional parameters for the DeploymentOperationsClient.NewListPager
// method.
func (client *DeploymentOperationsClient) NewListPager(resourceGroupName string, deploymentName string, options *DeploymentOperationsClientListOptions) *runtime.Pager[DeploymentOperationsClientListResponse] {
return runtime.NewPager(runtime.PagingHandler[DeploymentOperationsClientListResponse]{
More: func(page DeploymentOperationsClientListResponse) bool {
return page.NextLink != nil && len(*page.NextLink) > 0
},
Fetcher: func(ctx context.Context, page *DeploymentOperationsClientListResponse) (DeploymentOperationsClientListResponse, error) {
var req *policy.Request
var err error
if page == nil {
req, err = client.listCreateRequest(ctx, resourceGroupName, deploymentName, options)
} else {
req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink)
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DeploymentOperationsClient.NewListPager")
nextLink := ""
if page != nil {
nextLink = *page.NextLink
}
resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) {
return client.listCreateRequest(ctx, resourceGroupName, deploymentName, options)
}, nil)
if err != nil {
return DeploymentOperationsClientListResponse{}, err
}
resp, err := client.pl.Do(req)
if err != nil {
return DeploymentOperationsClientListResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return DeploymentOperationsClientListResponse{}, runtime.NewResponseError(resp)
}
return client.listHandleResponse(resp)
},
Tracer: client.internal.Tracer(),
})
}
@ -390,7 +414,7 @@ func (client *DeploymentOperationsClient) listCreateRequest(ctx context.Context,
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -414,37 +438,32 @@ func (client *DeploymentOperationsClient) listHandleResponse(resp *http.Response
}
// NewListAtManagementGroupScopePager - Gets all deployments operations for a deployment.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// groupID - The management group ID.
// deploymentName - The name of the deployment.
// options - DeploymentOperationsClientListAtManagementGroupScopeOptions contains the optional parameters for the DeploymentOperationsClient.ListAtManagementGroupScope
// method.
// - groupID - The management group ID.
// - deploymentName - The name of the deployment.
// - options - DeploymentOperationsClientListAtManagementGroupScopeOptions contains the optional parameters for the DeploymentOperationsClient.NewListAtManagementGroupScopePager
// method.
func (client *DeploymentOperationsClient) NewListAtManagementGroupScopePager(groupID string, deploymentName string, options *DeploymentOperationsClientListAtManagementGroupScopeOptions) *runtime.Pager[DeploymentOperationsClientListAtManagementGroupScopeResponse] {
return runtime.NewPager(runtime.PagingHandler[DeploymentOperationsClientListAtManagementGroupScopeResponse]{
More: func(page DeploymentOperationsClientListAtManagementGroupScopeResponse) bool {
return page.NextLink != nil && len(*page.NextLink) > 0
},
Fetcher: func(ctx context.Context, page *DeploymentOperationsClientListAtManagementGroupScopeResponse) (DeploymentOperationsClientListAtManagementGroupScopeResponse, error) {
var req *policy.Request
var err error
if page == nil {
req, err = client.listAtManagementGroupScopeCreateRequest(ctx, groupID, deploymentName, options)
} else {
req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink)
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DeploymentOperationsClient.NewListAtManagementGroupScopePager")
nextLink := ""
if page != nil {
nextLink = *page.NextLink
}
resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) {
return client.listAtManagementGroupScopeCreateRequest(ctx, groupID, deploymentName, options)
}, nil)
if err != nil {
return DeploymentOperationsClientListAtManagementGroupScopeResponse{}, err
}
resp, err := client.pl.Do(req)
if err != nil {
return DeploymentOperationsClientListAtManagementGroupScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return DeploymentOperationsClientListAtManagementGroupScopeResponse{}, runtime.NewResponseError(resp)
}
return client.listAtManagementGroupScopeHandleResponse(resp)
},
Tracer: client.internal.Tracer(),
})
}
@ -459,7 +478,7 @@ func (client *DeploymentOperationsClient) listAtManagementGroupScopeCreateReques
return nil, errors.New("parameter deploymentName cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -483,37 +502,32 @@ func (client *DeploymentOperationsClient) listAtManagementGroupScopeHandleRespon
}
// NewListAtScopePager - Gets all deployments operations for a deployment.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// scope - The resource scope.
// deploymentName - The name of the deployment.
// options - DeploymentOperationsClientListAtScopeOptions contains the optional parameters for the DeploymentOperationsClient.ListAtScope
// method.
// - scope - The resource scope.
// - deploymentName - The name of the deployment.
// - options - DeploymentOperationsClientListAtScopeOptions contains the optional parameters for the DeploymentOperationsClient.NewListAtScopePager
// method.
func (client *DeploymentOperationsClient) NewListAtScopePager(scope string, deploymentName string, options *DeploymentOperationsClientListAtScopeOptions) *runtime.Pager[DeploymentOperationsClientListAtScopeResponse] {
return runtime.NewPager(runtime.PagingHandler[DeploymentOperationsClientListAtScopeResponse]{
More: func(page DeploymentOperationsClientListAtScopeResponse) bool {
return page.NextLink != nil && len(*page.NextLink) > 0
},
Fetcher: func(ctx context.Context, page *DeploymentOperationsClientListAtScopeResponse) (DeploymentOperationsClientListAtScopeResponse, error) {
var req *policy.Request
var err error
if page == nil {
req, err = client.listAtScopeCreateRequest(ctx, scope, deploymentName, options)
} else {
req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink)
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DeploymentOperationsClient.NewListAtScopePager")
nextLink := ""
if page != nil {
nextLink = *page.NextLink
}
resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) {
return client.listAtScopeCreateRequest(ctx, scope, deploymentName, options)
}, nil)
if err != nil {
return DeploymentOperationsClientListAtScopeResponse{}, err
}
resp, err := client.pl.Do(req)
if err != nil {
return DeploymentOperationsClientListAtScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return DeploymentOperationsClientListAtScopeResponse{}, runtime.NewResponseError(resp)
}
return client.listAtScopeHandleResponse(resp)
},
Tracer: client.internal.Tracer(),
})
}
@ -525,7 +539,7 @@ func (client *DeploymentOperationsClient) listAtScopeCreateRequest(ctx context.C
return nil, errors.New("parameter deploymentName cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -549,36 +563,31 @@ func (client *DeploymentOperationsClient) listAtScopeHandleResponse(resp *http.R
}
// NewListAtSubscriptionScopePager - Gets all deployments operations for a deployment.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// deploymentName - The name of the deployment.
// options - DeploymentOperationsClientListAtSubscriptionScopeOptions contains the optional parameters for the DeploymentOperationsClient.ListAtSubscriptionScope
// method.
// - deploymentName - The name of the deployment.
// - options - DeploymentOperationsClientListAtSubscriptionScopeOptions contains the optional parameters for the DeploymentOperationsClient.NewListAtSubscriptionScopePager
// method.
func (client *DeploymentOperationsClient) NewListAtSubscriptionScopePager(deploymentName string, options *DeploymentOperationsClientListAtSubscriptionScopeOptions) *runtime.Pager[DeploymentOperationsClientListAtSubscriptionScopeResponse] {
return runtime.NewPager(runtime.PagingHandler[DeploymentOperationsClientListAtSubscriptionScopeResponse]{
More: func(page DeploymentOperationsClientListAtSubscriptionScopeResponse) bool {
return page.NextLink != nil && len(*page.NextLink) > 0
},
Fetcher: func(ctx context.Context, page *DeploymentOperationsClientListAtSubscriptionScopeResponse) (DeploymentOperationsClientListAtSubscriptionScopeResponse, error) {
var req *policy.Request
var err error
if page == nil {
req, err = client.listAtSubscriptionScopeCreateRequest(ctx, deploymentName, options)
} else {
req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink)
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DeploymentOperationsClient.NewListAtSubscriptionScopePager")
nextLink := ""
if page != nil {
nextLink = *page.NextLink
}
resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) {
return client.listAtSubscriptionScopeCreateRequest(ctx, deploymentName, options)
}, nil)
if err != nil {
return DeploymentOperationsClientListAtSubscriptionScopeResponse{}, err
}
resp, err := client.pl.Do(req)
if err != nil {
return DeploymentOperationsClientListAtSubscriptionScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return DeploymentOperationsClientListAtSubscriptionScopeResponse{}, runtime.NewResponseError(resp)
}
return client.listAtSubscriptionScopeHandleResponse(resp)
},
Tracer: client.internal.Tracer(),
})
}
@ -593,7 +602,7 @@ func (client *DeploymentOperationsClient) listAtSubscriptionScopeCreateRequest(c
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -617,36 +626,31 @@ func (client *DeploymentOperationsClient) listAtSubscriptionScopeHandleResponse(
}
// NewListAtTenantScopePager - Gets all deployments operations for a deployment.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// deploymentName - The name of the deployment.
// options - DeploymentOperationsClientListAtTenantScopeOptions contains the optional parameters for the DeploymentOperationsClient.ListAtTenantScope
// method.
// - deploymentName - The name of the deployment.
// - options - DeploymentOperationsClientListAtTenantScopeOptions contains the optional parameters for the DeploymentOperationsClient.NewListAtTenantScopePager
// method.
func (client *DeploymentOperationsClient) NewListAtTenantScopePager(deploymentName string, options *DeploymentOperationsClientListAtTenantScopeOptions) *runtime.Pager[DeploymentOperationsClientListAtTenantScopeResponse] {
return runtime.NewPager(runtime.PagingHandler[DeploymentOperationsClientListAtTenantScopeResponse]{
More: func(page DeploymentOperationsClientListAtTenantScopeResponse) bool {
return page.NextLink != nil && len(*page.NextLink) > 0
},
Fetcher: func(ctx context.Context, page *DeploymentOperationsClientListAtTenantScopeResponse) (DeploymentOperationsClientListAtTenantScopeResponse, error) {
var req *policy.Request
var err error
if page == nil {
req, err = client.listAtTenantScopeCreateRequest(ctx, deploymentName, options)
} else {
req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink)
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "DeploymentOperationsClient.NewListAtTenantScopePager")
nextLink := ""
if page != nil {
nextLink = *page.NextLink
}
resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) {
return client.listAtTenantScopeCreateRequest(ctx, deploymentName, options)
}, nil)
if err != nil {
return DeploymentOperationsClientListAtTenantScopeResponse{}, err
}
resp, err := client.pl.Do(req)
if err != nil {
return DeploymentOperationsClientListAtTenantScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return DeploymentOperationsClientListAtTenantScopeResponse{}, runtime.NewResponseError(resp)
}
return client.listAtTenantScopeHandleResponse(resp)
},
Tracer: client.internal.Tracer(),
})
}
@ -657,7 +661,7 @@ func (client *DeploymentOperationsClient) listAtTenantScopeCreateRequest(ctx con
return nil, errors.New("parameter deploymentName cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{deploymentName}", url.PathEscape(deploymentName))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
package armresources
@ -12,8 +12,6 @@ import (
"context"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
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/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"net/http"
@ -22,68 +20,54 @@ import (
// OperationsClient contains the methods for the Operations group.
// Don't use this type directly, use NewOperationsClient() instead.
type OperationsClient struct {
host string
pl runtime.Pipeline
internal *arm.Client
}
// NewOperationsClient creates a new instance of OperationsClient with the specified values.
// credential - used to authorize requests. Usually a credential from azidentity.
// options - pass nil to accept the default values.
// - credential - used to authorize requests. Usually a credential from azidentity.
// - options - pass nil to accept the default values.
func NewOperationsClient(credential azcore.TokenCredential, options *arm.ClientOptions) (*OperationsClient, error) {
if options == nil {
options = &arm.ClientOptions{}
}
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, credential, runtime.PipelineOptions{}, options)
cl, err := arm.NewClient(moduleName, moduleVersion, credential, options)
if err != nil {
return nil, err
}
client := &OperationsClient{
host: ep,
pl: pl,
internal: cl,
}
return client, nil
}
// NewListPager - Lists all of the available Microsoft.Resources REST API operations.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// options - OperationsClientListOptions contains the optional parameters for the OperationsClient.List method.
// - options - OperationsClientListOptions contains the optional parameters for the OperationsClient.NewListPager method.
func (client *OperationsClient) NewListPager(options *OperationsClientListOptions) *runtime.Pager[OperationsClientListResponse] {
return runtime.NewPager(runtime.PagingHandler[OperationsClientListResponse]{
More: func(page OperationsClientListResponse) bool {
return page.NextLink != nil && len(*page.NextLink) > 0
},
Fetcher: func(ctx context.Context, page *OperationsClientListResponse) (OperationsClientListResponse, error) {
var req *policy.Request
var err error
if page == nil {
req, err = client.listCreateRequest(ctx, options)
} else {
req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink)
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "OperationsClient.NewListPager")
nextLink := ""
if page != nil {
nextLink = *page.NextLink
}
resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) {
return client.listCreateRequest(ctx, options)
}, nil)
if err != nil {
return OperationsClientListResponse{}, err
}
resp, err := client.pl.Do(req)
if err != nil {
return OperationsClientListResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return OperationsClientListResponse{}, runtime.NewResponseError(resp)
}
return client.listHandleResponse(resp)
},
Tracer: client.internal.Tracer(),
})
}
// listCreateRequest creates the List request.
func (client *OperationsClient) listCreateRequest(ctx context.Context, options *OperationsClientListOptions) (*policy.Request, error) {
urlPath := "/providers/Microsoft.Resources/operations"
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}

View File

@ -0,0 +1,654 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
package armresources
// ClientBeginCreateOrUpdateByIDOptions contains the optional parameters for the Client.BeginCreateOrUpdateByID method.
type ClientBeginCreateOrUpdateByIDOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// ClientBeginCreateOrUpdateOptions contains the optional parameters for the Client.BeginCreateOrUpdate method.
type ClientBeginCreateOrUpdateOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// ClientBeginDeleteByIDOptions contains the optional parameters for the Client.BeginDeleteByID method.
type ClientBeginDeleteByIDOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// ClientBeginDeleteOptions contains the optional parameters for the Client.BeginDelete method.
type ClientBeginDeleteOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// ClientBeginMoveResourcesOptions contains the optional parameters for the Client.BeginMoveResources method.
type ClientBeginMoveResourcesOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// ClientBeginUpdateByIDOptions contains the optional parameters for the Client.BeginUpdateByID method.
type ClientBeginUpdateByIDOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// ClientBeginUpdateOptions contains the optional parameters for the Client.BeginUpdate method.
type ClientBeginUpdateOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// ClientBeginValidateMoveResourcesOptions contains the optional parameters for the Client.BeginValidateMoveResources method.
type ClientBeginValidateMoveResourcesOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// ClientCheckExistenceByIDOptions contains the optional parameters for the Client.CheckExistenceByID method.
type ClientCheckExistenceByIDOptions struct {
// placeholder for future optional parameters
}
// ClientCheckExistenceOptions contains the optional parameters for the Client.CheckExistence method.
type ClientCheckExistenceOptions struct {
// placeholder for future optional parameters
}
// ClientGetByIDOptions contains the optional parameters for the Client.GetByID method.
type ClientGetByIDOptions struct {
// placeholder for future optional parameters
}
// ClientGetOptions contains the optional parameters for the Client.Get method.
type ClientGetOptions struct {
// placeholder for future optional parameters
}
// ClientListByResourceGroupOptions contains the optional parameters for the Client.NewListByResourceGroupPager method.
type ClientListByResourceGroupOptions struct {
// Comma-separated list of additional properties to be included in the response. Valid values include createdTime, changedTime
// and provisioningState. For example, $expand=createdTime,changedTime.
Expand *string
// The filter to apply on the operation.
// The properties you can use for eq (equals) or ne (not equals) are: location, resourceType, name, resourceGroup, identity,
// identity/principalId, plan, plan/publisher, plan/product, plan/name,
// plan/version, and plan/promotionCode.
// For example, to filter by a resource type, use: $filter=resourceType eq 'Microsoft.Network/virtualNetworks'
// You can use substringof(value, property) in the filter. The properties you can use for substring are: name and resourceGroup.
// For example, to get all resources with 'demo' anywhere in the name, use: $filter=substringof('demo', name)
// You can link more than one substringof together by adding and/or operators.
// You can filter by tag names and values. For example, to filter for a tag name and value, use $filter=tagName eq 'tag1'
// and tagValue eq 'Value1'. When you filter by a tag name and value, the tags for
// each resource are not returned in the results.
// You can use some properties together when filtering. The combinations you can use are: substringof and/or resourceType,
// plan and plan/publisher and plan/name, identity and identity/principalId.
Filter *string
// The number of results to return. If null is passed, returns all resources.
Top *int32
}
// ClientListOptions contains the optional parameters for the Client.NewListPager method.
type ClientListOptions struct {
// Comma-separated list of additional properties to be included in the response. Valid values include createdTime, changedTime
// and provisioningState. For example, $expand=createdTime,changedTime.
Expand *string
// The filter to apply on the operation.
// Filter comparison operators include eq (equals) and ne (not equals) and may be used with the following properties: location,
// resourceType, name, resourceGroup, identity, identity/principalId, plan,
// plan/publisher, plan/product, plan/name, plan/version, and plan/promotionCode.
// For example, to filter by a resource type, use $filter=resourceType eq 'Microsoft.Network/virtualNetworks'
// substringof(value, property) can be used to filter for substrings of the following currently-supported properties: name
// and resourceGroup
// For example, to get all resources with 'demo' anywhere in the resource name, use $filter=substringof('demo', name)
// Multiple substring operations can also be combined using and/or operators.
// Note that any truncated number of results queried via $top may also not be compatible when using a filter.
// Resources can be filtered by tag names and values. For example, to filter for a tag name and value, use $filter=tagName
// eq 'tag1' and tagValue eq 'Value1'. Note that when resources are filtered by tag
// name and value, the original tags for each resource will not be returned in the results. Any list of additional properties
// queried via $expand may also not be compatible when filtering by tag
// names/values.
// For tag names only, resources can be filtered by prefix using the following syntax: $filter=startswith(tagName, 'depart').
// This query will return all resources with a tag name prefixed by the phrase
// depart (i.e.department, departureDate, departureTime, etc.)
// Note that some properties can be combined when filtering resources, which include the following: substringof() and/or resourceType,
// plan and plan/publisher and plan/name, and identity and
// identity/principalId.
Filter *string
// The number of results to return. If null is passed, returns all resources.
Top *int32
}
// DeploymentOperationsClientGetAtManagementGroupScopeOptions contains the optional parameters for the DeploymentOperationsClient.GetAtManagementGroupScope
// method.
type DeploymentOperationsClientGetAtManagementGroupScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentOperationsClientGetAtScopeOptions contains the optional parameters for the DeploymentOperationsClient.GetAtScope
// method.
type DeploymentOperationsClientGetAtScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentOperationsClientGetAtSubscriptionScopeOptions contains the optional parameters for the DeploymentOperationsClient.GetAtSubscriptionScope
// method.
type DeploymentOperationsClientGetAtSubscriptionScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentOperationsClientGetAtTenantScopeOptions contains the optional parameters for the DeploymentOperationsClient.GetAtTenantScope
// method.
type DeploymentOperationsClientGetAtTenantScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentOperationsClientGetOptions contains the optional parameters for the DeploymentOperationsClient.Get method.
type DeploymentOperationsClientGetOptions struct {
// placeholder for future optional parameters
}
// DeploymentOperationsClientListAtManagementGroupScopeOptions contains the optional parameters for the DeploymentOperationsClient.NewListAtManagementGroupScopePager
// method.
type DeploymentOperationsClientListAtManagementGroupScopeOptions struct {
// The number of results to return.
Top *int32
}
// DeploymentOperationsClientListAtScopeOptions contains the optional parameters for the DeploymentOperationsClient.NewListAtScopePager
// method.
type DeploymentOperationsClientListAtScopeOptions struct {
// The number of results to return.
Top *int32
}
// DeploymentOperationsClientListAtSubscriptionScopeOptions contains the optional parameters for the DeploymentOperationsClient.NewListAtSubscriptionScopePager
// method.
type DeploymentOperationsClientListAtSubscriptionScopeOptions struct {
// The number of results to return.
Top *int32
}
// DeploymentOperationsClientListAtTenantScopeOptions contains the optional parameters for the DeploymentOperationsClient.NewListAtTenantScopePager
// method.
type DeploymentOperationsClientListAtTenantScopeOptions struct {
// The number of results to return.
Top *int32
}
// DeploymentOperationsClientListOptions contains the optional parameters for the DeploymentOperationsClient.NewListPager
// method.
type DeploymentOperationsClientListOptions struct {
// The number of results to return.
Top *int32
}
// DeploymentsClientBeginCreateOrUpdateAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.BeginCreateOrUpdateAtManagementGroupScope
// method.
type DeploymentsClientBeginCreateOrUpdateAtManagementGroupScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginCreateOrUpdateAtScopeOptions contains the optional parameters for the DeploymentsClient.BeginCreateOrUpdateAtScope
// method.
type DeploymentsClientBeginCreateOrUpdateAtScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginCreateOrUpdateAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.BeginCreateOrUpdateAtSubscriptionScope
// method.
type DeploymentsClientBeginCreateOrUpdateAtSubscriptionScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginCreateOrUpdateAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.BeginCreateOrUpdateAtTenantScope
// method.
type DeploymentsClientBeginCreateOrUpdateAtTenantScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginCreateOrUpdateOptions contains the optional parameters for the DeploymentsClient.BeginCreateOrUpdate
// method.
type DeploymentsClientBeginCreateOrUpdateOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginDeleteAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.BeginDeleteAtManagementGroupScope
// method.
type DeploymentsClientBeginDeleteAtManagementGroupScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginDeleteAtScopeOptions contains the optional parameters for the DeploymentsClient.BeginDeleteAtScope
// method.
type DeploymentsClientBeginDeleteAtScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginDeleteAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.BeginDeleteAtSubscriptionScope
// method.
type DeploymentsClientBeginDeleteAtSubscriptionScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginDeleteAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.BeginDeleteAtTenantScope
// method.
type DeploymentsClientBeginDeleteAtTenantScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginDeleteOptions contains the optional parameters for the DeploymentsClient.BeginDelete method.
type DeploymentsClientBeginDeleteOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginValidateAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.BeginValidateAtManagementGroupScope
// method.
type DeploymentsClientBeginValidateAtManagementGroupScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginValidateAtScopeOptions contains the optional parameters for the DeploymentsClient.BeginValidateAtScope
// method.
type DeploymentsClientBeginValidateAtScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginValidateAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.BeginValidateAtSubscriptionScope
// method.
type DeploymentsClientBeginValidateAtSubscriptionScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginValidateAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.BeginValidateAtTenantScope
// method.
type DeploymentsClientBeginValidateAtTenantScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginValidateOptions contains the optional parameters for the DeploymentsClient.BeginValidate method.
type DeploymentsClientBeginValidateOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginWhatIfAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.BeginWhatIfAtManagementGroupScope
// method.
type DeploymentsClientBeginWhatIfAtManagementGroupScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginWhatIfAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.BeginWhatIfAtSubscriptionScope
// method.
type DeploymentsClientBeginWhatIfAtSubscriptionScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginWhatIfAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.BeginWhatIfAtTenantScope
// method.
type DeploymentsClientBeginWhatIfAtTenantScopeOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientBeginWhatIfOptions contains the optional parameters for the DeploymentsClient.BeginWhatIf method.
type DeploymentsClientBeginWhatIfOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// DeploymentsClientCalculateTemplateHashOptions contains the optional parameters for the DeploymentsClient.CalculateTemplateHash
// method.
type DeploymentsClientCalculateTemplateHashOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientCancelAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.CancelAtManagementGroupScope
// method.
type DeploymentsClientCancelAtManagementGroupScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientCancelAtScopeOptions contains the optional parameters for the DeploymentsClient.CancelAtScope method.
type DeploymentsClientCancelAtScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientCancelAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.CancelAtSubscriptionScope
// method.
type DeploymentsClientCancelAtSubscriptionScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientCancelAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.CancelAtTenantScope
// method.
type DeploymentsClientCancelAtTenantScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientCancelOptions contains the optional parameters for the DeploymentsClient.Cancel method.
type DeploymentsClientCancelOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientCheckExistenceAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.CheckExistenceAtManagementGroupScope
// method.
type DeploymentsClientCheckExistenceAtManagementGroupScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientCheckExistenceAtScopeOptions contains the optional parameters for the DeploymentsClient.CheckExistenceAtScope
// method.
type DeploymentsClientCheckExistenceAtScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientCheckExistenceAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.CheckExistenceAtSubscriptionScope
// method.
type DeploymentsClientCheckExistenceAtSubscriptionScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientCheckExistenceAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.CheckExistenceAtTenantScope
// method.
type DeploymentsClientCheckExistenceAtTenantScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientCheckExistenceOptions contains the optional parameters for the DeploymentsClient.CheckExistence method.
type DeploymentsClientCheckExistenceOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientExportTemplateAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.ExportTemplateAtManagementGroupScope
// method.
type DeploymentsClientExportTemplateAtManagementGroupScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientExportTemplateAtScopeOptions contains the optional parameters for the DeploymentsClient.ExportTemplateAtScope
// method.
type DeploymentsClientExportTemplateAtScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientExportTemplateAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.ExportTemplateAtSubscriptionScope
// method.
type DeploymentsClientExportTemplateAtSubscriptionScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientExportTemplateAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.ExportTemplateAtTenantScope
// method.
type DeploymentsClientExportTemplateAtTenantScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientExportTemplateOptions contains the optional parameters for the DeploymentsClient.ExportTemplate method.
type DeploymentsClientExportTemplateOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientGetAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.GetAtManagementGroupScope
// method.
type DeploymentsClientGetAtManagementGroupScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientGetAtScopeOptions contains the optional parameters for the DeploymentsClient.GetAtScope method.
type DeploymentsClientGetAtScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientGetAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.GetAtSubscriptionScope
// method.
type DeploymentsClientGetAtSubscriptionScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientGetAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.GetAtTenantScope method.
type DeploymentsClientGetAtTenantScopeOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientGetOptions contains the optional parameters for the DeploymentsClient.Get method.
type DeploymentsClientGetOptions struct {
// placeholder for future optional parameters
}
// DeploymentsClientListAtManagementGroupScopeOptions contains the optional parameters for the DeploymentsClient.NewListAtManagementGroupScopePager
// method.
type DeploymentsClientListAtManagementGroupScopeOptions struct {
// The filter to apply on the operation. For example, you can use $filter=provisioningState eq '{state}'.
Filter *string
// The number of results to get. If null is passed, returns all deployments.
Top *int32
}
// DeploymentsClientListAtScopeOptions contains the optional parameters for the DeploymentsClient.NewListAtScopePager method.
type DeploymentsClientListAtScopeOptions struct {
// The filter to apply on the operation. For example, you can use $filter=provisioningState eq '{state}'.
Filter *string
// The number of results to get. If null is passed, returns all deployments.
Top *int32
}
// DeploymentsClientListAtSubscriptionScopeOptions contains the optional parameters for the DeploymentsClient.NewListAtSubscriptionScopePager
// method.
type DeploymentsClientListAtSubscriptionScopeOptions struct {
// The filter to apply on the operation. For example, you can use $filter=provisioningState eq '{state}'.
Filter *string
// The number of results to get. If null is passed, returns all deployments.
Top *int32
}
// DeploymentsClientListAtTenantScopeOptions contains the optional parameters for the DeploymentsClient.NewListAtTenantScopePager
// method.
type DeploymentsClientListAtTenantScopeOptions struct {
// The filter to apply on the operation. For example, you can use $filter=provisioningState eq '{state}'.
Filter *string
// The number of results to get. If null is passed, returns all deployments.
Top *int32
}
// DeploymentsClientListByResourceGroupOptions contains the optional parameters for the DeploymentsClient.NewListByResourceGroupPager
// method.
type DeploymentsClientListByResourceGroupOptions struct {
// The filter to apply on the operation. For example, you can use $filter=provisioningState eq '{state}'.
Filter *string
// The number of results to get. If null is passed, returns all deployments.
Top *int32
}
// OperationsClientListOptions contains the optional parameters for the OperationsClient.NewListPager method.
type OperationsClientListOptions struct {
// placeholder for future optional parameters
}
// ProviderResourceTypesClientListOptions contains the optional parameters for the ProviderResourceTypesClient.List method.
type ProviderResourceTypesClientListOptions struct {
// The $expand query parameter. For example, to include property aliases in response, use $expand=resourceTypes/aliases.
Expand *string
}
// ProvidersClientGetAtTenantScopeOptions contains the optional parameters for the ProvidersClient.GetAtTenantScope method.
type ProvidersClientGetAtTenantScopeOptions struct {
// The $expand query parameter. For example, to include property aliases in response, use $expand=resourceTypes/aliases.
Expand *string
}
// ProvidersClientGetOptions contains the optional parameters for the ProvidersClient.Get method.
type ProvidersClientGetOptions struct {
// The $expand query parameter. For example, to include property aliases in response, use $expand=resourceTypes/aliases.
Expand *string
}
// ProvidersClientListAtTenantScopeOptions contains the optional parameters for the ProvidersClient.NewListAtTenantScopePager
// method.
type ProvidersClientListAtTenantScopeOptions struct {
// The properties to include in the results. For example, use &$expand=metadata in the query string to retrieve resource provider
// metadata. To include property aliases in response, use
// $expand=resourceTypes/aliases.
Expand *string
}
// ProvidersClientListOptions contains the optional parameters for the ProvidersClient.NewListPager method.
type ProvidersClientListOptions struct {
// The properties to include in the results. For example, use &$expand=metadata in the query string to retrieve resource provider
// metadata. To include property aliases in response, use
// $expand=resourceTypes/aliases.
Expand *string
}
// ProvidersClientProviderPermissionsOptions contains the optional parameters for the ProvidersClient.ProviderPermissions
// method.
type ProvidersClientProviderPermissionsOptions struct {
// placeholder for future optional parameters
}
// ProvidersClientRegisterAtManagementGroupScopeOptions contains the optional parameters for the ProvidersClient.RegisterAtManagementGroupScope
// method.
type ProvidersClientRegisterAtManagementGroupScopeOptions struct {
// placeholder for future optional parameters
}
// ProvidersClientRegisterOptions contains the optional parameters for the ProvidersClient.Register method.
type ProvidersClientRegisterOptions struct {
// The third party consent for S2S.
Properties *ProviderRegistrationRequest
}
// ProvidersClientUnregisterOptions contains the optional parameters for the ProvidersClient.Unregister method.
type ProvidersClientUnregisterOptions struct {
// placeholder for future optional parameters
}
// ResourceGroupsClientBeginDeleteOptions contains the optional parameters for the ResourceGroupsClient.BeginDelete method.
type ResourceGroupsClientBeginDeleteOptions struct {
// The resource types you want to force delete. Currently, only the following is supported: forceDeletionTypes=Microsoft.Compute/virtualMachines,Microsoft.Compute/virtualMachineScaleSets
ForceDeletionTypes *string
// Resumes the LRO from the provided token.
ResumeToken string
}
// ResourceGroupsClientBeginExportTemplateOptions contains the optional parameters for the ResourceGroupsClient.BeginExportTemplate
// method.
type ResourceGroupsClientBeginExportTemplateOptions struct {
// Resumes the LRO from the provided token.
ResumeToken string
}
// ResourceGroupsClientCheckExistenceOptions contains the optional parameters for the ResourceGroupsClient.CheckExistence
// method.
type ResourceGroupsClientCheckExistenceOptions struct {
// placeholder for future optional parameters
}
// ResourceGroupsClientCreateOrUpdateOptions contains the optional parameters for the ResourceGroupsClient.CreateOrUpdate
// method.
type ResourceGroupsClientCreateOrUpdateOptions struct {
// placeholder for future optional parameters
}
// ResourceGroupsClientGetOptions contains the optional parameters for the ResourceGroupsClient.Get method.
type ResourceGroupsClientGetOptions struct {
// placeholder for future optional parameters
}
// ResourceGroupsClientListOptions contains the optional parameters for the ResourceGroupsClient.NewListPager method.
type ResourceGroupsClientListOptions struct {
// The filter to apply on the operation.
// You can filter by tag names and values. For example, to filter for a tag name and value, use $filter=tagName eq 'tag1'
// and tagValue eq 'Value1'
Filter *string
// The number of results to return. If null is passed, returns all resource groups.
Top *int32
}
// ResourceGroupsClientUpdateOptions contains the optional parameters for the ResourceGroupsClient.Update method.
type ResourceGroupsClientUpdateOptions struct {
// placeholder for future optional parameters
}
// TagsClientCreateOrUpdateAtScopeOptions contains the optional parameters for the TagsClient.CreateOrUpdateAtScope method.
type TagsClientCreateOrUpdateAtScopeOptions struct {
// placeholder for future optional parameters
}
// TagsClientCreateOrUpdateOptions contains the optional parameters for the TagsClient.CreateOrUpdate method.
type TagsClientCreateOrUpdateOptions struct {
// placeholder for future optional parameters
}
// TagsClientCreateOrUpdateValueOptions contains the optional parameters for the TagsClient.CreateOrUpdateValue method.
type TagsClientCreateOrUpdateValueOptions struct {
// placeholder for future optional parameters
}
// TagsClientDeleteAtScopeOptions contains the optional parameters for the TagsClient.DeleteAtScope method.
type TagsClientDeleteAtScopeOptions struct {
// placeholder for future optional parameters
}
// TagsClientDeleteOptions contains the optional parameters for the TagsClient.Delete method.
type TagsClientDeleteOptions struct {
// placeholder for future optional parameters
}
// TagsClientDeleteValueOptions contains the optional parameters for the TagsClient.DeleteValue method.
type TagsClientDeleteValueOptions struct {
// placeholder for future optional parameters
}
// TagsClientGetAtScopeOptions contains the optional parameters for the TagsClient.GetAtScope method.
type TagsClientGetAtScopeOptions struct {
// placeholder for future optional parameters
}
// TagsClientListOptions contains the optional parameters for the TagsClient.NewListPager method.
type TagsClientListOptions struct {
// placeholder for future optional parameters
}
// TagsClientUpdateAtScopeOptions contains the optional parameters for the TagsClient.UpdateAtScope method.
type TagsClientUpdateAtScopeOptions struct {
// placeholder for future optional parameters
}

View File

@ -3,7 +3,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
package armresources
@ -13,8 +13,6 @@ import (
"errors"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
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/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"net/http"
@ -25,54 +23,53 @@ import (
// ProviderResourceTypesClient contains the methods for the ProviderResourceTypes group.
// Don't use this type directly, use NewProviderResourceTypesClient() instead.
type ProviderResourceTypesClient struct {
host string
internal *arm.Client
subscriptionID string
pl runtime.Pipeline
}
// NewProviderResourceTypesClient creates a new instance of ProviderResourceTypesClient with the specified values.
// subscriptionID - The Microsoft Azure subscription ID.
// credential - used to authorize requests. Usually a credential from azidentity.
// options - pass nil to accept the default values.
// - subscriptionID - The Microsoft Azure subscription ID.
// - credential - used to authorize requests. Usually a credential from azidentity.
// - options - pass nil to accept the default values.
func NewProviderResourceTypesClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*ProviderResourceTypesClient, error) {
if options == nil {
options = &arm.ClientOptions{}
}
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, credential, runtime.PipelineOptions{}, options)
cl, err := arm.NewClient(moduleName, moduleVersion, credential, options)
if err != nil {
return nil, err
}
client := &ProviderResourceTypesClient{
subscriptionID: subscriptionID,
host: ep,
pl: pl,
internal: cl,
}
return client, nil
}
// List - List the resource types for a specified resource provider.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceProviderNamespace - The namespace of the resource provider.
// options - ProviderResourceTypesClientListOptions contains the optional parameters for the ProviderResourceTypesClient.List
// method.
// - resourceProviderNamespace - The namespace of the resource provider.
// - options - ProviderResourceTypesClientListOptions contains the optional parameters for the ProviderResourceTypesClient.List
// method.
func (client *ProviderResourceTypesClient) List(ctx context.Context, resourceProviderNamespace string, options *ProviderResourceTypesClientListOptions) (ProviderResourceTypesClientListResponse, error) {
var err error
const operationName = "ProviderResourceTypesClient.List"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.listCreateRequest(ctx, resourceProviderNamespace, options)
if err != nil {
return ProviderResourceTypesClientListResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return ProviderResourceTypesClientListResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ProviderResourceTypesClientListResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return ProviderResourceTypesClientListResponse{}, err
}
return client.listHandleResponse(resp)
resp, err := client.listHandleResponse(httpResp)
return resp, err
}
// listCreateRequest creates the List request.
@ -86,7 +83,7 @@ func (client *ProviderResourceTypesClient) listCreateRequest(ctx context.Context
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}

View File

@ -3,7 +3,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
package armresources
@ -13,8 +13,6 @@ import (
"errors"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
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/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"net/http"
@ -25,53 +23,52 @@ import (
// ProvidersClient contains the methods for the Providers group.
// Don't use this type directly, use NewProvidersClient() instead.
type ProvidersClient struct {
host string
internal *arm.Client
subscriptionID string
pl runtime.Pipeline
}
// NewProvidersClient creates a new instance of ProvidersClient with the specified values.
// subscriptionID - The Microsoft Azure subscription ID.
// credential - used to authorize requests. Usually a credential from azidentity.
// options - pass nil to accept the default values.
// - subscriptionID - The Microsoft Azure subscription ID.
// - credential - used to authorize requests. Usually a credential from azidentity.
// - options - pass nil to accept the default values.
func NewProvidersClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*ProvidersClient, error) {
if options == nil {
options = &arm.ClientOptions{}
}
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, credential, runtime.PipelineOptions{}, options)
cl, err := arm.NewClient(moduleName, moduleVersion, credential, options)
if err != nil {
return nil, err
}
client := &ProvidersClient{
subscriptionID: subscriptionID,
host: ep,
pl: pl,
internal: cl,
}
return client, nil
}
// Get - Gets the specified resource provider.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceProviderNamespace - The namespace of the resource provider.
// options - ProvidersClientGetOptions contains the optional parameters for the ProvidersClient.Get method.
// - resourceProviderNamespace - The namespace of the resource provider.
// - options - ProvidersClientGetOptions contains the optional parameters for the ProvidersClient.Get method.
func (client *ProvidersClient) Get(ctx context.Context, resourceProviderNamespace string, options *ProvidersClientGetOptions) (ProvidersClientGetResponse, error) {
var err error
const operationName = "ProvidersClient.Get"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.getCreateRequest(ctx, resourceProviderNamespace, options)
if err != nil {
return ProvidersClientGetResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return ProvidersClientGetResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ProvidersClientGetResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return ProvidersClientGetResponse{}, err
}
return client.getHandleResponse(resp)
resp, err := client.getHandleResponse(httpResp)
return resp, err
}
// getCreateRequest creates the Get request.
@ -85,7 +82,7 @@ func (client *ProvidersClient) getCreateRequest(ctx context.Context, resourcePro
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -110,23 +107,31 @@ func (client *ProvidersClient) getHandleResponse(resp *http.Response) (Providers
// GetAtTenantScope - Gets the specified resource provider at the tenant level.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceProviderNamespace - The namespace of the resource provider.
// options - ProvidersClientGetAtTenantScopeOptions contains the optional parameters for the ProvidersClient.GetAtTenantScope
// method.
// - resourceProviderNamespace - The namespace of the resource provider.
// - options - ProvidersClientGetAtTenantScopeOptions contains the optional parameters for the ProvidersClient.GetAtTenantScope
// method.
func (client *ProvidersClient) GetAtTenantScope(ctx context.Context, resourceProviderNamespace string, options *ProvidersClientGetAtTenantScopeOptions) (ProvidersClientGetAtTenantScopeResponse, error) {
var err error
const operationName = "ProvidersClient.GetAtTenantScope"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.getAtTenantScopeCreateRequest(ctx, resourceProviderNamespace, options)
if err != nil {
return ProvidersClientGetAtTenantScopeResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return ProvidersClientGetAtTenantScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ProvidersClientGetAtTenantScopeResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return ProvidersClientGetAtTenantScopeResponse{}, err
}
return client.getAtTenantScopeHandleResponse(resp)
resp, err := client.getAtTenantScopeHandleResponse(httpResp)
return resp, err
}
// getAtTenantScopeCreateRequest creates the GetAtTenantScope request.
@ -136,7 +141,7 @@ func (client *ProvidersClient) getAtTenantScopeCreateRequest(ctx context.Context
return nil, errors.New("parameter resourceProviderNamespace cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{resourceProviderNamespace}", url.PathEscape(resourceProviderNamespace))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -160,34 +165,29 @@ func (client *ProvidersClient) getAtTenantScopeHandleResponse(resp *http.Respons
}
// NewListPager - Gets all resource providers for a subscription.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// options - ProvidersClientListOptions contains the optional parameters for the ProvidersClient.List method.
// - options - ProvidersClientListOptions contains the optional parameters for the ProvidersClient.NewListPager method.
func (client *ProvidersClient) NewListPager(options *ProvidersClientListOptions) *runtime.Pager[ProvidersClientListResponse] {
return runtime.NewPager(runtime.PagingHandler[ProvidersClientListResponse]{
More: func(page ProvidersClientListResponse) bool {
return page.NextLink != nil && len(*page.NextLink) > 0
},
Fetcher: func(ctx context.Context, page *ProvidersClientListResponse) (ProvidersClientListResponse, error) {
var req *policy.Request
var err error
if page == nil {
req, err = client.listCreateRequest(ctx, options)
} else {
req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink)
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "ProvidersClient.NewListPager")
nextLink := ""
if page != nil {
nextLink = *page.NextLink
}
resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) {
return client.listCreateRequest(ctx, options)
}, nil)
if err != nil {
return ProvidersClientListResponse{}, err
}
resp, err := client.pl.Do(req)
if err != nil {
return ProvidersClientListResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ProvidersClientListResponse{}, runtime.NewResponseError(resp)
}
return client.listHandleResponse(resp)
},
Tracer: client.internal.Tracer(),
})
}
@ -198,7 +198,7 @@ func (client *ProvidersClient) listCreateRequest(ctx context.Context, options *P
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -222,42 +222,37 @@ func (client *ProvidersClient) listHandleResponse(resp *http.Response) (Provider
}
// NewListAtTenantScopePager - Gets all resource providers for the tenant.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// options - ProvidersClientListAtTenantScopeOptions contains the optional parameters for the ProvidersClient.ListAtTenantScope
// method.
// - options - ProvidersClientListAtTenantScopeOptions contains the optional parameters for the ProvidersClient.NewListAtTenantScopePager
// method.
func (client *ProvidersClient) NewListAtTenantScopePager(options *ProvidersClientListAtTenantScopeOptions) *runtime.Pager[ProvidersClientListAtTenantScopeResponse] {
return runtime.NewPager(runtime.PagingHandler[ProvidersClientListAtTenantScopeResponse]{
More: func(page ProvidersClientListAtTenantScopeResponse) bool {
return page.NextLink != nil && len(*page.NextLink) > 0
},
Fetcher: func(ctx context.Context, page *ProvidersClientListAtTenantScopeResponse) (ProvidersClientListAtTenantScopeResponse, error) {
var req *policy.Request
var err error
if page == nil {
req, err = client.listAtTenantScopeCreateRequest(ctx, options)
} else {
req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink)
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "ProvidersClient.NewListAtTenantScopePager")
nextLink := ""
if page != nil {
nextLink = *page.NextLink
}
resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) {
return client.listAtTenantScopeCreateRequest(ctx, options)
}, nil)
if err != nil {
return ProvidersClientListAtTenantScopeResponse{}, err
}
resp, err := client.pl.Do(req)
if err != nil {
return ProvidersClientListAtTenantScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ProvidersClientListAtTenantScopeResponse{}, runtime.NewResponseError(resp)
}
return client.listAtTenantScopeHandleResponse(resp)
},
Tracer: client.internal.Tracer(),
})
}
// listAtTenantScopeCreateRequest creates the ListAtTenantScope request.
func (client *ProvidersClient) listAtTenantScopeCreateRequest(ctx context.Context, options *ProvidersClientListAtTenantScopeOptions) (*policy.Request, error) {
urlPath := "/providers"
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -282,23 +277,31 @@ func (client *ProvidersClient) listAtTenantScopeHandleResponse(resp *http.Respon
// ProviderPermissions - Get the provider permissions.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceProviderNamespace - The namespace of the resource provider.
// options - ProvidersClientProviderPermissionsOptions contains the optional parameters for the ProvidersClient.ProviderPermissions
// method.
// - resourceProviderNamespace - The namespace of the resource provider.
// - options - ProvidersClientProviderPermissionsOptions contains the optional parameters for the ProvidersClient.ProviderPermissions
// method.
func (client *ProvidersClient) ProviderPermissions(ctx context.Context, resourceProviderNamespace string, options *ProvidersClientProviderPermissionsOptions) (ProvidersClientProviderPermissionsResponse, error) {
var err error
const operationName = "ProvidersClient.ProviderPermissions"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.providerPermissionsCreateRequest(ctx, resourceProviderNamespace, options)
if err != nil {
return ProvidersClientProviderPermissionsResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return ProvidersClientProviderPermissionsResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ProvidersClientProviderPermissionsResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return ProvidersClientProviderPermissionsResponse{}, err
}
return client.providerPermissionsHandleResponse(resp)
resp, err := client.providerPermissionsHandleResponse(httpResp)
return resp, err
}
// providerPermissionsCreateRequest creates the ProviderPermissions request.
@ -312,7 +315,7 @@ func (client *ProvidersClient) providerPermissionsCreateRequest(ctx context.Cont
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -334,22 +337,30 @@ func (client *ProvidersClient) providerPermissionsHandleResponse(resp *http.Resp
// Register - Registers a subscription with a resource provider.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceProviderNamespace - The namespace of the resource provider to register.
// options - ProvidersClientRegisterOptions contains the optional parameters for the ProvidersClient.Register method.
// - resourceProviderNamespace - The namespace of the resource provider to register.
// - options - ProvidersClientRegisterOptions contains the optional parameters for the ProvidersClient.Register method.
func (client *ProvidersClient) Register(ctx context.Context, resourceProviderNamespace string, options *ProvidersClientRegisterOptions) (ProvidersClientRegisterResponse, error) {
var err error
const operationName = "ProvidersClient.Register"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.registerCreateRequest(ctx, resourceProviderNamespace, options)
if err != nil {
return ProvidersClientRegisterResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return ProvidersClientRegisterResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ProvidersClientRegisterResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return ProvidersClientRegisterResponse{}, err
}
return client.registerHandleResponse(resp)
resp, err := client.registerHandleResponse(httpResp)
return resp, err
}
// registerCreateRequest creates the Register request.
@ -363,7 +374,7 @@ func (client *ProvidersClient) registerCreateRequest(ctx context.Context, resour
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -372,7 +383,10 @@ func (client *ProvidersClient) registerCreateRequest(ctx context.Context, resour
req.Raw().URL.RawQuery = reqQP.Encode()
req.Raw().Header["Accept"] = []string{"application/json"}
if options != nil && options.Properties != nil {
return req, runtime.MarshalAsJSON(req, *options.Properties)
if err := runtime.MarshalAsJSON(req, *options.Properties); err != nil {
return nil, err
}
return req, nil
}
return req, nil
}
@ -388,22 +402,29 @@ func (client *ProvidersClient) registerHandleResponse(resp *http.Response) (Prov
// RegisterAtManagementGroupScope - Registers a management group with a resource provider.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceProviderNamespace - The namespace of the resource provider to register.
// groupID - The management group ID.
// options - ProvidersClientRegisterAtManagementGroupScopeOptions contains the optional parameters for the ProvidersClient.RegisterAtManagementGroupScope
// method.
// - resourceProviderNamespace - The namespace of the resource provider to register.
// - groupID - The management group ID.
// - options - ProvidersClientRegisterAtManagementGroupScopeOptions contains the optional parameters for the ProvidersClient.RegisterAtManagementGroupScope
// method.
func (client *ProvidersClient) RegisterAtManagementGroupScope(ctx context.Context, resourceProviderNamespace string, groupID string, options *ProvidersClientRegisterAtManagementGroupScopeOptions) (ProvidersClientRegisterAtManagementGroupScopeResponse, error) {
var err error
const operationName = "ProvidersClient.RegisterAtManagementGroupScope"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.registerAtManagementGroupScopeCreateRequest(ctx, resourceProviderNamespace, groupID, options)
if err != nil {
return ProvidersClientRegisterAtManagementGroupScopeResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return ProvidersClientRegisterAtManagementGroupScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ProvidersClientRegisterAtManagementGroupScopeResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return ProvidersClientRegisterAtManagementGroupScopeResponse{}, err
}
return ProvidersClientRegisterAtManagementGroupScopeResponse{}, nil
}
@ -419,7 +440,7 @@ func (client *ProvidersClient) registerAtManagementGroupScopeCreateRequest(ctx c
return nil, errors.New("parameter groupID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{groupId}", url.PathEscape(groupID))
req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -432,22 +453,30 @@ func (client *ProvidersClient) registerAtManagementGroupScopeCreateRequest(ctx c
// Unregister - Unregisters a subscription from a resource provider.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceProviderNamespace - The namespace of the resource provider to unregister.
// options - ProvidersClientUnregisterOptions contains the optional parameters for the ProvidersClient.Unregister method.
// - resourceProviderNamespace - The namespace of the resource provider to unregister.
// - options - ProvidersClientUnregisterOptions contains the optional parameters for the ProvidersClient.Unregister method.
func (client *ProvidersClient) Unregister(ctx context.Context, resourceProviderNamespace string, options *ProvidersClientUnregisterOptions) (ProvidersClientUnregisterResponse, error) {
var err error
const operationName = "ProvidersClient.Unregister"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.unregisterCreateRequest(ctx, resourceProviderNamespace, options)
if err != nil {
return ProvidersClientUnregisterResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return ProvidersClientUnregisterResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ProvidersClientUnregisterResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return ProvidersClientUnregisterResponse{}, err
}
return client.unregisterHandleResponse(resp)
resp, err := client.unregisterHandleResponse(httpResp)
return resp, err
}
// unregisterCreateRequest creates the Unregister request.
@ -461,7 +490,7 @@ func (client *ProvidersClient) unregisterCreateRequest(ctx context.Context, reso
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}

View File

@ -3,7 +3,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
package armresources
@ -13,8 +13,6 @@ import (
"errors"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
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/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"net/http"
@ -26,53 +24,51 @@ import (
// ResourceGroupsClient contains the methods for the ResourceGroups group.
// Don't use this type directly, use NewResourceGroupsClient() instead.
type ResourceGroupsClient struct {
host string
internal *arm.Client
subscriptionID string
pl runtime.Pipeline
}
// NewResourceGroupsClient creates a new instance of ResourceGroupsClient with the specified values.
// subscriptionID - The Microsoft Azure subscription ID.
// credential - used to authorize requests. Usually a credential from azidentity.
// options - pass nil to accept the default values.
// - subscriptionID - The Microsoft Azure subscription ID.
// - credential - used to authorize requests. Usually a credential from azidentity.
// - options - pass nil to accept the default values.
func NewResourceGroupsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*ResourceGroupsClient, error) {
if options == nil {
options = &arm.ClientOptions{}
}
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, credential, runtime.PipelineOptions{}, options)
cl, err := arm.NewClient(moduleName, moduleVersion, credential, options)
if err != nil {
return nil, err
}
client := &ResourceGroupsClient{
subscriptionID: subscriptionID,
host: ep,
pl: pl,
internal: cl,
}
return client, nil
}
// CheckExistence - Checks whether a resource group exists.
//
// Generated from API version 2021-04-01
// resourceGroupName - The name of the resource group to check. The name is case insensitive.
// options - ResourceGroupsClientCheckExistenceOptions contains the optional parameters for the ResourceGroupsClient.CheckExistence
// method.
// - resourceGroupName - The name of the resource group to check. The name is case insensitive.
// - options - ResourceGroupsClientCheckExistenceOptions contains the optional parameters for the ResourceGroupsClient.CheckExistence
// method.
func (client *ResourceGroupsClient) CheckExistence(ctx context.Context, resourceGroupName string, options *ResourceGroupsClientCheckExistenceOptions) (ResourceGroupsClientCheckExistenceResponse, error) {
var err error
const operationName = "ResourceGroupsClient.CheckExistence"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.checkExistenceCreateRequest(ctx, resourceGroupName, options)
if err != nil {
return ResourceGroupsClientCheckExistenceResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return ResourceGroupsClientCheckExistenceResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusNoContent, http.StatusNotFound) {
return ResourceGroupsClientCheckExistenceResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusNoContent, http.StatusNotFound) {
err = runtime.NewResponseError(httpResp)
return ResourceGroupsClientCheckExistenceResponse{}, err
}
return ResourceGroupsClientCheckExistenceResponse{Success: resp.StatusCode >= 200 && resp.StatusCode < 300}, nil
return ResourceGroupsClientCheckExistenceResponse{Success: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil
}
// checkExistenceCreateRequest creates the CheckExistence request.
@ -86,7 +82,7 @@ func (client *ResourceGroupsClient) checkExistenceCreateRequest(ctx context.Cont
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodHead, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodHead, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -99,25 +95,33 @@ func (client *ResourceGroupsClient) checkExistenceCreateRequest(ctx context.Cont
// CreateOrUpdate - Creates or updates a resource group.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceGroupName - The name of the resource group to create or update. Can include alphanumeric, underscore, parentheses,
// hyphen, period (except at end), and Unicode characters that match the allowed characters.
// parameters - Parameters supplied to the create or update a resource group.
// options - ResourceGroupsClientCreateOrUpdateOptions contains the optional parameters for the ResourceGroupsClient.CreateOrUpdate
// method.
// - resourceGroupName - The name of the resource group to create or update. Can include alphanumeric, underscore, parentheses,
// hyphen, period (except at end), and Unicode characters that match the allowed characters.
// - parameters - Parameters supplied to the create or update a resource group.
// - options - ResourceGroupsClientCreateOrUpdateOptions contains the optional parameters for the ResourceGroupsClient.CreateOrUpdate
// method.
func (client *ResourceGroupsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, parameters ResourceGroup, options *ResourceGroupsClientCreateOrUpdateOptions) (ResourceGroupsClientCreateOrUpdateResponse, error) {
var err error
const operationName = "ResourceGroupsClient.CreateOrUpdate"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.createOrUpdateCreateRequest(ctx, resourceGroupName, parameters, options)
if err != nil {
return ResourceGroupsClientCreateOrUpdateResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return ResourceGroupsClientCreateOrUpdateResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK, http.StatusCreated) {
return ResourceGroupsClientCreateOrUpdateResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) {
err = runtime.NewResponseError(httpResp)
return ResourceGroupsClientCreateOrUpdateResponse{}, err
}
return client.createOrUpdateHandleResponse(resp)
resp, err := client.createOrUpdateHandleResponse(httpResp)
return resp, err
}
// createOrUpdateCreateRequest creates the CreateOrUpdate request.
@ -131,7 +135,7 @@ func (client *ResourceGroupsClient) createOrUpdateCreateRequest(ctx context.Cont
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -139,7 +143,10 @@ func (client *ResourceGroupsClient) createOrUpdateCreateRequest(ctx context.Cont
reqQP.Set("api-version", "2021-04-01")
req.Raw().URL.RawQuery = reqQP.Encode()
req.Raw().Header["Accept"] = []string{"application/json"}
return req, runtime.MarshalAsJSON(req, parameters)
if err := runtime.MarshalAsJSON(req, parameters); err != nil {
return nil, err
}
return req, nil
}
// createOrUpdateHandleResponse handles the CreateOrUpdate response.
@ -154,39 +161,52 @@ func (client *ResourceGroupsClient) createOrUpdateHandleResponse(resp *http.Resp
// BeginDelete - When you delete a resource group, all of its resources are also deleted. Deleting a resource group deletes
// all of its template deployments and currently stored operations.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceGroupName - The name of the resource group to delete. The name is case insensitive.
// options - ResourceGroupsClientBeginDeleteOptions contains the optional parameters for the ResourceGroupsClient.BeginDelete
// method.
// - resourceGroupName - The name of the resource group to delete. The name is case insensitive.
// - options - ResourceGroupsClientBeginDeleteOptions contains the optional parameters for the ResourceGroupsClient.BeginDelete
// method.
func (client *ResourceGroupsClient) BeginDelete(ctx context.Context, resourceGroupName string, options *ResourceGroupsClientBeginDeleteOptions) (*runtime.Poller[ResourceGroupsClientDeleteResponse], error) {
if options == nil || options.ResumeToken == "" {
resp, err := client.deleteOperation(ctx, resourceGroupName, options)
if err != nil {
return nil, err
}
return runtime.NewPoller[ResourceGroupsClientDeleteResponse](resp, client.pl, nil)
poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[ResourceGroupsClientDeleteResponse]{
Tracer: client.internal.Tracer(),
})
return poller, err
} else {
return runtime.NewPollerFromResumeToken[ResourceGroupsClientDeleteResponse](options.ResumeToken, client.pl, nil)
return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[ResourceGroupsClientDeleteResponse]{
Tracer: client.internal.Tracer(),
})
}
}
// Delete - When you delete a resource group, all of its resources are also deleted. Deleting a resource group deletes all
// of its template deployments and currently stored operations.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
func (client *ResourceGroupsClient) deleteOperation(ctx context.Context, resourceGroupName string, options *ResourceGroupsClientBeginDeleteOptions) (*http.Response, error) {
var err error
const operationName = "ResourceGroupsClient.BeginDelete"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.deleteCreateRequest(ctx, resourceGroupName, options)
if err != nil {
return nil, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return nil, err
}
if !runtime.HasStatusCode(resp, http.StatusOK, http.StatusAccepted) {
return nil, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted) {
err = runtime.NewResponseError(httpResp)
return nil, err
}
return resp, nil
return httpResp, nil
}
// deleteCreateRequest creates the Delete request.
@ -200,7 +220,7 @@ func (client *ResourceGroupsClient) deleteCreateRequest(ctx context.Context, res
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -216,41 +236,53 @@ func (client *ResourceGroupsClient) deleteCreateRequest(ctx context.Context, res
// BeginExportTemplate - Captures the specified resource group as a template.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceGroupName - The name of the resource group. The name is case insensitive.
// parameters - Parameters for exporting the template.
// options - ResourceGroupsClientBeginExportTemplateOptions contains the optional parameters for the ResourceGroupsClient.BeginExportTemplate
// method.
// - resourceGroupName - The name of the resource group. The name is case insensitive.
// - parameters - Parameters for exporting the template.
// - options - ResourceGroupsClientBeginExportTemplateOptions contains the optional parameters for the ResourceGroupsClient.BeginExportTemplate
// method.
func (client *ResourceGroupsClient) BeginExportTemplate(ctx context.Context, resourceGroupName string, parameters ExportTemplateRequest, options *ResourceGroupsClientBeginExportTemplateOptions) (*runtime.Poller[ResourceGroupsClientExportTemplateResponse], error) {
if options == nil || options.ResumeToken == "" {
resp, err := client.exportTemplate(ctx, resourceGroupName, parameters, options)
if err != nil {
return nil, err
}
return runtime.NewPoller(resp, client.pl, &runtime.NewPollerOptions[ResourceGroupsClientExportTemplateResponse]{
poller, err := runtime.NewPoller(resp, client.internal.Pipeline(), &runtime.NewPollerOptions[ResourceGroupsClientExportTemplateResponse]{
FinalStateVia: runtime.FinalStateViaLocation,
Tracer: client.internal.Tracer(),
})
return poller, err
} else {
return runtime.NewPollerFromResumeToken[ResourceGroupsClientExportTemplateResponse](options.ResumeToken, client.pl, nil)
return runtime.NewPollerFromResumeToken(options.ResumeToken, client.internal.Pipeline(), &runtime.NewPollerFromResumeTokenOptions[ResourceGroupsClientExportTemplateResponse]{
Tracer: client.internal.Tracer(),
})
}
}
// ExportTemplate - Captures the specified resource group as a template.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
func (client *ResourceGroupsClient) exportTemplate(ctx context.Context, resourceGroupName string, parameters ExportTemplateRequest, options *ResourceGroupsClientBeginExportTemplateOptions) (*http.Response, error) {
var err error
const operationName = "ResourceGroupsClient.BeginExportTemplate"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.exportTemplateCreateRequest(ctx, resourceGroupName, parameters, options)
if err != nil {
return nil, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return nil, err
}
if !runtime.HasStatusCode(resp, http.StatusOK, http.StatusAccepted) {
return nil, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusAccepted) {
err = runtime.NewResponseError(httpResp)
return nil, err
}
return resp, nil
return httpResp, nil
}
// exportTemplateCreateRequest creates the ExportTemplate request.
@ -264,7 +296,7 @@ func (client *ResourceGroupsClient) exportTemplateCreateRequest(ctx context.Cont
return nil, errors.New("parameter resourceGroupName cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{resourceGroupName}", url.PathEscape(resourceGroupName))
req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -272,27 +304,38 @@ func (client *ResourceGroupsClient) exportTemplateCreateRequest(ctx context.Cont
reqQP.Set("api-version", "2021-04-01")
req.Raw().URL.RawQuery = reqQP.Encode()
req.Raw().Header["Accept"] = []string{"application/json"}
return req, runtime.MarshalAsJSON(req, parameters)
if err := runtime.MarshalAsJSON(req, parameters); err != nil {
return nil, err
}
return req, nil
}
// Get - Gets a resource group.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceGroupName - The name of the resource group to get. The name is case insensitive.
// options - ResourceGroupsClientGetOptions contains the optional parameters for the ResourceGroupsClient.Get method.
// - resourceGroupName - The name of the resource group to get. The name is case insensitive.
// - options - ResourceGroupsClientGetOptions contains the optional parameters for the ResourceGroupsClient.Get method.
func (client *ResourceGroupsClient) Get(ctx context.Context, resourceGroupName string, options *ResourceGroupsClientGetOptions) (ResourceGroupsClientGetResponse, error) {
var err error
const operationName = "ResourceGroupsClient.Get"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.getCreateRequest(ctx, resourceGroupName, options)
if err != nil {
return ResourceGroupsClientGetResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return ResourceGroupsClientGetResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ResourceGroupsClientGetResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return ResourceGroupsClientGetResponse{}, err
}
return client.getHandleResponse(resp)
resp, err := client.getHandleResponse(httpResp)
return resp, err
}
// getCreateRequest creates the Get request.
@ -306,7 +349,7 @@ func (client *ResourceGroupsClient) getCreateRequest(ctx context.Context, resour
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -327,34 +370,29 @@ func (client *ResourceGroupsClient) getHandleResponse(resp *http.Response) (Reso
}
// NewListPager - Gets all the resource groups for a subscription.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// options - ResourceGroupsClientListOptions contains the optional parameters for the ResourceGroupsClient.List method.
// - options - ResourceGroupsClientListOptions contains the optional parameters for the ResourceGroupsClient.NewListPager method.
func (client *ResourceGroupsClient) NewListPager(options *ResourceGroupsClientListOptions) *runtime.Pager[ResourceGroupsClientListResponse] {
return runtime.NewPager(runtime.PagingHandler[ResourceGroupsClientListResponse]{
More: func(page ResourceGroupsClientListResponse) bool {
return page.NextLink != nil && len(*page.NextLink) > 0
},
Fetcher: func(ctx context.Context, page *ResourceGroupsClientListResponse) (ResourceGroupsClientListResponse, error) {
var req *policy.Request
var err error
if page == nil {
req, err = client.listCreateRequest(ctx, options)
} else {
req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink)
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "ResourceGroupsClient.NewListPager")
nextLink := ""
if page != nil {
nextLink = *page.NextLink
}
resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) {
return client.listCreateRequest(ctx, options)
}, nil)
if err != nil {
return ResourceGroupsClientListResponse{}, err
}
resp, err := client.pl.Do(req)
if err != nil {
return ResourceGroupsClientListResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ResourceGroupsClientListResponse{}, runtime.NewResponseError(resp)
}
return client.listHandleResponse(resp)
},
Tracer: client.internal.Tracer(),
})
}
@ -365,7 +403,7 @@ func (client *ResourceGroupsClient) listCreateRequest(ctx context.Context, optio
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -395,23 +433,31 @@ func (client *ResourceGroupsClient) listHandleResponse(resp *http.Response) (Res
// is the same as that for creating a resource group. If a field is unspecified, the current
// value is retained.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// resourceGroupName - The name of the resource group to update. The name is case insensitive.
// parameters - Parameters supplied to update a resource group.
// options - ResourceGroupsClientUpdateOptions contains the optional parameters for the ResourceGroupsClient.Update method.
// - resourceGroupName - The name of the resource group to update. The name is case insensitive.
// - parameters - Parameters supplied to update a resource group.
// - options - ResourceGroupsClientUpdateOptions contains the optional parameters for the ResourceGroupsClient.Update method.
func (client *ResourceGroupsClient) Update(ctx context.Context, resourceGroupName string, parameters ResourceGroupPatchable, options *ResourceGroupsClientUpdateOptions) (ResourceGroupsClientUpdateResponse, error) {
var err error
const operationName = "ResourceGroupsClient.Update"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.updateCreateRequest(ctx, resourceGroupName, parameters, options)
if err != nil {
return ResourceGroupsClientUpdateResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return ResourceGroupsClientUpdateResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return ResourceGroupsClientUpdateResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return ResourceGroupsClientUpdateResponse{}, err
}
return client.updateHandleResponse(resp)
resp, err := client.updateHandleResponse(httpResp)
return resp, err
}
// updateCreateRequest creates the Update request.
@ -425,7 +471,7 @@ func (client *ResourceGroupsClient) updateCreateRequest(ctx context.Context, res
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodPatch, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodPatch, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -433,7 +479,10 @@ func (client *ResourceGroupsClient) updateCreateRequest(ctx context.Context, res
reqQP.Set("api-version", "2021-04-01")
req.Raw().URL.RawQuery = reqQP.Encode()
req.Raw().Header["Accept"] = []string{"application/json"}
return req, runtime.MarshalAsJSON(req, parameters)
if err := runtime.MarshalAsJSON(req, parameters); err != nil {
return nil, err
}
return req, nil
}
// updateHandleResponse handles the Update response.

View File

@ -3,7 +3,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
package armresources
@ -20,118 +20,137 @@ type ClientCheckExistenceResponse struct {
Success bool
}
// ClientCreateOrUpdateByIDResponse contains the response from method Client.CreateOrUpdateByID.
// ClientCreateOrUpdateByIDResponse contains the response from method Client.BeginCreateOrUpdateByID.
type ClientCreateOrUpdateByIDResponse struct {
// Resource information.
GenericResource
}
// ClientCreateOrUpdateResponse contains the response from method Client.CreateOrUpdate.
// ClientCreateOrUpdateResponse contains the response from method Client.BeginCreateOrUpdate.
type ClientCreateOrUpdateResponse struct {
// Resource information.
GenericResource
}
// ClientDeleteByIDResponse contains the response from method Client.DeleteByID.
// ClientDeleteByIDResponse contains the response from method Client.BeginDeleteByID.
type ClientDeleteByIDResponse struct {
// placeholder for future response values
}
// ClientDeleteResponse contains the response from method Client.Delete.
// ClientDeleteResponse contains the response from method Client.BeginDelete.
type ClientDeleteResponse struct {
// placeholder for future response values
}
// ClientGetByIDResponse contains the response from method Client.GetByID.
type ClientGetByIDResponse struct {
// Resource information.
GenericResource
}
// ClientGetResponse contains the response from method Client.Get.
type ClientGetResponse struct {
// Resource information.
GenericResource
}
// ClientListByResourceGroupResponse contains the response from method Client.ListByResourceGroup.
// ClientListByResourceGroupResponse contains the response from method Client.NewListByResourceGroupPager.
type ClientListByResourceGroupResponse struct {
// List of resource groups.
ResourceListResult
}
// ClientListResponse contains the response from method Client.List.
// ClientListResponse contains the response from method Client.NewListPager.
type ClientListResponse struct {
// List of resource groups.
ResourceListResult
}
// ClientMoveResourcesResponse contains the response from method Client.MoveResources.
// ClientMoveResourcesResponse contains the response from method Client.BeginMoveResources.
type ClientMoveResourcesResponse struct {
// placeholder for future response values
}
// ClientUpdateByIDResponse contains the response from method Client.UpdateByID.
// ClientUpdateByIDResponse contains the response from method Client.BeginUpdateByID.
type ClientUpdateByIDResponse struct {
// Resource information.
GenericResource
}
// ClientUpdateResponse contains the response from method Client.Update.
// ClientUpdateResponse contains the response from method Client.BeginUpdate.
type ClientUpdateResponse struct {
// Resource information.
GenericResource
}
// ClientValidateMoveResourcesResponse contains the response from method Client.ValidateMoveResources.
// ClientValidateMoveResourcesResponse contains the response from method Client.BeginValidateMoveResources.
type ClientValidateMoveResourcesResponse struct {
// placeholder for future response values
}
// DeploymentOperationsClientGetAtManagementGroupScopeResponse contains the response from method DeploymentOperationsClient.GetAtManagementGroupScope.
type DeploymentOperationsClientGetAtManagementGroupScopeResponse struct {
// Deployment operation information.
DeploymentOperation
}
// DeploymentOperationsClientGetAtScopeResponse contains the response from method DeploymentOperationsClient.GetAtScope.
type DeploymentOperationsClientGetAtScopeResponse struct {
// Deployment operation information.
DeploymentOperation
}
// DeploymentOperationsClientGetAtSubscriptionScopeResponse contains the response from method DeploymentOperationsClient.GetAtSubscriptionScope.
type DeploymentOperationsClientGetAtSubscriptionScopeResponse struct {
// Deployment operation information.
DeploymentOperation
}
// DeploymentOperationsClientGetAtTenantScopeResponse contains the response from method DeploymentOperationsClient.GetAtTenantScope.
type DeploymentOperationsClientGetAtTenantScopeResponse struct {
// Deployment operation information.
DeploymentOperation
}
// DeploymentOperationsClientGetResponse contains the response from method DeploymentOperationsClient.Get.
type DeploymentOperationsClientGetResponse struct {
// Deployment operation information.
DeploymentOperation
}
// DeploymentOperationsClientListAtManagementGroupScopeResponse contains the response from method DeploymentOperationsClient.ListAtManagementGroupScope.
// DeploymentOperationsClientListAtManagementGroupScopeResponse contains the response from method DeploymentOperationsClient.NewListAtManagementGroupScopePager.
type DeploymentOperationsClientListAtManagementGroupScopeResponse struct {
// List of deployment operations.
DeploymentOperationsListResult
}
// DeploymentOperationsClientListAtScopeResponse contains the response from method DeploymentOperationsClient.ListAtScope.
// DeploymentOperationsClientListAtScopeResponse contains the response from method DeploymentOperationsClient.NewListAtScopePager.
type DeploymentOperationsClientListAtScopeResponse struct {
// List of deployment operations.
DeploymentOperationsListResult
}
// DeploymentOperationsClientListAtSubscriptionScopeResponse contains the response from method DeploymentOperationsClient.ListAtSubscriptionScope.
// DeploymentOperationsClientListAtSubscriptionScopeResponse contains the response from method DeploymentOperationsClient.NewListAtSubscriptionScopePager.
type DeploymentOperationsClientListAtSubscriptionScopeResponse struct {
// List of deployment operations.
DeploymentOperationsListResult
}
// DeploymentOperationsClientListAtTenantScopeResponse contains the response from method DeploymentOperationsClient.ListAtTenantScope.
// DeploymentOperationsClientListAtTenantScopeResponse contains the response from method DeploymentOperationsClient.NewListAtTenantScopePager.
type DeploymentOperationsClientListAtTenantScopeResponse struct {
// List of deployment operations.
DeploymentOperationsListResult
}
// DeploymentOperationsClientListResponse contains the response from method DeploymentOperationsClient.List.
// DeploymentOperationsClientListResponse contains the response from method DeploymentOperationsClient.NewListPager.
type DeploymentOperationsClientListResponse struct {
// List of deployment operations.
DeploymentOperationsListResult
}
// DeploymentsClientCalculateTemplateHashResponse contains the response from method DeploymentsClient.CalculateTemplateHash.
type DeploymentsClientCalculateTemplateHashResponse struct {
// Result of the request to calculate template hash. It contains a string of minified template and its hash.
TemplateHashResult
}
@ -190,208 +209,245 @@ type DeploymentsClientCheckExistenceResponse struct {
Success bool
}
// DeploymentsClientCreateOrUpdateAtManagementGroupScopeResponse contains the response from method DeploymentsClient.CreateOrUpdateAtManagementGroupScope.
// DeploymentsClientCreateOrUpdateAtManagementGroupScopeResponse contains the response from method DeploymentsClient.BeginCreateOrUpdateAtManagementGroupScope.
type DeploymentsClientCreateOrUpdateAtManagementGroupScopeResponse struct {
// Deployment information.
DeploymentExtended
}
// DeploymentsClientCreateOrUpdateAtScopeResponse contains the response from method DeploymentsClient.CreateOrUpdateAtScope.
// DeploymentsClientCreateOrUpdateAtScopeResponse contains the response from method DeploymentsClient.BeginCreateOrUpdateAtScope.
type DeploymentsClientCreateOrUpdateAtScopeResponse struct {
// Deployment information.
DeploymentExtended
}
// DeploymentsClientCreateOrUpdateAtSubscriptionScopeResponse contains the response from method DeploymentsClient.CreateOrUpdateAtSubscriptionScope.
// DeploymentsClientCreateOrUpdateAtSubscriptionScopeResponse contains the response from method DeploymentsClient.BeginCreateOrUpdateAtSubscriptionScope.
type DeploymentsClientCreateOrUpdateAtSubscriptionScopeResponse struct {
// Deployment information.
DeploymentExtended
}
// DeploymentsClientCreateOrUpdateAtTenantScopeResponse contains the response from method DeploymentsClient.CreateOrUpdateAtTenantScope.
// DeploymentsClientCreateOrUpdateAtTenantScopeResponse contains the response from method DeploymentsClient.BeginCreateOrUpdateAtTenantScope.
type DeploymentsClientCreateOrUpdateAtTenantScopeResponse struct {
// Deployment information.
DeploymentExtended
}
// DeploymentsClientCreateOrUpdateResponse contains the response from method DeploymentsClient.CreateOrUpdate.
// DeploymentsClientCreateOrUpdateResponse contains the response from method DeploymentsClient.BeginCreateOrUpdate.
type DeploymentsClientCreateOrUpdateResponse struct {
// Deployment information.
DeploymentExtended
}
// DeploymentsClientDeleteAtManagementGroupScopeResponse contains the response from method DeploymentsClient.DeleteAtManagementGroupScope.
// DeploymentsClientDeleteAtManagementGroupScopeResponse contains the response from method DeploymentsClient.BeginDeleteAtManagementGroupScope.
type DeploymentsClientDeleteAtManagementGroupScopeResponse struct {
// placeholder for future response values
}
// DeploymentsClientDeleteAtScopeResponse contains the response from method DeploymentsClient.DeleteAtScope.
// DeploymentsClientDeleteAtScopeResponse contains the response from method DeploymentsClient.BeginDeleteAtScope.
type DeploymentsClientDeleteAtScopeResponse struct {
// placeholder for future response values
}
// DeploymentsClientDeleteAtSubscriptionScopeResponse contains the response from method DeploymentsClient.DeleteAtSubscriptionScope.
// DeploymentsClientDeleteAtSubscriptionScopeResponse contains the response from method DeploymentsClient.BeginDeleteAtSubscriptionScope.
type DeploymentsClientDeleteAtSubscriptionScopeResponse struct {
// placeholder for future response values
}
// DeploymentsClientDeleteAtTenantScopeResponse contains the response from method DeploymentsClient.DeleteAtTenantScope.
// DeploymentsClientDeleteAtTenantScopeResponse contains the response from method DeploymentsClient.BeginDeleteAtTenantScope.
type DeploymentsClientDeleteAtTenantScopeResponse struct {
// placeholder for future response values
}
// DeploymentsClientDeleteResponse contains the response from method DeploymentsClient.Delete.
// DeploymentsClientDeleteResponse contains the response from method DeploymentsClient.BeginDelete.
type DeploymentsClientDeleteResponse struct {
// placeholder for future response values
}
// DeploymentsClientExportTemplateAtManagementGroupScopeResponse contains the response from method DeploymentsClient.ExportTemplateAtManagementGroupScope.
type DeploymentsClientExportTemplateAtManagementGroupScopeResponse struct {
// The deployment export result.
DeploymentExportResult
}
// DeploymentsClientExportTemplateAtScopeResponse contains the response from method DeploymentsClient.ExportTemplateAtScope.
type DeploymentsClientExportTemplateAtScopeResponse struct {
// The deployment export result.
DeploymentExportResult
}
// DeploymentsClientExportTemplateAtSubscriptionScopeResponse contains the response from method DeploymentsClient.ExportTemplateAtSubscriptionScope.
type DeploymentsClientExportTemplateAtSubscriptionScopeResponse struct {
// The deployment export result.
DeploymentExportResult
}
// DeploymentsClientExportTemplateAtTenantScopeResponse contains the response from method DeploymentsClient.ExportTemplateAtTenantScope.
type DeploymentsClientExportTemplateAtTenantScopeResponse struct {
// The deployment export result.
DeploymentExportResult
}
// DeploymentsClientExportTemplateResponse contains the response from method DeploymentsClient.ExportTemplate.
type DeploymentsClientExportTemplateResponse struct {
// The deployment export result.
DeploymentExportResult
}
// DeploymentsClientGetAtManagementGroupScopeResponse contains the response from method DeploymentsClient.GetAtManagementGroupScope.
type DeploymentsClientGetAtManagementGroupScopeResponse struct {
// Deployment information.
DeploymentExtended
}
// DeploymentsClientGetAtScopeResponse contains the response from method DeploymentsClient.GetAtScope.
type DeploymentsClientGetAtScopeResponse struct {
// Deployment information.
DeploymentExtended
}
// DeploymentsClientGetAtSubscriptionScopeResponse contains the response from method DeploymentsClient.GetAtSubscriptionScope.
type DeploymentsClientGetAtSubscriptionScopeResponse struct {
// Deployment information.
DeploymentExtended
}
// DeploymentsClientGetAtTenantScopeResponse contains the response from method DeploymentsClient.GetAtTenantScope.
type DeploymentsClientGetAtTenantScopeResponse struct {
// Deployment information.
DeploymentExtended
}
// DeploymentsClientGetResponse contains the response from method DeploymentsClient.Get.
type DeploymentsClientGetResponse struct {
// Deployment information.
DeploymentExtended
}
// DeploymentsClientListAtManagementGroupScopeResponse contains the response from method DeploymentsClient.ListAtManagementGroupScope.
// DeploymentsClientListAtManagementGroupScopeResponse contains the response from method DeploymentsClient.NewListAtManagementGroupScopePager.
type DeploymentsClientListAtManagementGroupScopeResponse struct {
// List of deployments.
DeploymentListResult
}
// DeploymentsClientListAtScopeResponse contains the response from method DeploymentsClient.ListAtScope.
// DeploymentsClientListAtScopeResponse contains the response from method DeploymentsClient.NewListAtScopePager.
type DeploymentsClientListAtScopeResponse struct {
// List of deployments.
DeploymentListResult
}
// DeploymentsClientListAtSubscriptionScopeResponse contains the response from method DeploymentsClient.ListAtSubscriptionScope.
// DeploymentsClientListAtSubscriptionScopeResponse contains the response from method DeploymentsClient.NewListAtSubscriptionScopePager.
type DeploymentsClientListAtSubscriptionScopeResponse struct {
// List of deployments.
DeploymentListResult
}
// DeploymentsClientListAtTenantScopeResponse contains the response from method DeploymentsClient.ListAtTenantScope.
// DeploymentsClientListAtTenantScopeResponse contains the response from method DeploymentsClient.NewListAtTenantScopePager.
type DeploymentsClientListAtTenantScopeResponse struct {
// List of deployments.
DeploymentListResult
}
// DeploymentsClientListByResourceGroupResponse contains the response from method DeploymentsClient.ListByResourceGroup.
// DeploymentsClientListByResourceGroupResponse contains the response from method DeploymentsClient.NewListByResourceGroupPager.
type DeploymentsClientListByResourceGroupResponse struct {
// List of deployments.
DeploymentListResult
}
// DeploymentsClientValidateAtManagementGroupScopeResponse contains the response from method DeploymentsClient.ValidateAtManagementGroupScope.
// DeploymentsClientValidateAtManagementGroupScopeResponse contains the response from method DeploymentsClient.BeginValidateAtManagementGroupScope.
type DeploymentsClientValidateAtManagementGroupScopeResponse struct {
// Information from validate template deployment response.
DeploymentValidateResult
}
// DeploymentsClientValidateAtScopeResponse contains the response from method DeploymentsClient.ValidateAtScope.
// DeploymentsClientValidateAtScopeResponse contains the response from method DeploymentsClient.BeginValidateAtScope.
type DeploymentsClientValidateAtScopeResponse struct {
// Information from validate template deployment response.
DeploymentValidateResult
}
// DeploymentsClientValidateAtSubscriptionScopeResponse contains the response from method DeploymentsClient.ValidateAtSubscriptionScope.
// DeploymentsClientValidateAtSubscriptionScopeResponse contains the response from method DeploymentsClient.BeginValidateAtSubscriptionScope.
type DeploymentsClientValidateAtSubscriptionScopeResponse struct {
// Information from validate template deployment response.
DeploymentValidateResult
}
// DeploymentsClientValidateAtTenantScopeResponse contains the response from method DeploymentsClient.ValidateAtTenantScope.
// DeploymentsClientValidateAtTenantScopeResponse contains the response from method DeploymentsClient.BeginValidateAtTenantScope.
type DeploymentsClientValidateAtTenantScopeResponse struct {
// Information from validate template deployment response.
DeploymentValidateResult
}
// DeploymentsClientValidateResponse contains the response from method DeploymentsClient.Validate.
// DeploymentsClientValidateResponse contains the response from method DeploymentsClient.BeginValidate.
type DeploymentsClientValidateResponse struct {
// Information from validate template deployment response.
DeploymentValidateResult
}
// DeploymentsClientWhatIfAtManagementGroupScopeResponse contains the response from method DeploymentsClient.WhatIfAtManagementGroupScope.
// DeploymentsClientWhatIfAtManagementGroupScopeResponse contains the response from method DeploymentsClient.BeginWhatIfAtManagementGroupScope.
type DeploymentsClientWhatIfAtManagementGroupScopeResponse struct {
// Result of the What-If operation. Contains a list of predicted changes and a URL link to get to the next set of results.
WhatIfOperationResult
}
// DeploymentsClientWhatIfAtSubscriptionScopeResponse contains the response from method DeploymentsClient.WhatIfAtSubscriptionScope.
// DeploymentsClientWhatIfAtSubscriptionScopeResponse contains the response from method DeploymentsClient.BeginWhatIfAtSubscriptionScope.
type DeploymentsClientWhatIfAtSubscriptionScopeResponse struct {
// Result of the What-If operation. Contains a list of predicted changes and a URL link to get to the next set of results.
WhatIfOperationResult
}
// DeploymentsClientWhatIfAtTenantScopeResponse contains the response from method DeploymentsClient.WhatIfAtTenantScope.
// DeploymentsClientWhatIfAtTenantScopeResponse contains the response from method DeploymentsClient.BeginWhatIfAtTenantScope.
type DeploymentsClientWhatIfAtTenantScopeResponse struct {
// Result of the What-If operation. Contains a list of predicted changes and a URL link to get to the next set of results.
WhatIfOperationResult
}
// DeploymentsClientWhatIfResponse contains the response from method DeploymentsClient.WhatIf.
// DeploymentsClientWhatIfResponse contains the response from method DeploymentsClient.BeginWhatIf.
type DeploymentsClientWhatIfResponse struct {
// Result of the What-If operation. Contains a list of predicted changes and a URL link to get to the next set of results.
WhatIfOperationResult
}
// OperationsClientListResponse contains the response from method OperationsClient.List.
// OperationsClientListResponse contains the response from method OperationsClient.NewListPager.
type OperationsClientListResponse struct {
// Result of the request to list Microsoft.Resources operations. It contains a list of operations and a URL link to get the
// next set of results.
OperationListResult
}
// ProviderResourceTypesClientListResponse contains the response from method ProviderResourceTypesClient.List.
type ProviderResourceTypesClientListResponse struct {
// List of resource types of a resource provider.
ProviderResourceTypeListResult
}
// ProvidersClientGetAtTenantScopeResponse contains the response from method ProvidersClient.GetAtTenantScope.
type ProvidersClientGetAtTenantScopeResponse struct {
// Resource provider information.
Provider
}
// ProvidersClientGetResponse contains the response from method ProvidersClient.Get.
type ProvidersClientGetResponse struct {
// Resource provider information.
Provider
}
// ProvidersClientListAtTenantScopeResponse contains the response from method ProvidersClient.ListAtTenantScope.
// ProvidersClientListAtTenantScopeResponse contains the response from method ProvidersClient.NewListAtTenantScopePager.
type ProvidersClientListAtTenantScopeResponse struct {
// List of resource providers.
ProviderListResult
}
// ProvidersClientListResponse contains the response from method ProvidersClient.List.
// ProvidersClientListResponse contains the response from method ProvidersClient.NewListPager.
type ProvidersClientListResponse struct {
// List of resource providers.
ProviderListResult
}
// ProvidersClientProviderPermissionsResponse contains the response from method ProvidersClient.ProviderPermissions.
type ProvidersClientProviderPermissionsResponse struct {
// List of provider permissions.
ProviderPermissionListResult
}
@ -402,11 +458,13 @@ type ProvidersClientRegisterAtManagementGroupScopeResponse struct {
// ProvidersClientRegisterResponse contains the response from method ProvidersClient.Register.
type ProvidersClientRegisterResponse struct {
// Resource provider information.
Provider
}
// ProvidersClientUnregisterResponse contains the response from method ProvidersClient.Unregister.
type ProvidersClientUnregisterResponse struct {
// Resource provider information.
Provider
}
@ -418,46 +476,54 @@ type ResourceGroupsClientCheckExistenceResponse struct {
// ResourceGroupsClientCreateOrUpdateResponse contains the response from method ResourceGroupsClient.CreateOrUpdate.
type ResourceGroupsClientCreateOrUpdateResponse struct {
// Resource group information.
ResourceGroup
}
// ResourceGroupsClientDeleteResponse contains the response from method ResourceGroupsClient.Delete.
// ResourceGroupsClientDeleteResponse contains the response from method ResourceGroupsClient.BeginDelete.
type ResourceGroupsClientDeleteResponse struct {
// placeholder for future response values
}
// ResourceGroupsClientExportTemplateResponse contains the response from method ResourceGroupsClient.ExportTemplate.
// ResourceGroupsClientExportTemplateResponse contains the response from method ResourceGroupsClient.BeginExportTemplate.
type ResourceGroupsClientExportTemplateResponse struct {
// Resource group export result.
ResourceGroupExportResult
}
// ResourceGroupsClientGetResponse contains the response from method ResourceGroupsClient.Get.
type ResourceGroupsClientGetResponse struct {
// Resource group information.
ResourceGroup
}
// ResourceGroupsClientListResponse contains the response from method ResourceGroupsClient.List.
// ResourceGroupsClientListResponse contains the response from method ResourceGroupsClient.NewListPager.
type ResourceGroupsClientListResponse struct {
// List of resource groups.
ResourceGroupListResult
}
// ResourceGroupsClientUpdateResponse contains the response from method ResourceGroupsClient.Update.
type ResourceGroupsClientUpdateResponse struct {
// Resource group information.
ResourceGroup
}
// TagsClientCreateOrUpdateAtScopeResponse contains the response from method TagsClient.CreateOrUpdateAtScope.
type TagsClientCreateOrUpdateAtScopeResponse struct {
// Wrapper resource for tags API requests and responses.
TagsResource
}
// TagsClientCreateOrUpdateResponse contains the response from method TagsClient.CreateOrUpdate.
type TagsClientCreateOrUpdateResponse struct {
// Tag details.
TagDetails
}
// TagsClientCreateOrUpdateValueResponse contains the response from method TagsClient.CreateOrUpdateValue.
type TagsClientCreateOrUpdateValueResponse struct {
// Tag information.
TagValue
}
@ -478,15 +544,18 @@ type TagsClientDeleteValueResponse struct {
// TagsClientGetAtScopeResponse contains the response from method TagsClient.GetAtScope.
type TagsClientGetAtScopeResponse struct {
// Wrapper resource for tags API requests and responses.
TagsResource
}
// TagsClientListResponse contains the response from method TagsClient.List.
// TagsClientListResponse contains the response from method TagsClient.NewListPager.
type TagsClientListResponse struct {
// List of subscription tags.
TagsListResult
}
// TagsClientUpdateAtScopeResponse contains the response from method TagsClient.UpdateAtScope.
type TagsClientUpdateAtScopeResponse struct {
// Wrapper resource for tags API requests and responses.
TagsResource
}

View File

@ -3,7 +3,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
package armresources
@ -13,8 +13,6 @@ import (
"errors"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
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/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
"net/http"
@ -25,31 +23,22 @@ import (
// TagsClient contains the methods for the Tags group.
// Don't use this type directly, use NewTagsClient() instead.
type TagsClient struct {
host string
internal *arm.Client
subscriptionID string
pl runtime.Pipeline
}
// NewTagsClient creates a new instance of TagsClient with the specified values.
// subscriptionID - The Microsoft Azure subscription ID.
// credential - used to authorize requests. Usually a credential from azidentity.
// options - pass nil to accept the default values.
// - subscriptionID - The Microsoft Azure subscription ID.
// - credential - used to authorize requests. Usually a credential from azidentity.
// - options - pass nil to accept the default values.
func NewTagsClient(subscriptionID string, credential azcore.TokenCredential, options *arm.ClientOptions) (*TagsClient, error) {
if options == nil {
options = &arm.ClientOptions{}
}
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, credential, runtime.PipelineOptions{}, options)
cl, err := arm.NewClient(moduleName, moduleVersion, credential, options)
if err != nil {
return nil, err
}
client := &TagsClient{
subscriptionID: subscriptionID,
host: ep,
pl: pl,
internal: cl,
}
return client, nil
}
@ -58,22 +47,30 @@ func NewTagsClient(subscriptionID string, credential azcore.TokenCredential, opt
// tag name can have a maximum of 512 characters and is case-insensitive. Tag names cannot have the
// following prefixes which are reserved for Azure use: 'microsoft', 'azure', 'windows'.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// tagName - The name of the tag to create.
// options - TagsClientCreateOrUpdateOptions contains the optional parameters for the TagsClient.CreateOrUpdate method.
// - tagName - The name of the tag to create.
// - options - TagsClientCreateOrUpdateOptions contains the optional parameters for the TagsClient.CreateOrUpdate method.
func (client *TagsClient) CreateOrUpdate(ctx context.Context, tagName string, options *TagsClientCreateOrUpdateOptions) (TagsClientCreateOrUpdateResponse, error) {
var err error
const operationName = "TagsClient.CreateOrUpdate"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.createOrUpdateCreateRequest(ctx, tagName, options)
if err != nil {
return TagsClientCreateOrUpdateResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return TagsClientCreateOrUpdateResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK, http.StatusCreated) {
return TagsClientCreateOrUpdateResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) {
err = runtime.NewResponseError(httpResp)
return TagsClientCreateOrUpdateResponse{}, err
}
return client.createOrUpdateHandleResponse(resp)
resp, err := client.createOrUpdateHandleResponse(httpResp)
return resp, err
}
// createOrUpdateCreateRequest creates the CreateOrUpdate request.
@ -87,7 +84,7 @@ func (client *TagsClient) createOrUpdateCreateRequest(ctx context.Context, tagNa
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -110,30 +107,38 @@ func (client *TagsClient) createOrUpdateHandleResponse(resp *http.Response) (Tag
// CreateOrUpdateAtScope - This operation allows adding or replacing the entire set of tags on the specified resource or subscription.
// The specified entity can have a maximum of 50 tags.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// scope - The resource scope.
// options - TagsClientCreateOrUpdateAtScopeOptions contains the optional parameters for the TagsClient.CreateOrUpdateAtScope
// method.
// - scope - The resource scope.
// - options - TagsClientCreateOrUpdateAtScopeOptions contains the optional parameters for the TagsClient.CreateOrUpdateAtScope
// method.
func (client *TagsClient) CreateOrUpdateAtScope(ctx context.Context, scope string, parameters TagsResource, options *TagsClientCreateOrUpdateAtScopeOptions) (TagsClientCreateOrUpdateAtScopeResponse, error) {
var err error
const operationName = "TagsClient.CreateOrUpdateAtScope"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.createOrUpdateAtScopeCreateRequest(ctx, scope, parameters, options)
if err != nil {
return TagsClientCreateOrUpdateAtScopeResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return TagsClientCreateOrUpdateAtScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return TagsClientCreateOrUpdateAtScopeResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return TagsClientCreateOrUpdateAtScopeResponse{}, err
}
return client.createOrUpdateAtScopeHandleResponse(resp)
resp, err := client.createOrUpdateAtScopeHandleResponse(httpResp)
return resp, err
}
// createOrUpdateAtScopeCreateRequest creates the CreateOrUpdateAtScope request.
func (client *TagsClient) createOrUpdateAtScopeCreateRequest(ctx context.Context, scope string, parameters TagsResource, options *TagsClientCreateOrUpdateAtScopeOptions) (*policy.Request, error) {
urlPath := "/{scope}/providers/Microsoft.Resources/tags/default"
urlPath = strings.ReplaceAll(urlPath, "{scope}", scope)
req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -141,7 +146,10 @@ func (client *TagsClient) createOrUpdateAtScopeCreateRequest(ctx context.Context
reqQP.Set("api-version", "2021-04-01")
req.Raw().URL.RawQuery = reqQP.Encode()
req.Raw().Header["Accept"] = []string{"application/json"}
return req, runtime.MarshalAsJSON(req, parameters)
if err := runtime.MarshalAsJSON(req, parameters); err != nil {
return nil, err
}
return req, nil
}
// createOrUpdateAtScopeHandleResponse handles the CreateOrUpdateAtScope response.
@ -156,24 +164,32 @@ func (client *TagsClient) createOrUpdateAtScopeHandleResponse(resp *http.Respons
// CreateOrUpdateValue - This operation allows adding a value to the list of predefined values for an existing predefined
// tag name. A tag value can have a maximum of 256 characters.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// tagName - The name of the tag.
// tagValue - The value of the tag to create.
// options - TagsClientCreateOrUpdateValueOptions contains the optional parameters for the TagsClient.CreateOrUpdateValue
// method.
// - tagName - The name of the tag.
// - tagValue - The value of the tag to create.
// - options - TagsClientCreateOrUpdateValueOptions contains the optional parameters for the TagsClient.CreateOrUpdateValue
// method.
func (client *TagsClient) CreateOrUpdateValue(ctx context.Context, tagName string, tagValue string, options *TagsClientCreateOrUpdateValueOptions) (TagsClientCreateOrUpdateValueResponse, error) {
var err error
const operationName = "TagsClient.CreateOrUpdateValue"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.createOrUpdateValueCreateRequest(ctx, tagName, tagValue, options)
if err != nil {
return TagsClientCreateOrUpdateValueResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return TagsClientCreateOrUpdateValueResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK, http.StatusCreated) {
return TagsClientCreateOrUpdateValueResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusCreated) {
err = runtime.NewResponseError(httpResp)
return TagsClientCreateOrUpdateValueResponse{}, err
}
return client.createOrUpdateValueHandleResponse(resp)
resp, err := client.createOrUpdateValueHandleResponse(httpResp)
return resp, err
}
// createOrUpdateValueCreateRequest creates the CreateOrUpdateValue request.
@ -191,7 +207,7 @@ func (client *TagsClient) createOrUpdateValueCreateRequest(ctx context.Context,
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodPut, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -215,20 +231,27 @@ func (client *TagsClient) createOrUpdateValueHandleResponse(resp *http.Response)
// being deleted must not be in use as a tag name for any resource. All predefined values
// for the given name must have already been deleted.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// tagName - The name of the tag.
// options - TagsClientDeleteOptions contains the optional parameters for the TagsClient.Delete method.
// - tagName - The name of the tag.
// - options - TagsClientDeleteOptions contains the optional parameters for the TagsClient.Delete method.
func (client *TagsClient) Delete(ctx context.Context, tagName string, options *TagsClientDeleteOptions) (TagsClientDeleteResponse, error) {
var err error
const operationName = "TagsClient.Delete"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.deleteCreateRequest(ctx, tagName, options)
if err != nil {
return TagsClientDeleteResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return TagsClientDeleteResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK, http.StatusNoContent) {
return TagsClientDeleteResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusNoContent) {
err = runtime.NewResponseError(httpResp)
return TagsClientDeleteResponse{}, err
}
return TagsClientDeleteResponse{}, nil
}
@ -244,7 +267,7 @@ func (client *TagsClient) deleteCreateRequest(ctx context.Context, tagName strin
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -257,20 +280,27 @@ func (client *TagsClient) deleteCreateRequest(ctx context.Context, tagName strin
// DeleteAtScope - Deletes the entire set of tags on a resource or subscription.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// scope - The resource scope.
// options - TagsClientDeleteAtScopeOptions contains the optional parameters for the TagsClient.DeleteAtScope method.
// - scope - The resource scope.
// - options - TagsClientDeleteAtScopeOptions contains the optional parameters for the TagsClient.DeleteAtScope method.
func (client *TagsClient) DeleteAtScope(ctx context.Context, scope string, options *TagsClientDeleteAtScopeOptions) (TagsClientDeleteAtScopeResponse, error) {
var err error
const operationName = "TagsClient.DeleteAtScope"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.deleteAtScopeCreateRequest(ctx, scope, options)
if err != nil {
return TagsClientDeleteAtScopeResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return TagsClientDeleteAtScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return TagsClientDeleteAtScopeResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return TagsClientDeleteAtScopeResponse{}, err
}
return TagsClientDeleteAtScopeResponse{}, nil
}
@ -279,7 +309,7 @@ func (client *TagsClient) DeleteAtScope(ctx context.Context, scope string, optio
func (client *TagsClient) deleteAtScopeCreateRequest(ctx context.Context, scope string, options *TagsClientDeleteAtScopeOptions) (*policy.Request, error) {
urlPath := "/{scope}/providers/Microsoft.Resources/tags/default"
urlPath = strings.ReplaceAll(urlPath, "{scope}", scope)
req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -294,21 +324,28 @@ func (client *TagsClient) deleteAtScopeCreateRequest(ctx context.Context, scope
// name. The value being deleted must not be in use as a tag value for the given tag name for any
// resource.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// tagName - The name of the tag.
// tagValue - The value of the tag to delete.
// options - TagsClientDeleteValueOptions contains the optional parameters for the TagsClient.DeleteValue method.
// - tagName - The name of the tag.
// - tagValue - The value of the tag to delete.
// - options - TagsClientDeleteValueOptions contains the optional parameters for the TagsClient.DeleteValue method.
func (client *TagsClient) DeleteValue(ctx context.Context, tagName string, tagValue string, options *TagsClientDeleteValueOptions) (TagsClientDeleteValueResponse, error) {
var err error
const operationName = "TagsClient.DeleteValue"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.deleteValueCreateRequest(ctx, tagName, tagValue, options)
if err != nil {
return TagsClientDeleteValueResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return TagsClientDeleteValueResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK, http.StatusNoContent) {
return TagsClientDeleteValueResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK, http.StatusNoContent) {
err = runtime.NewResponseError(httpResp)
return TagsClientDeleteValueResponse{}, err
}
return TagsClientDeleteValueResponse{}, nil
}
@ -328,7 +365,7 @@ func (client *TagsClient) deleteValueCreateRequest(ctx context.Context, tagName
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodDelete, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -341,29 +378,37 @@ func (client *TagsClient) deleteValueCreateRequest(ctx context.Context, tagName
// GetAtScope - Gets the entire set of tags on a resource or subscription.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// scope - The resource scope.
// options - TagsClientGetAtScopeOptions contains the optional parameters for the TagsClient.GetAtScope method.
// - scope - The resource scope.
// - options - TagsClientGetAtScopeOptions contains the optional parameters for the TagsClient.GetAtScope method.
func (client *TagsClient) GetAtScope(ctx context.Context, scope string, options *TagsClientGetAtScopeOptions) (TagsClientGetAtScopeResponse, error) {
var err error
const operationName = "TagsClient.GetAtScope"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.getAtScopeCreateRequest(ctx, scope, options)
if err != nil {
return TagsClientGetAtScopeResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return TagsClientGetAtScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return TagsClientGetAtScopeResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return TagsClientGetAtScopeResponse{}, err
}
return client.getAtScopeHandleResponse(resp)
resp, err := client.getAtScopeHandleResponse(httpResp)
return resp, err
}
// getAtScopeCreateRequest creates the GetAtScope request.
func (client *TagsClient) getAtScopeCreateRequest(ctx context.Context, scope string, options *TagsClientGetAtScopeOptions) (*policy.Request, error) {
urlPath := "/{scope}/providers/Microsoft.Resources/tags/default"
urlPath = strings.ReplaceAll(urlPath, "{scope}", scope)
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -386,34 +431,29 @@ func (client *TagsClient) getAtScopeHandleResponse(resp *http.Response) (TagsCli
// NewListPager - This operation performs a union of predefined tags, resource tags, resource group tags and subscription
// tags, and returns a summary of usage for each tag name and value under the given subscription.
// In case of a large number of tags, this operation may return a previously cached result.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// options - TagsClientListOptions contains the optional parameters for the TagsClient.List method.
// - options - TagsClientListOptions contains the optional parameters for the TagsClient.NewListPager method.
func (client *TagsClient) NewListPager(options *TagsClientListOptions) *runtime.Pager[TagsClientListResponse] {
return runtime.NewPager(runtime.PagingHandler[TagsClientListResponse]{
More: func(page TagsClientListResponse) bool {
return page.NextLink != nil && len(*page.NextLink) > 0
},
Fetcher: func(ctx context.Context, page *TagsClientListResponse) (TagsClientListResponse, error) {
var req *policy.Request
var err error
if page == nil {
req, err = client.listCreateRequest(ctx, options)
} else {
req, err = runtime.NewRequest(ctx, http.MethodGet, *page.NextLink)
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "TagsClient.NewListPager")
nextLink := ""
if page != nil {
nextLink = *page.NextLink
}
resp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), nextLink, func(ctx context.Context) (*policy.Request, error) {
return client.listCreateRequest(ctx, options)
}, nil)
if err != nil {
return TagsClientListResponse{}, err
}
resp, err := client.pl.Do(req)
if err != nil {
return TagsClientListResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return TagsClientListResponse{}, runtime.NewResponseError(resp)
}
return client.listHandleResponse(resp)
},
Tracer: client.internal.Tracer(),
})
}
@ -424,7 +464,7 @@ func (client *TagsClient) listCreateRequest(ctx context.Context, options *TagsCl
return nil, errors.New("parameter client.subscriptionID cannot be empty")
}
urlPath = strings.ReplaceAll(urlPath, "{subscriptionId}", url.PathEscape(client.subscriptionID))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodGet, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -450,29 +490,37 @@ func (client *TagsClient) listHandleResponse(resp *http.Response) (TagsClientLis
// names and updating the values of tags with existing names. The 'delete' option
// allows selectively deleting tags based on given names or name/value pairs.
// If the operation fails it returns an *azcore.ResponseError type.
//
// Generated from API version 2021-04-01
// scope - The resource scope.
// options - TagsClientUpdateAtScopeOptions contains the optional parameters for the TagsClient.UpdateAtScope method.
// - scope - The resource scope.
// - options - TagsClientUpdateAtScopeOptions contains the optional parameters for the TagsClient.UpdateAtScope method.
func (client *TagsClient) UpdateAtScope(ctx context.Context, scope string, parameters TagsPatchResource, options *TagsClientUpdateAtScopeOptions) (TagsClientUpdateAtScopeResponse, error) {
var err error
const operationName = "TagsClient.UpdateAtScope"
ctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, operationName)
ctx, endSpan := runtime.StartSpan(ctx, operationName, client.internal.Tracer(), nil)
defer func() { endSpan(err) }()
req, err := client.updateAtScopeCreateRequest(ctx, scope, parameters, options)
if err != nil {
return TagsClientUpdateAtScopeResponse{}, err
}
resp, err := client.pl.Do(req)
httpResp, err := client.internal.Pipeline().Do(req)
if err != nil {
return TagsClientUpdateAtScopeResponse{}, err
}
if !runtime.HasStatusCode(resp, http.StatusOK) {
return TagsClientUpdateAtScopeResponse{}, runtime.NewResponseError(resp)
if !runtime.HasStatusCode(httpResp, http.StatusOK) {
err = runtime.NewResponseError(httpResp)
return TagsClientUpdateAtScopeResponse{}, err
}
return client.updateAtScopeHandleResponse(resp)
resp, err := client.updateAtScopeHandleResponse(httpResp)
return resp, err
}
// updateAtScopeCreateRequest creates the UpdateAtScope request.
func (client *TagsClient) updateAtScopeCreateRequest(ctx context.Context, scope string, parameters TagsPatchResource, options *TagsClientUpdateAtScopeOptions) (*policy.Request, error) {
urlPath := "/{scope}/providers/Microsoft.Resources/tags/default"
urlPath = strings.ReplaceAll(urlPath, "{scope}", scope)
req, err := runtime.NewRequest(ctx, http.MethodPatch, runtime.JoinPaths(client.host, urlPath))
req, err := runtime.NewRequest(ctx, http.MethodPatch, runtime.JoinPaths(client.internal.Endpoint(), urlPath))
if err != nil {
return nil, err
}
@ -480,7 +528,10 @@ func (client *TagsClient) updateAtScopeCreateRequest(ctx context.Context, scope
reqQP.Set("api-version", "2021-04-01")
req.Raw().URL.RawQuery = reqQP.Encode()
req.Raw().Header["Accept"] = []string{"application/json"}
return req, runtime.MarshalAsJSON(req, parameters)
if err := runtime.MarshalAsJSON(req, parameters); err != nil {
return nil, err
}
return req, nil
}
// updateAtScopeHandleResponse handles the UpdateAtScope response.

View File

@ -3,7 +3,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
package armresources
@ -18,50 +18,50 @@ import (
"time"
)
const (
utcLayoutJSON = `"2006-01-02T15:04:05.999999999"`
utcLayout = "2006-01-02T15:04:05.999999999"
rfc3339JSON = `"` + time.RFC3339Nano + `"`
)
// Azure reports time in UTC but it doesn't include the 'Z' time zone suffix in some cases.
var tzOffsetRegex = regexp.MustCompile(`(Z|z|\+|-)(\d+:\d+)*"*$`)
type timeRFC3339 time.Time
const (
utcDateTimeJSON = `"2006-01-02T15:04:05.999999999"`
utcDateTime = "2006-01-02T15:04:05.999999999"
dateTimeJSON = `"` + time.RFC3339Nano + `"`
)
func (t timeRFC3339) MarshalJSON() (json []byte, err error) {
type dateTimeRFC3339 time.Time
func (t dateTimeRFC3339) MarshalJSON() ([]byte, error) {
tt := time.Time(t)
return tt.MarshalJSON()
}
func (t timeRFC3339) MarshalText() (text []byte, err error) {
func (t dateTimeRFC3339) MarshalText() ([]byte, error) {
tt := time.Time(t)
return tt.MarshalText()
}
func (t *timeRFC3339) UnmarshalJSON(data []byte) error {
layout := utcLayoutJSON
func (t *dateTimeRFC3339) UnmarshalJSON(data []byte) error {
layout := utcDateTimeJSON
if tzOffsetRegex.Match(data) {
layout = rfc3339JSON
layout = dateTimeJSON
}
return t.Parse(layout, string(data))
}
func (t *timeRFC3339) UnmarshalText(data []byte) (err error) {
layout := utcLayout
func (t *dateTimeRFC3339) UnmarshalText(data []byte) error {
layout := utcDateTime
if tzOffsetRegex.Match(data) {
layout = time.RFC3339Nano
}
return t.Parse(layout, string(data))
}
func (t *timeRFC3339) Parse(layout, value string) error {
func (t *dateTimeRFC3339) Parse(layout, value string) error {
p, err := time.Parse(layout, strings.ToUpper(value))
*t = timeRFC3339(p)
*t = dateTimeRFC3339(p)
return err
}
func populateTimeRFC3339(m map[string]interface{}, k string, t *time.Time) {
func populateDateTimeRFC3339(m map[string]any, k string, t *time.Time) {
if t == nil {
return
} else if azcore.IsNullValue(t) {
@ -70,14 +70,14 @@ func populateTimeRFC3339(m map[string]interface{}, k string, t *time.Time) {
} else if reflect.ValueOf(t).IsNil() {
return
}
m[k] = (*timeRFC3339)(t)
m[k] = (*dateTimeRFC3339)(t)
}
func unpopulateTimeRFC3339(data json.RawMessage, fn string, t **time.Time) error {
func unpopulateDateTimeRFC3339(data json.RawMessage, fn string, t **time.Time) error {
if data == nil || strings.EqualFold(string(data), "null") {
return nil
}
var aux timeRFC3339
var aux dateTimeRFC3339
if err := json.Unmarshal(data, &aux); err != nil {
return fmt.Errorf("struct field %s: %v", fn, err)
}

View File

@ -1,346 +0,0 @@
//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
package armresources
import (
"encoding/json"
"fmt"
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"reflect"
)
// MarshalJSON implements the json.Marshaller interface for type Deployment.
func (d Deployment) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
populate(objectMap, "location", d.Location)
populate(objectMap, "properties", d.Properties)
populate(objectMap, "tags", d.Tags)
return json.Marshal(objectMap)
}
// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentOperationProperties.
func (d *DeploymentOperationProperties) UnmarshalJSON(data []byte) error {
var rawMsg map[string]json.RawMessage
if err := json.Unmarshal(data, &rawMsg); err != nil {
return fmt.Errorf("unmarshalling type %T: %v", d, err)
}
for key, val := range rawMsg {
var err error
switch key {
case "duration":
err = unpopulate(val, "Duration", &d.Duration)
delete(rawMsg, key)
case "provisioningOperation":
err = unpopulate(val, "ProvisioningOperation", &d.ProvisioningOperation)
delete(rawMsg, key)
case "provisioningState":
err = unpopulate(val, "ProvisioningState", &d.ProvisioningState)
delete(rawMsg, key)
case "request":
err = unpopulate(val, "Request", &d.Request)
delete(rawMsg, key)
case "response":
err = unpopulate(val, "Response", &d.Response)
delete(rawMsg, key)
case "serviceRequestId":
err = unpopulate(val, "ServiceRequestID", &d.ServiceRequestID)
delete(rawMsg, key)
case "statusCode":
err = unpopulate(val, "StatusCode", &d.StatusCode)
delete(rawMsg, key)
case "statusMessage":
err = unpopulate(val, "StatusMessage", &d.StatusMessage)
delete(rawMsg, key)
case "targetResource":
err = unpopulate(val, "TargetResource", &d.TargetResource)
delete(rawMsg, key)
case "timestamp":
err = unpopulateTimeRFC3339(val, "Timestamp", &d.Timestamp)
delete(rawMsg, key)
}
if err != nil {
return fmt.Errorf("unmarshalling type %T: %v", d, err)
}
}
return nil
}
// UnmarshalJSON implements the json.Unmarshaller interface for type DeploymentPropertiesExtended.
func (d *DeploymentPropertiesExtended) UnmarshalJSON(data []byte) error {
var rawMsg map[string]json.RawMessage
if err := json.Unmarshal(data, &rawMsg); err != nil {
return fmt.Errorf("unmarshalling type %T: %v", d, err)
}
for key, val := range rawMsg {
var err error
switch key {
case "correlationId":
err = unpopulate(val, "CorrelationID", &d.CorrelationID)
delete(rawMsg, key)
case "debugSetting":
err = unpopulate(val, "DebugSetting", &d.DebugSetting)
delete(rawMsg, key)
case "dependencies":
err = unpopulate(val, "Dependencies", &d.Dependencies)
delete(rawMsg, key)
case "duration":
err = unpopulate(val, "Duration", &d.Duration)
delete(rawMsg, key)
case "error":
err = unpopulate(val, "Error", &d.Error)
delete(rawMsg, key)
case "mode":
err = unpopulate(val, "Mode", &d.Mode)
delete(rawMsg, key)
case "onErrorDeployment":
err = unpopulate(val, "OnErrorDeployment", &d.OnErrorDeployment)
delete(rawMsg, key)
case "outputResources":
err = unpopulate(val, "OutputResources", &d.OutputResources)
delete(rawMsg, key)
case "outputs":
err = unpopulate(val, "Outputs", &d.Outputs)
delete(rawMsg, key)
case "parameters":
err = unpopulate(val, "Parameters", &d.Parameters)
delete(rawMsg, key)
case "parametersLink":
err = unpopulate(val, "ParametersLink", &d.ParametersLink)
delete(rawMsg, key)
case "providers":
err = unpopulate(val, "Providers", &d.Providers)
delete(rawMsg, key)
case "provisioningState":
err = unpopulate(val, "ProvisioningState", &d.ProvisioningState)
delete(rawMsg, key)
case "templateHash":
err = unpopulate(val, "TemplateHash", &d.TemplateHash)
delete(rawMsg, key)
case "templateLink":
err = unpopulate(val, "TemplateLink", &d.TemplateLink)
delete(rawMsg, key)
case "timestamp":
err = unpopulateTimeRFC3339(val, "Timestamp", &d.Timestamp)
delete(rawMsg, key)
case "validatedResources":
err = unpopulate(val, "ValidatedResources", &d.ValidatedResources)
delete(rawMsg, key)
}
if err != nil {
return fmt.Errorf("unmarshalling type %T: %v", d, err)
}
}
return nil
}
// MarshalJSON implements the json.Marshaller interface for type ExportTemplateRequest.
func (e ExportTemplateRequest) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
populate(objectMap, "options", e.Options)
populate(objectMap, "resources", e.Resources)
return json.Marshal(objectMap)
}
// MarshalJSON implements the json.Marshaller interface for type GenericResource.
func (g GenericResource) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
populate(objectMap, "extendedLocation", g.ExtendedLocation)
populate(objectMap, "id", g.ID)
populate(objectMap, "identity", g.Identity)
populate(objectMap, "kind", g.Kind)
populate(objectMap, "location", g.Location)
populate(objectMap, "managedBy", g.ManagedBy)
populate(objectMap, "name", g.Name)
populate(objectMap, "plan", g.Plan)
populate(objectMap, "properties", &g.Properties)
populate(objectMap, "sku", g.SKU)
populate(objectMap, "tags", g.Tags)
populate(objectMap, "type", g.Type)
return json.Marshal(objectMap)
}
// MarshalJSON implements the json.Marshaller interface for type GenericResourceExpanded.
func (g GenericResourceExpanded) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
populateTimeRFC3339(objectMap, "changedTime", g.ChangedTime)
populateTimeRFC3339(objectMap, "createdTime", g.CreatedTime)
populate(objectMap, "extendedLocation", g.ExtendedLocation)
populate(objectMap, "id", g.ID)
populate(objectMap, "identity", g.Identity)
populate(objectMap, "kind", g.Kind)
populate(objectMap, "location", g.Location)
populate(objectMap, "managedBy", g.ManagedBy)
populate(objectMap, "name", g.Name)
populate(objectMap, "plan", g.Plan)
populate(objectMap, "properties", &g.Properties)
populate(objectMap, "provisioningState", g.ProvisioningState)
populate(objectMap, "sku", g.SKU)
populate(objectMap, "tags", g.Tags)
populate(objectMap, "type", g.Type)
return json.Marshal(objectMap)
}
// UnmarshalJSON implements the json.Unmarshaller interface for type GenericResourceExpanded.
func (g *GenericResourceExpanded) UnmarshalJSON(data []byte) error {
var rawMsg map[string]json.RawMessage
if err := json.Unmarshal(data, &rawMsg); err != nil {
return fmt.Errorf("unmarshalling type %T: %v", g, err)
}
for key, val := range rawMsg {
var err error
switch key {
case "changedTime":
err = unpopulateTimeRFC3339(val, "ChangedTime", &g.ChangedTime)
delete(rawMsg, key)
case "createdTime":
err = unpopulateTimeRFC3339(val, "CreatedTime", &g.CreatedTime)
delete(rawMsg, key)
case "extendedLocation":
err = unpopulate(val, "ExtendedLocation", &g.ExtendedLocation)
delete(rawMsg, key)
case "id":
err = unpopulate(val, "ID", &g.ID)
delete(rawMsg, key)
case "identity":
err = unpopulate(val, "Identity", &g.Identity)
delete(rawMsg, key)
case "kind":
err = unpopulate(val, "Kind", &g.Kind)
delete(rawMsg, key)
case "location":
err = unpopulate(val, "Location", &g.Location)
delete(rawMsg, key)
case "managedBy":
err = unpopulate(val, "ManagedBy", &g.ManagedBy)
delete(rawMsg, key)
case "name":
err = unpopulate(val, "Name", &g.Name)
delete(rawMsg, key)
case "plan":
err = unpopulate(val, "Plan", &g.Plan)
delete(rawMsg, key)
case "properties":
err = unpopulate(val, "Properties", &g.Properties)
delete(rawMsg, key)
case "provisioningState":
err = unpopulate(val, "ProvisioningState", &g.ProvisioningState)
delete(rawMsg, key)
case "sku":
err = unpopulate(val, "SKU", &g.SKU)
delete(rawMsg, key)
case "tags":
err = unpopulate(val, "Tags", &g.Tags)
delete(rawMsg, key)
case "type":
err = unpopulate(val, "Type", &g.Type)
delete(rawMsg, key)
}
if err != nil {
return fmt.Errorf("unmarshalling type %T: %v", g, err)
}
}
return nil
}
// MarshalJSON implements the json.Marshaller interface for type Identity.
func (i Identity) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
populate(objectMap, "principalId", i.PrincipalID)
populate(objectMap, "tenantId", i.TenantID)
populate(objectMap, "type", i.Type)
populate(objectMap, "userAssignedIdentities", i.UserAssignedIdentities)
return json.Marshal(objectMap)
}
// MarshalJSON implements the json.Marshaller interface for type MoveInfo.
func (m MoveInfo) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
populate(objectMap, "resources", m.Resources)
populate(objectMap, "targetResourceGroup", m.TargetResourceGroup)
return json.Marshal(objectMap)
}
// MarshalJSON implements the json.Marshaller interface for type Resource.
func (r Resource) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
populate(objectMap, "extendedLocation", r.ExtendedLocation)
populate(objectMap, "id", r.ID)
populate(objectMap, "location", r.Location)
populate(objectMap, "name", r.Name)
populate(objectMap, "tags", r.Tags)
populate(objectMap, "type", r.Type)
return json.Marshal(objectMap)
}
// MarshalJSON implements the json.Marshaller interface for type ResourceGroup.
func (r ResourceGroup) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
populate(objectMap, "id", r.ID)
populate(objectMap, "location", r.Location)
populate(objectMap, "managedBy", r.ManagedBy)
populate(objectMap, "name", r.Name)
populate(objectMap, "properties", r.Properties)
populate(objectMap, "tags", r.Tags)
populate(objectMap, "type", r.Type)
return json.Marshal(objectMap)
}
// MarshalJSON implements the json.Marshaller interface for type ResourceGroupPatchable.
func (r ResourceGroupPatchable) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
populate(objectMap, "managedBy", r.ManagedBy)
populate(objectMap, "name", r.Name)
populate(objectMap, "properties", r.Properties)
populate(objectMap, "tags", r.Tags)
return json.Marshal(objectMap)
}
// MarshalJSON implements the json.Marshaller interface for type ScopedDeployment.
func (s ScopedDeployment) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
populate(objectMap, "location", s.Location)
populate(objectMap, "properties", s.Properties)
populate(objectMap, "tags", s.Tags)
return json.Marshal(objectMap)
}
// MarshalJSON implements the json.Marshaller interface for type Tags.
func (t Tags) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
populate(objectMap, "tags", t.Tags)
return json.Marshal(objectMap)
}
// MarshalJSON implements the json.Marshaller interface for type TagsPatchResource.
func (t TagsPatchResource) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
populate(objectMap, "operation", t.Operation)
populate(objectMap, "properties", t.Properties)
return json.Marshal(objectMap)
}
func populate(m map[string]interface{}, k string, v interface{}) {
if v == nil {
return
} else if azcore.IsNullValue(v) {
m[k] = nil
} else if !reflect.ValueOf(v).IsNil() {
m[k] = v
}
}
func unpopulate(data json.RawMessage, fn string, v interface{}) error {
if data == nil {
return nil
}
if err := json.Unmarshal(data, v); err != nil {
return fmt.Errorf("struct field %s: %v", fn, err)
}
return nil
}

View File

@ -59,6 +59,8 @@ added, it doesn't exist in real life. As such I've put a PEM decoder into here.
// For details see https://aka.ms/msal-net-authenticationresult
type AuthResult = base.AuthResult
type AuthenticationScheme = authority.AuthenticationScheme
type Account = shared.Account
// CertFromPEM converts a PEM file (.pem or .key) for use with [NewCredFromCert]. The file
@ -454,6 +456,33 @@ func WithClaims(claims string) interface {
}
}
// WithAuthenticationScheme is an extensibility mechanism designed to be used only by Azure Arc for proof of possession access tokens.
func WithAuthenticationScheme(authnScheme AuthenticationScheme) interface {
AcquireSilentOption
AcquireByCredentialOption
options.CallOption
} {
return struct {
AcquireSilentOption
AcquireByCredentialOption
options.CallOption
}{
CallOption: options.NewCallOption(
func(a any) error {
switch t := a.(type) {
case *acquireTokenSilentOptions:
t.authnScheme = authnScheme
case *acquireTokenByCredentialOptions:
t.authnScheme = authnScheme
default:
return fmt.Errorf("unexpected options type %T", a)
}
return nil
},
),
}
}
// WithTenantID specifies a tenant for a single authentication. It may be different than the tenant set in [New].
// This option is valid for any token acquisition method.
func WithTenantID(tenantID string) interface {
@ -499,6 +528,7 @@ func WithTenantID(tenantID string) interface {
type acquireTokenSilentOptions struct {
account Account
claims, tenantID string
authnScheme AuthenticationScheme
}
// AcquireSilentOption is implemented by options for AcquireTokenSilent
@ -549,6 +579,7 @@ func (cca Client) AcquireTokenSilent(ctx context.Context, scopes []string, opts
Credential: cca.cred,
IsAppCache: o.account.IsZero(),
TenantID: o.tenantID,
AuthnScheme: o.authnScheme,
}
return cca.base.AcquireTokenSilent(ctx, silentParameters)
@ -614,6 +645,7 @@ func (cca Client) AcquireTokenByAuthCode(ctx context.Context, code string, redir
// acquireTokenByCredentialOptions contains optional configuration for AcquireTokenByCredential
type acquireTokenByCredentialOptions struct {
claims, tenantID string
authnScheme AuthenticationScheme
}
// AcquireByCredentialOption is implemented by options for AcquireTokenByCredential
@ -637,7 +669,9 @@ func (cca Client) AcquireTokenByCredential(ctx context.Context, scopes []string,
authParams.Scopes = scopes
authParams.AuthorizationType = authority.ATClientCredentials
authParams.Claims = o.claims
if o.authnScheme != nil {
authParams.AuthnScheme = o.authnScheme
}
token, err := cca.base.Token.Credential(ctx, authParams, cca.cred)
if err != nil {
return AuthResult{}, err

View File

@ -54,6 +54,7 @@ type AcquireTokenSilentParameters struct {
UserAssertion string
AuthorizationType authority.AuthorizeType
Claims string
AuthnScheme authority.AuthenticationScheme
}
// AcquireTokenAuthCodeParameters contains the parameters required to acquire an access token using the auth code flow.
@ -289,6 +290,9 @@ func (b Client) AcquireTokenSilent(ctx context.Context, silent AcquireTokenSilen
authParams.AuthorizationType = silent.AuthorizationType
authParams.Claims = silent.Claims
authParams.UserAssertion = silent.UserAssertion
if silent.AuthnScheme != nil {
authParams.AuthnScheme = silent.AuthnScheme
}
m := b.pmanager
if authParams.AuthorizationType != authority.ATOnBehalfOf {
@ -313,6 +317,7 @@ func (b Client) AcquireTokenSilent(ctx context.Context, silent AcquireTokenSilen
if silent.Claims == "" {
ar, err = AuthResultFromStorage(storageTokenResponse)
if err == nil {
ar.AccessToken, err = authParams.AuthnScheme.FormatAccessToken(ar.AccessToken)
return ar, err
}
}
@ -417,6 +422,11 @@ func (b Client) AuthResultFromToken(ctx context.Context, authParams authority.Au
if err == nil && b.cacheAccessor != nil {
err = b.cacheAccessor.Export(ctx, b.manager, cache.ExportHints{PartitionKey: key})
}
if err != nil {
return AuthResult{}, err
}
ar.AccessToken, err = authParams.AuthnScheme.FormatAccessToken(ar.AccessToken)
return ar, err
}

View File

@ -12,6 +12,7 @@ import (
internalTime "github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/json/types/time"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/accesstokens"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/oauth/ops/authority"
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/shared"
)
@ -75,12 +76,14 @@ type AccessToken struct {
ExtendedExpiresOn internalTime.Unix `json:"extended_expires_on,omitempty"`
CachedAt internalTime.Unix `json:"cached_at,omitempty"`
UserAssertionHash string `json:"user_assertion_hash,omitempty"`
TokenType string `json:"token_type,omitempty"`
AuthnSchemeKeyID string `json:"keyid,omitempty"`
AdditionalFields map[string]interface{}
}
// NewAccessToken is the constructor for AccessToken.
func NewAccessToken(homeID, env, realm, clientID string, cachedAt, expiresOn, extendedExpiresOn time.Time, scopes, token string) AccessToken {
func NewAccessToken(homeID, env, realm, clientID string, cachedAt, expiresOn, extendedExpiresOn time.Time, scopes, token, tokenType, authnSchemeKeyID string) AccessToken {
return AccessToken{
HomeAccountID: homeID,
Environment: env,
@ -92,6 +95,8 @@ func NewAccessToken(homeID, env, realm, clientID string, cachedAt, expiresOn, ex
CachedAt: internalTime.Unix{T: cachedAt.UTC()},
ExpiresOn: internalTime.Unix{T: expiresOn.UTC()},
ExtendedExpiresOn: internalTime.Unix{T: extendedExpiresOn.UTC()},
TokenType: tokenType,
AuthnSchemeKeyID: authnSchemeKeyID,
}
}
@ -101,6 +106,11 @@ func (a AccessToken) Key() string {
[]string{a.HomeAccountID, a.Environment, a.CredentialType, a.ClientID, a.Realm, a.Scopes},
shared.CacheKeySeparator,
)
// add token type to key for new access tokens types. skip for bearer token type to
// preserve fwd and back compat between a common cache and msal clients
if !strings.EqualFold(a.TokenType, authority.AccessTokenTypeBearer) {
key = strings.Join([]string{key, a.TokenType}, shared.CacheKeySeparator)
}
return strings.ToLower(key)
}

View File

@ -41,6 +41,8 @@ func (m *PartitionedManager) Read(ctx context.Context, authParameters authority.
realm := authParameters.AuthorityInfo.Tenant
clientID := authParameters.ClientID
scopes := authParameters.Scopes
authnSchemeKeyID := authParameters.AuthnScheme.KeyID()
tokenType := authParameters.AuthnScheme.AccessTokenType()
// fetch metadata if instanceDiscovery is enabled
aliases := []string{authParameters.AuthorityInfo.Host}
@ -57,7 +59,7 @@ func (m *PartitionedManager) Read(ctx context.Context, authParameters authority.
// errors returned by read* methods indicate a cache miss and are therefore non-fatal. We continue populating
// TokenResponse fields so that e.g. lack of an ID token doesn't prevent the caller from receiving a refresh token.
accessToken, err := m.readAccessToken(aliases, realm, clientID, userAssertionHash, scopes, partitionKeyFromRequest)
accessToken, err := m.readAccessToken(aliases, realm, clientID, userAssertionHash, scopes, partitionKeyFromRequest, tokenType, authnSchemeKeyID)
if err == nil {
tr.AccessToken = accessToken
}
@ -92,7 +94,7 @@ func (m *PartitionedManager) Write(authParameters authority.AuthParams, tokenRes
target := strings.Join(tokenResponse.GrantedScopes.Slice, scopeSeparator)
userAssertionHash := authParameters.AssertionHash()
cachedAt := time.Now()
authnSchemeKeyID := authParameters.AuthnScheme.KeyID()
var account shared.Account
if len(tokenResponse.RefreshToken) > 0 {
@ -116,6 +118,8 @@ func (m *PartitionedManager) Write(authParameters authority.AuthParams, tokenRes
tokenResponse.ExtExpiresOn.T,
target,
tokenResponse.AccessToken,
tokenResponse.TokenType,
authnSchemeKeyID,
)
if authParameters.AuthorizationType == authority.ATOnBehalfOf {
accessToken.UserAssertionHash = userAssertionHash // get Hash method on this
@ -215,7 +219,7 @@ func (m *PartitionedManager) aadMetadata(ctx context.Context, authorityInfo auth
return m.aadCache[authorityInfo.Host], nil
}
func (m *PartitionedManager) readAccessToken(envAliases []string, realm, clientID, userAssertionHash string, scopes []string, partitionKey string) (AccessToken, error) {
func (m *PartitionedManager) readAccessToken(envAliases []string, realm, clientID, userAssertionHash string, scopes []string, partitionKey, tokenType, authnSchemeKeyID string) (AccessToken, error) {
m.contractMu.RLock()
defer m.contractMu.RUnlock()
if accessTokens, ok := m.contract.AccessTokensPartition[partitionKey]; ok {
@ -224,9 +228,11 @@ func (m *PartitionedManager) readAccessToken(envAliases []string, realm, clientI
// an issue, however if it does become a problem then we know where to look.
for _, at := range accessTokens {
if at.Realm == realm && at.ClientID == clientID && at.UserAssertionHash == userAssertionHash {
if checkAlias(at.Environment, envAliases) {
if isMatchingScopes(scopes, at.Scopes) {
return at, nil
if at.TokenType == tokenType && at.AuthnSchemeKeyID == authnSchemeKeyID {
if checkAlias(at.Environment, envAliases) {
if isMatchingScopes(scopes, at.Scopes) {
return at, nil
}
}
}
}

View File

@ -82,6 +82,39 @@ func isMatchingScopes(scopesOne []string, scopesTwo string) bool {
return scopeCounter == len(scopesOne)
}
// needsUpgrade returns true if the given key follows the v1.0 schema i.e.,
// it contains an uppercase character (v1.1+ keys are all lowercase)
func needsUpgrade(key string) bool {
for _, r := range key {
if 'A' <= r && r <= 'Z' {
return true
}
}
return false
}
// upgrade a v1.0 cache item by adding a v1.1+ item having the same value and deleting
// the v1.0 item. Callers must hold an exclusive lock on m.
func upgrade[T any](m map[string]T, k string) T {
v1_1Key := strings.ToLower(k)
v, ok := m[k]
if !ok {
// another goroutine did the upgrade while this one was waiting for the write lock
return m[v1_1Key]
}
if v2, ok := m[v1_1Key]; ok {
// cache has an equivalent v1.1+ item, which we prefer because we know it was added
// by a newer version of the module and is therefore more likely to remain valid.
// The v1.0 item may have expired because only v1.0 or earlier would update it.
v = v2
} else {
// add an equivalent item according to the v1.1 schema
m[v1_1Key] = v
}
delete(m, k)
return v
}
// Read reads a storage token from the cache if it exists.
func (m *Manager) Read(ctx context.Context, authParameters authority.AuthParams) (TokenResponse, error) {
tr := TokenResponse{}
@ -89,6 +122,8 @@ func (m *Manager) Read(ctx context.Context, authParameters authority.AuthParams)
realm := authParameters.AuthorityInfo.Tenant
clientID := authParameters.ClientID
scopes := authParameters.Scopes
authnSchemeKeyID := authParameters.AuthnScheme.KeyID()
tokenType := authParameters.AuthnScheme.AccessTokenType()
// fetch metadata if instanceDiscovery is enabled
aliases := []string{authParameters.AuthorityInfo.Host}
@ -100,7 +135,7 @@ func (m *Manager) Read(ctx context.Context, authParameters authority.AuthParams)
aliases = metadata.Aliases
}
accessToken := m.readAccessToken(homeAccountID, aliases, realm, clientID, scopes)
accessToken := m.readAccessToken(homeAccountID, aliases, realm, clientID, scopes, tokenType, authnSchemeKeyID)
tr.AccessToken = accessToken
if homeAccountID == "" {
@ -140,6 +175,7 @@ func (m *Manager) Write(authParameters authority.AuthParams, tokenResponse acces
clientID := authParameters.ClientID
target := strings.Join(tokenResponse.GrantedScopes.Slice, scopeSeparator)
cachedAt := time.Now()
authnSchemeKeyID := authParameters.AuthnScheme.KeyID()
var account shared.Account
@ -161,6 +197,8 @@ func (m *Manager) Write(authParameters authority.AuthParams, tokenResponse acces
tokenResponse.ExtExpiresOn.T,
target,
tokenResponse.AccessToken,
tokenResponse.TokenType,
authnSchemeKeyID,
)
// Since we have a valid access token, cache it before moving on.
@ -248,21 +286,27 @@ func (m *Manager) aadMetadata(ctx context.Context, authorityInfo authority.Info)
return m.aadCache[authorityInfo.Host], nil
}
func (m *Manager) readAccessToken(homeID string, envAliases []string, realm, clientID string, scopes []string) AccessToken {
func (m *Manager) readAccessToken(homeID string, envAliases []string, realm, clientID string, scopes []string, tokenType, authnSchemeKeyID string) AccessToken {
m.contractMu.RLock()
defer m.contractMu.RUnlock()
// TODO: linear search (over a map no less) is slow for a large number (thousands) of tokens.
// this shows up as the dominating node in a profile. for real-world scenarios this likely isn't
// an issue, however if it does become a problem then we know where to look.
for _, at := range m.contract.AccessTokens {
for k, at := range m.contract.AccessTokens {
if at.HomeAccountID == homeID && at.Realm == realm && at.ClientID == clientID {
if checkAlias(at.Environment, envAliases) {
if isMatchingScopes(scopes, at.Scopes) {
if (strings.EqualFold(at.TokenType, tokenType) && at.AuthnSchemeKeyID == authnSchemeKeyID) || (at.TokenType == "" && (tokenType == "" || tokenType == "Bearer")) {
if checkAlias(at.Environment, envAliases) && isMatchingScopes(scopes, at.Scopes) {
m.contractMu.RUnlock()
if needsUpgrade(k) {
m.contractMu.Lock()
defer m.contractMu.Unlock()
at = upgrade(m.contract.AccessTokens, k)
}
return at
}
}
}
}
m.contractMu.RUnlock()
return AccessToken{}
}
@ -303,15 +347,21 @@ func (m *Manager) readRefreshToken(homeID string, envAliases []string, familyID,
// If app is part of the family or if we DO NOT KNOW if it's part of the family, search by family ID, then by client_id (we will know if an app is part of the family after the first token response).
// https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/blob/311fe8b16e7c293462806f397e189a6aa1159769/src/client/Microsoft.Identity.Client/Internal/Requests/Silent/CacheSilentStrategy.cs#L95
m.contractMu.RLock()
defer m.contractMu.RUnlock()
for _, matcher := range matchers {
for _, rt := range m.contract.RefreshTokens {
for k, rt := range m.contract.RefreshTokens {
if matcher(rt) {
m.contractMu.RUnlock()
if needsUpgrade(k) {
m.contractMu.Lock()
defer m.contractMu.Unlock()
rt = upgrade(m.contract.RefreshTokens, k)
}
return rt, nil
}
}
}
m.contractMu.RUnlock()
return accesstokens.RefreshToken{}, fmt.Errorf("refresh token not found")
}
@ -333,14 +383,20 @@ func (m *Manager) writeRefreshToken(refreshToken accesstokens.RefreshToken) erro
func (m *Manager) readIDToken(homeID string, envAliases []string, realm, clientID string) (IDToken, error) {
m.contractMu.RLock()
defer m.contractMu.RUnlock()
for _, idt := range m.contract.IDTokens {
for k, idt := range m.contract.IDTokens {
if idt.HomeAccountID == homeID && idt.Realm == realm && idt.ClientID == clientID {
if checkAlias(idt.Environment, envAliases) {
m.contractMu.RUnlock()
if needsUpgrade(k) {
m.contractMu.Lock()
defer m.contractMu.Unlock()
idt = upgrade(m.contract.IDTokens, k)
}
return idt, nil
}
}
}
m.contractMu.RUnlock()
return IDToken{}, fmt.Errorf("token not found")
}
@ -379,7 +435,6 @@ func (m *Manager) Account(homeAccountID string) shared.Account {
func (m *Manager) readAccount(homeAccountID string, envAliases []string, realm string) (shared.Account, error) {
m.contractMu.RLock()
defer m.contractMu.RUnlock()
// You might ask why, if cache.Accounts is a map, we would loop through all of these instead of using a key.
// We only use a map because the storage contract shared between all language implementations says use a map.
@ -387,11 +442,18 @@ func (m *Manager) readAccount(homeAccountID string, envAliases []string, realm s
// a match in multiple envs (envAlias). That means we either need to hash each possible keyand do the lookup
// or just statically check. Since the design is to have a storage.Manager per user, the amount of keys stored
// is really low (say 2). Each hash is more expensive than the entire iteration.
for _, acc := range m.contract.Accounts {
for k, acc := range m.contract.Accounts {
if acc.HomeAccountID == homeAccountID && checkAlias(acc.Environment, envAliases) && acc.Realm == realm {
m.contractMu.RUnlock()
if needsUpgrade(k) {
m.contractMu.Lock()
defer m.contractMu.Unlock()
acc = upgrade(m.contract.Accounts, k)
}
return acc, nil
}
}
m.contractMu.RUnlock()
return shared.Account{}, fmt.Errorf("account not found")
}
@ -405,13 +467,18 @@ func (m *Manager) writeAccount(account shared.Account) error {
func (m *Manager) readAppMetaData(envAliases []string, clientID string) (AppMetaData, error) {
m.contractMu.RLock()
defer m.contractMu.RUnlock()
for _, app := range m.contract.AppMetaData {
for k, app := range m.contract.AppMetaData {
if checkAlias(app.Environment, envAliases) && app.ClientID == clientID {
m.contractMu.RUnlock()
if needsUpgrade(k) {
m.contractMu.Lock()
defer m.contractMu.Unlock()
app = upgrade(m.contract.AppMetaData, k)
}
return app, nil
}
}
m.contractMu.RUnlock()
return AppMetaData{}, fmt.Errorf("not found")
}

View File

@ -119,6 +119,7 @@ func (t *Client) Credential(ctx context.Context, authParams authority.AuthParams
return accesstokens.TokenResponse{}, err
}
return accesstokens.TokenResponse{
TokenType: authParams.AuthnScheme.AccessTokenType(),
AccessToken: tr.AccessToken,
ExpiresOn: internalTime.DurationTime{
T: now.Add(time.Duration(tr.ExpiresInSeconds) * time.Second),

View File

@ -380,6 +380,12 @@ func (c Client) FromSamlGrant(ctx context.Context, authParameters authority.Auth
func (c Client) doTokenResp(ctx context.Context, authParams authority.AuthParams, qv url.Values) (TokenResponse, error) {
resp := TokenResponse{}
if authParams.AuthnScheme != nil {
trParams := authParams.AuthnScheme.TokenRequestParams()
for k, v := range trParams {
qv.Set(k, v)
}
}
err := c.Comm.URLFormCall(ctx, authParams.Endpoints.TokenEndpoint, qv, &resp)
if err != nil {
return resp, err

View File

@ -168,6 +168,7 @@ type TokenResponse struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
TokenType string `json:"token_type"`
FamilyID string `json:"foci"`
IDToken IDToken `json:"id_token"`

View File

@ -29,6 +29,7 @@ const (
defaultAPIVersion = "2021-10-01"
imdsEndpoint = "http://169.254.169.254/metadata/instance/compute/location?format=text&api-version=" + defaultAPIVersion
autoDetectRegion = "TryAutoDetect"
AccessTokenTypeBearer = "Bearer"
)
// These are various hosts that host AAD Instance discovery endpoints.
@ -138,6 +139,39 @@ const (
ADFS = "ADFS"
)
// AuthenticationScheme is an extensibility mechanism designed to be used only by Azure Arc for proof of possession access tokens.
type AuthenticationScheme interface {
// Extra parameters that are added to the request to the /token endpoint.
TokenRequestParams() map[string]string
// Key ID of the public / private key pair used by the encryption algorithm, if any.
// Tokens obtained by authentication schemes that use this are bound to the KeyId, i.e.
// if a different kid is presented, the access token cannot be used.
KeyID() string
// Creates the access token that goes into an Authorization HTTP header.
FormatAccessToken(accessToken string) (string, error)
//Expected to match the token_type parameter returned by ESTS. Used to disambiguate
// between ATs of different types (e.g. Bearer and PoP) when loading from cache etc.
AccessTokenType() string
}
// default authn scheme realizing AuthenticationScheme for "Bearer" tokens
type BearerAuthenticationScheme struct{}
var bearerAuthnScheme BearerAuthenticationScheme
func (ba *BearerAuthenticationScheme) TokenRequestParams() map[string]string {
return nil
}
func (ba *BearerAuthenticationScheme) KeyID() string {
return ""
}
func (ba *BearerAuthenticationScheme) FormatAccessToken(accessToken string) (string, error) {
return accessToken, nil
}
func (ba *BearerAuthenticationScheme) AccessTokenType() string {
return AccessTokenTypeBearer
}
// AuthParams represents the parameters used for authorization for token acquisition.
type AuthParams struct {
AuthorityInfo Info
@ -180,6 +214,8 @@ type AuthParams struct {
LoginHint string
// DomainHint is a directive that can be used to accelerate the user to their federated IdP sign-in page
DomainHint string
// AuthnScheme is an optional scheme for formatting access tokens
AuthnScheme AuthenticationScheme
}
// NewAuthParams creates an authorization parameters object.
@ -188,6 +224,7 @@ func NewAuthParams(clientID string, authorityInfo Info) AuthParams {
ClientID: clientID,
AuthorityInfo: authorityInfo,
CorrelationID: uuid.New().String(),
AuthnScheme: &bearerAuthnScheme,
}
}

View File

@ -5,4 +5,4 @@
package version
// Version is the version of this client package that is communicated to the server.
const Version = "1.1.1"
const Version = "1.2.0"

View File

@ -47,9 +47,11 @@ import (
// For details see https://aka.ms/msal-net-authenticationresult
type AuthResult = base.AuthResult
type AuthenticationScheme = authority.AuthenticationScheme
type Account = shared.Account
var errNoAccount = errors.New("no account was specified with public.WithAccount(), or the specified account is invalid")
var errNoAccount = errors.New("no account was specified with public.WithSilentAccount(), or the specified account is invalid")
// clientOptions configures the Client's behavior.
type clientOptions struct {
@ -211,6 +213,33 @@ func WithClaims(claims string) interface {
}
}
// WithAuthenticationScheme is an extensibility mechanism designed to be used only by Azure Arc for proof of possession access tokens.
func WithAuthenticationScheme(authnScheme AuthenticationScheme) interface {
AcquireSilentOption
AcquireInteractiveOption
options.CallOption
} {
return struct {
AcquireSilentOption
AcquireInteractiveOption
options.CallOption
}{
CallOption: options.NewCallOption(
func(a any) error {
switch t := a.(type) {
case *acquireTokenSilentOptions:
t.authnScheme = authnScheme
case *interactiveAuthOptions:
t.authnScheme = authnScheme
default:
return fmt.Errorf("unexpected options type %T", a)
}
return nil
},
),
}
}
// WithTenantID specifies a tenant for a single authentication. It may be different than the tenant set in [New] by [WithAuthority].
// This option is valid for any token acquisition method.
func WithTenantID(tenantID string) interface {
@ -260,6 +289,7 @@ func WithTenantID(tenantID string) interface {
type acquireTokenSilentOptions struct {
account Account
claims, tenantID string
authnScheme AuthenticationScheme
}
// AcquireSilentOption is implemented by options for AcquireTokenSilent
@ -310,6 +340,7 @@ func (pca Client) AcquireTokenSilent(ctx context.Context, scopes []string, opts
RequestType: accesstokens.ATPublic,
IsAppCache: false,
TenantID: o.tenantID,
AuthnScheme: o.authnScheme,
}
return pca.base.AcquireTokenSilent(ctx, silentParameters)
@ -482,6 +513,7 @@ func (pca Client) RemoveAccount(ctx context.Context, account Account) error {
type interactiveAuthOptions struct {
claims, domainHint, loginHint, redirectURI, tenantID string
openURL func(url string) error
authnScheme AuthenticationScheme
}
// AcquireInteractiveOption is implemented by options for AcquireTokenInteractive
@ -628,6 +660,9 @@ func (pca Client) AcquireTokenInteractive(ctx context.Context, scopes []string,
authParams.DomainHint = o.domainHint
authParams.State = uuid.New().String()
authParams.Prompt = "select_account"
if o.authnScheme != nil {
authParams.AuthnScheme = o.authnScheme
}
res, err := pca.browserLogin(ctx, redirectURL, authParams, o.openURL)
if err != nil {
return AuthResult{}, err

View File

@ -24795,16 +24795,6 @@ var awsPartition = partition{
},
},
Endpoints: serviceEndpoints{
endpointKey{
Region: "af-south-1",
}: endpoint{
Hostname: "resource-explorer-2.af-south-1.api.aws",
},
endpointKey{
Region: "ap-east-1",
}: endpoint{
Hostname: "resource-explorer-2.ap-east-1.api.aws",
},
endpointKey{
Region: "ap-northeast-1",
}: endpoint{
@ -24825,11 +24815,6 @@ var awsPartition = partition{
}: endpoint{
Hostname: "resource-explorer-2.ap-south-1.api.aws",
},
endpointKey{
Region: "ap-south-2",
}: endpoint{
Hostname: "resource-explorer-2.ap-south-2.api.aws",
},
endpointKey{
Region: "ap-southeast-1",
}: endpoint{
@ -24845,11 +24830,6 @@ var awsPartition = partition{
}: endpoint{
Hostname: "resource-explorer-2.ap-southeast-3.api.aws",
},
endpointKey{
Region: "ap-southeast-4",
}: endpoint{
Hostname: "resource-explorer-2.ap-southeast-4.api.aws",
},
endpointKey{
Region: "ca-central-1",
}: endpoint{
@ -24860,21 +24840,11 @@ var awsPartition = partition{
}: endpoint{
Hostname: "resource-explorer-2.eu-central-1.api.aws",
},
endpointKey{
Region: "eu-central-2",
}: endpoint{
Hostname: "resource-explorer-2.eu-central-2.api.aws",
},
endpointKey{
Region: "eu-north-1",
}: endpoint{
Hostname: "resource-explorer-2.eu-north-1.api.aws",
},
endpointKey{
Region: "eu-south-1",
}: endpoint{
Hostname: "resource-explorer-2.eu-south-1.api.aws",
},
endpointKey{
Region: "eu-west-1",
}: endpoint{
@ -24890,16 +24860,6 @@ var awsPartition = partition{
}: endpoint{
Hostname: "resource-explorer-2.eu-west-3.api.aws",
},
endpointKey{
Region: "il-central-1",
}: endpoint{
Hostname: "resource-explorer-2.il-central-1.api.aws",
},
endpointKey{
Region: "me-central-1",
}: endpoint{
Hostname: "resource-explorer-2.me-central-1.api.aws",
},
endpointKey{
Region: "me-south-1",
}: endpoint{
@ -35537,6 +35497,16 @@ var awscnPartition = partition{
}: endpoint{},
},
},
"inspector2": service{
Endpoints: serviceEndpoints{
endpointKey{
Region: "cn-north-1",
}: endpoint{},
endpointKey{
Region: "cn-northwest-1",
}: endpoint{},
},
},
"internetmonitor": service{
Defaults: endpointDefaults{
defaultKey{}: endpoint{

View File

@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK
const SDKVersion = "1.50.10"
const SDKVersion = "1.50.14"

View File

@ -17,7 +17,7 @@ and corresponding updates for existing programs.
## Parsing and Validation Options
Under the hood, a new `validator` struct takes care of validating the claims. A
Under the hood, a new `Validator` struct takes care of validating the claims. A
long awaited feature has been the option to fine-tune the validation of tokens.
This is now possible with several `ParserOption` functions that can be appended
to most `Parse` functions, such as `ParseWithClaims`. The most important options
@ -68,6 +68,16 @@ type Claims interface {
}
```
Users that previously directly called the `Valid` function on their claims,
e.g., to perform validation independently of parsing/verifying a token, can now
use the `jwt.NewValidator` function to create a `Validator` independently of the
`Parser`.
```go
var v = jwt.NewValidator(jwt.WithLeeway(5*time.Second))
v.Validate(myClaims)
```
### Supported Claim Types and Removal of `StandardClaims`
The two standard claim types supported by this library, `MapClaims` and
@ -169,7 +179,7 @@ be a drop-in replacement, if you're having troubles migrating, please open an
issue.
You can replace all occurrences of `github.com/dgrijalva/jwt-go` or
`github.com/golang-jwt/jwt` with `github.com/golang-jwt/jwt/v5`, either manually
`github.com/golang-jwt/jwt` with `github.com/golang-jwt/jwt/v4`, either manually
or by using tools such as `sed` or `gofmt`.
And then you'd typically run:

View File

@ -62,7 +62,7 @@ func (m *SigningMethodECDSA) Verify(signingString string, sig []byte, key interf
case *ecdsa.PublicKey:
ecdsaKey = k
default:
return ErrInvalidKeyType
return newError("ECDSA verify expects *ecsda.PublicKey", ErrInvalidKeyType)
}
if len(sig) != 2*m.KeySize {
@ -96,7 +96,7 @@ func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) ([]byte
case *ecdsa.PrivateKey:
ecdsaKey = k
default:
return nil, ErrInvalidKeyType
return nil, newError("ECDSA sign expects *ecsda.PrivateKey", ErrInvalidKeyType)
}
// Create the hasher

View File

@ -1,11 +1,10 @@
package jwt
import (
"errors"
"crypto"
"crypto/ed25519"
"crypto/rand"
"errors"
)
var (
@ -39,7 +38,7 @@ func (m *SigningMethodEd25519) Verify(signingString string, sig []byte, key inte
var ok bool
if ed25519Key, ok = key.(ed25519.PublicKey); !ok {
return ErrInvalidKeyType
return newError("Ed25519 verify expects ed25519.PublicKey", ErrInvalidKeyType)
}
if len(ed25519Key) != ed25519.PublicKeySize {
@ -61,7 +60,7 @@ func (m *SigningMethodEd25519) Sign(signingString string, key interface{}) ([]by
var ok bool
if ed25519Key, ok = key.(crypto.Signer); !ok {
return nil, ErrInvalidKeyType
return nil, newError("Ed25519 sign expects crypto.Signer", ErrInvalidKeyType)
}
if _, ok := ed25519Key.Public().(ed25519.PublicKey); !ok {

View File

@ -22,7 +22,7 @@ func (je joinedError) Is(err error) bool {
// wrappedErrors is a workaround for wrapping multiple errors in environments
// where Go 1.20 is not available. It basically uses the already implemented
// functionatlity of joinedError to handle multiple errors with supplies a
// functionality of joinedError to handle multiple errors with supplies a
// custom error message that is identical to the one we produce in Go 1.20 using
// multiple %w directives.
type wrappedErrors struct {

View File

@ -59,7 +59,7 @@ func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key interfa
// Verify the key is the right type
keyBytes, ok := key.([]byte)
if !ok {
return ErrInvalidKeyType
return newError("HMAC verify expects []byte", ErrInvalidKeyType)
}
// Can we use the specified hashing method?
@ -91,7 +91,7 @@ func (m *SigningMethodHMAC) Verify(signingString string, sig []byte, key interfa
func (m *SigningMethodHMAC) Sign(signingString string, key interface{}) ([]byte, error) {
if keyBytes, ok := key.([]byte); ok {
if !m.Hash.Available() {
return nil, ErrHashUnavailable
return nil, newError("HMAC sign expects []byte", ErrInvalidKeyType)
}
hasher := hmac.New(m.Hash.New, keyBytes)

View File

@ -32,7 +32,7 @@ func (m *signingMethodNone) Verify(signingString string, sig []byte, key interfa
return NoneSignatureTypeDisallowedError
}
// If signing method is none, signature must be an empty string
if string(sig) != "" {
if len(sig) != 0 {
return newError("'none' signing method with non-empty signature", ErrTokenUnverifiable)
}

View File

@ -18,7 +18,7 @@ type Parser struct {
// Skip claims validation during token parsing.
skipClaimsValidation bool
validator *validator
validator *Validator
decodeStrict bool
@ -28,7 +28,7 @@ type Parser struct {
// NewParser creates a new Parser with the specified options
func NewParser(options ...ParserOption) *Parser {
p := &Parser{
validator: &validator{},
validator: &Validator{},
}
// Loop through our parsing options and apply them
@ -74,24 +74,40 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
}
}
// Lookup key
var key interface{}
if keyFunc == nil {
// keyFunc was not provided. short circuiting validation
return token, newError("no keyfunc was provided", ErrTokenUnverifiable)
}
if key, err = keyFunc(token); err != nil {
return token, newError("error while executing keyfunc", ErrTokenUnverifiable, err)
}
// Decode signature
token.Signature, err = p.DecodeSegment(parts[2])
if err != nil {
return token, newError("could not base64 decode signature", ErrTokenMalformed, err)
}
text := strings.Join(parts[0:2], ".")
// Perform signature validation
if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil {
// Lookup key(s)
if keyFunc == nil {
// keyFunc was not provided. short circuiting validation
return token, newError("no keyfunc was provided", ErrTokenUnverifiable)
}
got, err := keyFunc(token)
if err != nil {
return token, newError("error while executing keyfunc", ErrTokenUnverifiable, err)
}
switch have := got.(type) {
case VerificationKeySet:
if len(have.Keys) == 0 {
return token, newError("keyfunc returned empty verification key set", ErrTokenUnverifiable)
}
// Iterate through keys and verify signature, skipping the rest when a match is found.
// Return the last error if no match is found.
for _, key := range have.Keys {
if err = token.Method.Verify(text, token.Signature, key); err == nil {
break
}
}
default:
err = token.Method.Verify(text, token.Signature, have)
}
if err != nil {
return token, newError("", ErrTokenSignatureInvalid, err)
}
@ -99,7 +115,7 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
if !p.skipClaimsValidation {
// Make sure we have at least a default validator
if p.validator == nil {
p.validator = newValidator()
p.validator = NewValidator()
}
if err := p.validator.Validate(claims); err != nil {
@ -117,8 +133,8 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
//
// WARNING: Don't use this method unless you know what you're doing.
//
// It's only ever useful in cases where you know the signature is valid (because it has
// been checked previously in the stack) and you want to extract values from it.
// It's only ever useful in cases where you know the signature is valid (since it has already
// been or will be checked elsewhere in the stack) and you want to extract values from it.
func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) {
parts = strings.Split(tokenString, ".")
if len(parts) != 3 {
@ -130,9 +146,6 @@ func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Toke
// parse Header
var headerBytes []byte
if headerBytes, err = p.DecodeSegment(parts[0]); err != nil {
if strings.HasPrefix(strings.ToLower(tokenString), "bearer ") {
return token, parts, newError("tokenstring should not contain 'bearer '", ErrTokenMalformed)
}
return token, parts, newError("could not base64 decode header", ErrTokenMalformed, err)
}
if err = json.Unmarshal(headerBytes, &token.Header); err != nil {
@ -140,23 +153,33 @@ func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Toke
}
// parse Claims
var claimBytes []byte
token.Claims = claims
if claimBytes, err = p.DecodeSegment(parts[1]); err != nil {
claimBytes, err := p.DecodeSegment(parts[1])
if err != nil {
return token, parts, newError("could not base64 decode claim", ErrTokenMalformed, err)
}
dec := json.NewDecoder(bytes.NewBuffer(claimBytes))
if p.useJSONNumber {
dec.UseNumber()
}
// JSON Decode. Special case for map type to avoid weird pointer behavior
if c, ok := token.Claims.(MapClaims); ok {
err = dec.Decode(&c)
// If `useJSONNumber` is enabled then we must use *json.Decoder to decode
// the claims. However, this comes with a performance penalty so only use
// it if we must and, otherwise, simple use json.Unmarshal.
if !p.useJSONNumber {
// JSON Unmarshal. Special case for map type to avoid weird pointer behavior.
if c, ok := token.Claims.(MapClaims); ok {
err = json.Unmarshal(claimBytes, &c)
} else {
err = json.Unmarshal(claimBytes, &claims)
}
} else {
err = dec.Decode(&claims)
dec := json.NewDecoder(bytes.NewBuffer(claimBytes))
dec.UseNumber()
// JSON Decode. Special case for map type to avoid weird pointer behavior.
if c, ok := token.Claims.(MapClaims); ok {
err = dec.Decode(&c)
} else {
err = dec.Decode(&claims)
}
}
// Handle decode error
if err != nil {
return token, parts, newError("could not JSON decode claim", ErrTokenMalformed, err)
}

View File

@ -58,6 +58,14 @@ func WithIssuedAt() ParserOption {
}
}
// WithExpirationRequired returns the ParserOption to make exp claim required.
// By default exp claim is optional.
func WithExpirationRequired() ParserOption {
return func(p *Parser) {
p.validator.requireExp = true
}
}
// WithAudience configures the validator to require the specified audience in
// the `aud` claim. Validation will fail if the audience is not listed in the
// token or the `aud` claim is missing.

View File

@ -51,7 +51,7 @@ func (m *SigningMethodRSA) Verify(signingString string, sig []byte, key interfac
var ok bool
if rsaKey, ok = key.(*rsa.PublicKey); !ok {
return ErrInvalidKeyType
return newError("RSA verify expects *rsa.PublicKey", ErrInvalidKeyType)
}
// Create hasher
@ -73,7 +73,7 @@ func (m *SigningMethodRSA) Sign(signingString string, key interface{}) ([]byte,
// Validate type of key
if rsaKey, ok = key.(*rsa.PrivateKey); !ok {
return nil, ErrInvalidKey
return nil, newError("RSA sign expects *rsa.PrivateKey", ErrInvalidKeyType)
}
// Create the hasher

View File

@ -88,7 +88,7 @@ func (m *SigningMethodRSAPSS) Verify(signingString string, sig []byte, key inter
case *rsa.PublicKey:
rsaKey = k
default:
return ErrInvalidKey
return newError("RSA-PSS verify expects *rsa.PublicKey", ErrInvalidKeyType)
}
// Create hasher
@ -115,7 +115,7 @@ func (m *SigningMethodRSAPSS) Sign(signingString string, key interface{}) ([]byt
case *rsa.PrivateKey:
rsaKey = k
default:
return nil, ErrInvalidKeyType
return nil, newError("RSA-PSS sign expects *rsa.PrivateKey", ErrInvalidKeyType)
}
// Create the hasher

View File

@ -1,6 +1,7 @@
package jwt
import (
"crypto"
"encoding/base64"
"encoding/json"
)
@ -9,8 +10,21 @@ import (
// the key for verification. The function receives the parsed, but unverified
// Token. This allows you to use properties in the Header of the token (such as
// `kid`) to identify which key to use.
//
// The returned interface{} may be a single key or a VerificationKeySet containing
// multiple keys.
type Keyfunc func(*Token) (interface{}, error)
// VerificationKey represents a public or secret key for verifying a token's signature.
type VerificationKey interface {
crypto.PublicKey | []uint8
}
// VerificationKeySet is a set of public or secret keys. It is used by the parser to verify a token.
type VerificationKeySet struct {
Keys []VerificationKey
}
// Token represents a JWT Token. Different fields will be used depending on
// whether you're creating or parsing/verifying a token.
type Token struct {

View File

@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"
"math"
"reflect"
"strconv"
"time"
)
@ -121,14 +120,14 @@ func (s *ClaimStrings) UnmarshalJSON(data []byte) (err error) {
for _, vv := range v {
vs, ok := vv.(string)
if !ok {
return &json.UnsupportedTypeError{Type: reflect.TypeOf(vv)}
return ErrInvalidType
}
aud = append(aud, vs)
}
case nil:
return nil
default:
return &json.UnsupportedTypeError{Type: reflect.TypeOf(v)}
return ErrInvalidType
}
*s = aud

View File

@ -28,13 +28,12 @@ type ClaimsValidator interface {
Validate() error
}
// validator is the core of the new Validation API. It is automatically used by
// Validator is the core of the new Validation API. It is automatically used by
// a [Parser] during parsing and can be modified with various parser options.
//
// Note: This struct is intentionally not exported (yet) as we want to
// internally finalize its API. In the future, we might make it publicly
// available.
type validator struct {
// The [NewValidator] function should be used to create an instance of this
// struct.
type Validator struct {
// leeway is an optional leeway that can be provided to account for clock skew.
leeway time.Duration
@ -42,6 +41,9 @@ type validator struct {
// validation. If unspecified, this defaults to time.Now.
timeFunc func() time.Time
// requireExp specifies whether the exp claim is required
requireExp bool
// verifyIat specifies whether the iat (Issued At) claim will be verified.
// According to https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6 this
// only specifies the age of the token, but no validation check is
@ -62,16 +64,28 @@ type validator struct {
expectedSub string
}
// newValidator can be used to create a stand-alone validator with the supplied
// NewValidator can be used to create a stand-alone validator with the supplied
// options. This validator can then be used to validate already parsed claims.
func newValidator(opts ...ParserOption) *validator {
//
// Note: Under normal circumstances, explicitly creating a validator is not
// needed and can potentially be dangerous; instead functions of the [Parser]
// class should be used.
//
// The [Validator] is only checking the *validity* of the claims, such as its
// expiration time, but it does NOT perform *signature verification* of the
// token.
func NewValidator(opts ...ParserOption) *Validator {
p := NewParser(opts...)
return p.validator
}
// Validate validates the given claims. It will also perform any custom
// validation if claims implements the [ClaimsValidator] interface.
func (v *validator) Validate(claims Claims) error {
//
// Note: It will NOT perform any *signature verification* on the token that
// contains the claims and expects that the [Claim] was already successfully
// verified.
func (v *Validator) Validate(claims Claims) error {
var (
now time.Time
errs []error = make([]error, 0, 6)
@ -86,8 +100,9 @@ func (v *validator) Validate(claims Claims) error {
}
// We always need to check the expiration time, but usage of the claim
// itself is OPTIONAL.
if err = v.verifyExpiresAt(claims, now, false); err != nil {
// itself is OPTIONAL by default. requireExp overrides this behavior
// and makes the exp claim mandatory.
if err = v.verifyExpiresAt(claims, now, v.requireExp); err != nil {
errs = append(errs, err)
}
@ -149,7 +164,7 @@ func (v *validator) Validate(claims Claims) error {
//
// Additionally, if any error occurs while retrieving the claim, e.g., when its
// the wrong type, an ErrTokenUnverifiable error will be returned.
func (v *validator) verifyExpiresAt(claims Claims, cmp time.Time, required bool) error {
func (v *Validator) verifyExpiresAt(claims Claims, cmp time.Time, required bool) error {
exp, err := claims.GetExpirationTime()
if err != nil {
return err
@ -170,7 +185,7 @@ func (v *validator) verifyExpiresAt(claims Claims, cmp time.Time, required bool)
//
// Additionally, if any error occurs while retrieving the claim, e.g., when its
// the wrong type, an ErrTokenUnverifiable error will be returned.
func (v *validator) verifyIssuedAt(claims Claims, cmp time.Time, required bool) error {
func (v *Validator) verifyIssuedAt(claims Claims, cmp time.Time, required bool) error {
iat, err := claims.GetIssuedAt()
if err != nil {
return err
@ -191,7 +206,7 @@ func (v *validator) verifyIssuedAt(claims Claims, cmp time.Time, required bool)
//
// Additionally, if any error occurs while retrieving the claim, e.g., when its
// the wrong type, an ErrTokenUnverifiable error will be returned.
func (v *validator) verifyNotBefore(claims Claims, cmp time.Time, required bool) error {
func (v *Validator) verifyNotBefore(claims Claims, cmp time.Time, required bool) error {
nbf, err := claims.GetNotBefore()
if err != nil {
return err
@ -211,7 +226,7 @@ func (v *validator) verifyNotBefore(claims Claims, cmp time.Time, required bool)
//
// Additionally, if any error occurs while retrieving the claim, e.g., when its
// the wrong type, an ErrTokenUnverifiable error will be returned.
func (v *validator) verifyAudience(claims Claims, cmp string, required bool) error {
func (v *Validator) verifyAudience(claims Claims, cmp string, required bool) error {
aud, err := claims.GetAudience()
if err != nil {
return err
@ -247,7 +262,7 @@ func (v *validator) verifyAudience(claims Claims, cmp string, required bool) err
//
// Additionally, if any error occurs while retrieving the claim, e.g., when its
// the wrong type, an ErrTokenUnverifiable error will be returned.
func (v *validator) verifyIssuer(claims Claims, cmp string, required bool) error {
func (v *Validator) verifyIssuer(claims Claims, cmp string, required bool) error {
iss, err := claims.GetIssuer()
if err != nil {
return err
@ -267,7 +282,7 @@ func (v *validator) verifyIssuer(claims Claims, cmp string, required bool) error
//
// Additionally, if any error occurs while retrieving the claim, e.g., when its
// the wrong type, an ErrTokenUnverifiable error will be returned.
func (v *validator) verifySubject(claims Claims, cmp string, required bool) error {
func (v *Validator) verifySubject(claims Claims, cmp string, required bool) error {
sub, err := claims.GetSubject()
if err != nil {
return err

View File

@ -559,24 +559,6 @@ type GetVolumeRequest struct {
VolumeID string `json:"-"`
}
// ImportSnapshotFromS3Request: import snapshot from s3 request.
type ImportSnapshotFromS3Request struct {
// Zone: zone to target. If none is passed will use default zone from the config.
Zone scw.Zone `json:"-"`
Bucket string `json:"bucket"`
Key string `json:"key"`
Name string `json:"name"`
ProjectID string `json:"project_id"`
Tags []string `json:"tags"`
Size *scw.Size `json:"size,omitempty"`
}
// ListSnapshotsRequest: list snapshots request.
type ListSnapshotsRequest struct {
// Zone: zone to target. If none is passed will use default zone from the config.
@ -1147,43 +1129,6 @@ func (s *API) CreateSnapshot(req *CreateSnapshotRequest, opts ...scw.RequestOpti
return &resp, nil
}
// ImportSnapshotFromS3:
func (s *API) ImportSnapshotFromS3(req *ImportSnapshotFromS3Request, opts ...scw.RequestOption) (*Snapshot, error) {
var err error
if req.Zone == "" {
defaultZone, _ := s.client.GetDefaultZone()
req.Zone = defaultZone
}
if req.ProjectID == "" {
defaultProjectID, _ := s.client.GetDefaultProjectID()
req.ProjectID = defaultProjectID
}
if fmt.Sprint(req.Zone) == "" {
return nil, errors.New("field Zone cannot be empty in request")
}
scwReq := &scw.ScalewayRequest{
Method: "POST",
Path: "/block/v1alpha1/zones/" + fmt.Sprint(req.Zone) + "/snapshots/import-from-s3",
}
err = scwReq.SetBody(req)
if err != nil {
return nil, err
}
var resp Snapshot
err = s.client.Do(scwReq, &resp, opts...)
if err != nil {
return nil, err
}
return &resp, nil
}
// DeleteSnapshot: You must specify the `snapshot_id` of the snapshot you want to delete. The snapshot must not be in use.
func (s *API) DeleteSnapshot(req *DeleteSnapshotRequest, opts ...scw.RequestOption) error {
var err error

View File

@ -226,6 +226,40 @@ func (enum *ContactLegalForm) UnmarshalJSON(data []byte) error {
return nil
}
type ContactStatus string
const (
// If unspecified, the status is unknown by default.
ContactStatusStatusUnknown = ContactStatus("status_unknown")
// The contact is active and can be edited.
ContactStatusActive = ContactStatus("active")
// The contact is temporarily locked (ie. while being edited).
ContactStatusPending = ContactStatus("pending")
)
func (enum ContactStatus) String() string {
if enum == "" {
// return default value if empty
return "status_unknown"
}
return string(enum)
}
func (enum ContactStatus) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf(`"%s"`, enum)), nil
}
func (enum *ContactStatus) UnmarshalJSON(data []byte) error {
tmp := ""
if err := json.Unmarshal(data, &tmp); err != nil {
return err
}
*enum = ContactStatus(ContactStatus(tmp).String())
return nil
}
type DNSZoneStatus string
const (
@ -1428,6 +1462,9 @@ type Contact struct {
State string `json:"state"`
ExtensionNl *ContactExtensionNL `json:"extension_nl"`
// Status: default value: status_unknown
Status ContactStatus `json:"status"`
}
// ContactRolesRoles: contact roles roles.
@ -1705,25 +1742,37 @@ type SSLCertificate struct {
// Task: task.
type Task struct {
// ID: the unique identifier of the task.
ID string `json:"id"`
// ProjectID: the project ID associated to the task.
ProjectID string `json:"project_id"`
// OrganizationID: the organization ID associated to the task.
OrganizationID string `json:"organization_id"`
// Domain: the domain name associated to the task.
Domain *string `json:"domain"`
// Type: default value: unknown
// Type: the type of the task.
// Default value: unknown
Type TaskType `json:"type"`
// Status: default value: unavailable
// Status: the status of the task.
// Default value: unavailable
Status TaskStatus `json:"status"`
// StartedAt: start date of the task.
StartedAt *time.Time `json:"started_at"`
// UpdatedAt: last update of the task.
UpdatedAt *time.Time `json:"updated_at"`
// Message: error message associated to the task.
Message *string `json:"message"`
// ContactIDentifier: human-friendly contact identifier used when the task concerns a contact.
ContactIDentifier *string `json:"contact_identifier"`
}
// TransferInDomainRequestTransferRequest: transfer in domain request transfer request.

View File

@ -1254,7 +1254,7 @@ type ListAPIKeysRequest struct {
// Expired: defines whether to filter out expired API keys or not.
Expired *bool `json:"-"`
// AccessKey: filter by access key.
// Deprecated: AccessKey: filter by access key (deprecated in favor of `access_keys`).
AccessKey *string `json:"-"`
// Description: filter by description.
@ -1266,6 +1266,9 @@ type ListAPIKeysRequest struct {
// BearerType: filter by type of bearer.
// Default value: unknown_bearer_type
BearerType BearerType `json:"-"`
// AccessKeys: filter by a list of access keys.
AccessKeys []string `json:"-"`
}
// ListAPIKeysResponse: list api keys response.
@ -1596,6 +1599,9 @@ type ListPoliciesRequest struct {
// Tag: filter by tags containing a given string.
Tag *string `json:"-"`
// PolicyIDs: filter by a list of IDs.
PolicyIDs []string `json:"-"`
}
// ListPoliciesResponse: list policies response.
@ -1938,6 +1944,15 @@ type UpdateSSHKeyRequest struct {
Disabled *bool `json:"disabled,omitempty"`
}
// UpdateUserRequest: update user request.
type UpdateUserRequest struct {
// UserID: ID of the user to update.
UserID string `json:"-"`
// Tags: new tags for the user (maximum of 10 tags).
Tags *[]string `json:"tags,omitempty"`
}
// IAM API.
type API struct {
client *scw.Client
@ -2139,6 +2154,33 @@ func (s *API) GetUser(req *GetUserRequest, opts ...scw.RequestOption) (*User, er
return &resp, nil
}
// UpdateUser: Update the parameters of a user, including `tags`.
func (s *API) UpdateUser(req *UpdateUserRequest, opts ...scw.RequestOption) (*User, error) {
var err error
if fmt.Sprint(req.UserID) == "" {
return nil, errors.New("field UserID cannot be empty in request")
}
scwReq := &scw.ScalewayRequest{
Method: "PATCH",
Path: "/iam/v1alpha1/users/" + fmt.Sprint(req.UserID) + "",
}
err = scwReq.SetBody(req)
if err != nil {
return nil, err
}
var resp User
err = s.client.Do(scwReq, &resp, opts...)
if err != nil {
return nil, err
}
return &resp, nil
}
// DeleteUser: Remove a user from an Organization in which they are a guest. You must define the `user_id` in your request. Note that removing a user from an Organization automatically deletes their API keys, and any policies directly attached to them become orphaned.
func (s *API) DeleteUser(req *DeleteUserRequest, opts ...scw.RequestOption) error {
var err error
@ -2602,6 +2644,7 @@ func (s *API) ListPolicies(req *ListPoliciesRequest, opts ...scw.RequestOption)
parameter.AddToQuery(query, "no_principal", req.NoPrincipal)
parameter.AddToQuery(query, "policy_name", req.PolicyName)
parameter.AddToQuery(query, "tag", req.Tag)
parameter.AddToQuery(query, "policy_ids", req.PolicyIDs)
scwReq := &scw.ScalewayRequest{
Method: "GET",
@ -2853,6 +2896,7 @@ func (s *API) ListAPIKeys(req *ListAPIKeysRequest, opts ...scw.RequestOption) (*
parameter.AddToQuery(query, "description", req.Description)
parameter.AddToQuery(query, "bearer_id", req.BearerID)
parameter.AddToQuery(query, "bearer_type", req.BearerType)
parameter.AddToQuery(query, "access_keys", req.AccessKeys)
parameter.AddToQuery(query, "application_id", req.ApplicationID)
parameter.AddToQuery(query, "user_id", req.UserID)

View File

@ -1186,7 +1186,11 @@ type ServerIP struct {
// Tags: tags associated with the IP.
Tags []string `json:"tags"`
// State: default value: unknown_state
// IpamID: the ip_id of an IPAM ip if the ip is created from IPAM, null if not.
IpamID string `json:"ipam_id"`
// State: IP address state.
// Default value: unknown_state
State ServerIPState `json:"state"`
}
@ -1218,6 +1222,8 @@ type ServerLocation struct {
// ServerMaintenance: server maintenance.
type ServerMaintenance struct {
Reason string `json:"reason"`
StartDate *time.Time `json:"start_date"`
}
// VolumeServer: volume server.
@ -1429,6 +1435,8 @@ type IP struct {
Prefix scw.IPNet `json:"prefix"`
IpamID string `json:"ipam_id"`
// Zone: zone to target. If none is passed will use default zone from the config.
Zone scw.Zone `json:"zone"`
}

View File

@ -131,7 +131,7 @@ type Resource struct {
type Reverse struct {
Hostname string `json:"hostname"`
Address *scw.IPNet `json:"address"`
Address *net.IP `json:"address"`
}
// IP: ip.

View File

@ -524,6 +524,37 @@ func (enum *ListFrontendsRequestOrderBy) UnmarshalJSON(data []byte) error {
return nil
}
type ListIPsRequestIPType string
const (
ListIPsRequestIPTypeAll = ListIPsRequestIPType("all")
ListIPsRequestIPTypeIPv4 = ListIPsRequestIPType("ipv4")
ListIPsRequestIPTypeIPv6 = ListIPsRequestIPType("ipv6")
)
func (enum ListIPsRequestIPType) String() string {
if enum == "" {
// return default value if empty
return "all"
}
return string(enum)
}
func (enum ListIPsRequestIPType) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf(`"%s"`, enum)), nil
}
func (enum *ListIPsRequestIPType) UnmarshalJSON(data []byte) error {
tmp := ""
if err := json.Unmarshal(data, &tmp); err != nil {
return err
}
*enum = ListIPsRequestIPType(ListIPsRequestIPType(tmp).String())
return nil
}
type ListLBsRequestOrderBy string
const (
@ -1843,6 +1874,9 @@ type CreateIPRequest struct {
// Reverse: reverse DNS (domain name) for the IP address.
Reverse *string `json:"reverse,omitempty"`
// IsIPv6: if true, creates a Flexible IP with an ipv6 address.
IsIPv6 bool `json:"is_ipv6"`
}
// CreateLBRequest: create lb request.
@ -1870,6 +1904,12 @@ type CreateLBRequest struct {
// AssignFlexibleIP: defines whether to automatically assign a flexible public IP to lb. Default value is `false` (do not assign).
AssignFlexibleIP *bool `json:"assign_flexible_ip,omitempty"`
// AssignFlexibleIPv6: defines whether to automatically assign a flexible public IPv6 to the Load Balancer. Default value is `false` (do not assign).
AssignFlexibleIPv6 *bool `json:"assign_flexible_ipv6,omitempty"`
// IPIDs: list of IP IDs to attach to the Load Balancer.
IPIDs []string `json:"ip_ids"`
// Tags: list of tags for the Load Balancer.
Tags []string `json:"tags"`
@ -2354,6 +2394,10 @@ type ListIPsRequest struct {
// ProjectID: project ID to filter for, only Load Balancer IP addresses from this Project will be returned.
ProjectID *string `json:"-"`
// IPType: IP type to filter for.
// Default value: all
IPType ListIPsRequestIPType `json:"-"`
}
// ListIPsResponse: list i ps response.
@ -3016,6 +3060,9 @@ type UpdateIPRequest struct {
// Reverse: reverse DNS (domain name) for the IP address.
Reverse *string `json:"reverse,omitempty"`
// LBID: ID of the server on which to attach the flexible IP.
LBID *string `json:"lb_id,omitempty"`
}
// UpdateLBRequest: update lb request.
@ -3341,6 +3388,9 @@ type ZonedAPICreateIPRequest struct {
// Reverse: reverse DNS (domain name) for the IP address.
Reverse *string `json:"reverse,omitempty"`
// IsIPv6: if true, creates a Flexible IP with an ipv6 address.
IsIPv6 bool `json:"is_ipv6"`
}
// ZonedAPICreateLBRequest: zoned api create lb request.
@ -3368,6 +3418,12 @@ type ZonedAPICreateLBRequest struct {
// AssignFlexibleIP: defines whether to automatically assign a flexible public IP to lb. Default value is `false` (do not assign).
AssignFlexibleIP *bool `json:"assign_flexible_ip,omitempty"`
// AssignFlexibleIPv6: defines whether to automatically assign a flexible public IPv6 to the Load Balancer. Default value is `false` (do not assign).
AssignFlexibleIPv6 *bool `json:"assign_flexible_ipv6,omitempty"`
// IPIDs: list of IP IDs to attach to the Load Balancer.
IPIDs []string `json:"ip_ids"`
// Tags: list of tags for the Load Balancer.
Tags []string `json:"tags"`
@ -3706,6 +3762,10 @@ type ZonedAPIListIPsRequest struct {
// ProjectID: project ID to filter for, only Load Balancer IP addresses from this Project will be returned.
ProjectID *string `json:"-"`
// IPType: IP type to filter for.
// Default value: all
IPType ListIPsRequestIPType `json:"-"`
}
// ZonedAPIListLBPrivateNetworksRequest: zoned api list lb private networks request.
@ -4184,6 +4244,9 @@ type ZonedAPIUpdateIPRequest struct {
// Reverse: reverse DNS (domain name) for the IP address.
Reverse *string `json:"reverse,omitempty"`
// LBID: ID of the server on which to attach the flexible IP.
LBID *string `json:"lb_id,omitempty"`
}
// ZonedAPIUpdateLBRequest: zoned api update lb request.
@ -4501,6 +4564,7 @@ func (s *ZonedAPI) ListIPs(req *ZonedAPIListIPsRequest, opts ...scw.RequestOptio
parameter.AddToQuery(query, "ip_address", req.IPAddress)
parameter.AddToQuery(query, "organization_id", req.OrganizationID)
parameter.AddToQuery(query, "project_id", req.ProjectID)
parameter.AddToQuery(query, "ip_type", req.IPType)
if fmt.Sprint(req.Zone) == "" {
return nil, errors.New("field Zone cannot be empty in request")
@ -6460,6 +6524,7 @@ func (s *API) ListIPs(req *ListIPsRequest, opts ...scw.RequestOption) (*ListIPsR
parameter.AddToQuery(query, "ip_address", req.IPAddress)
parameter.AddToQuery(query, "organization_id", req.OrganizationID)
parameter.AddToQuery(query, "project_id", req.ProjectID)
parameter.AddToQuery(query, "ip_type", req.IPType)
if fmt.Sprint(req.Region) == "" {
return nil, errors.New("field Region cannot be empty in request")

View File

@ -6,7 +6,6 @@ import (
"fmt"
"io"
"math"
"net"
"net/http"
"reflect"
"strconv"
@ -546,13 +545,8 @@ func newVariableFromType(t interface{}) interface{} {
func newHTTPClient() *http.Client {
return &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{
DialContext: (&net.Dialer{Timeout: 5 * time.Second}).DialContext,
TLSHandshakeTimeout: 5 * time.Second,
ResponseHeaderTimeout: 30 * time.Second,
MaxIdleConnsPerHost: 20,
},
Timeout: 30 * time.Second,
Transport: http.DefaultTransport.(*http.Transport).Clone(),
}
}

View File

@ -31,10 +31,24 @@ const (
// Server HTTP metrics.
const (
RequestCount = "http.server.request_count" // Incoming request count total
RequestContentLength = "http.server.request_content_length" // Incoming request bytes total
// Deprecated: This field is unused.
RequestCount = "http.server.request_count" // Incoming request count total
// Deprecated: Use of this field has been migrated to serverRequestSize. It will be removed in a future version.
RequestContentLength = "http.server.request_content_length" // Incoming request bytes total
// Deprecated: Use of this field has been migrated to serverResponseSize. It will be removed in a future version.
ResponseContentLength = "http.server.response_content_length" // Incoming response bytes total
ServerLatency = "http.server.duration" // Incoming end to end duration, milliseconds
// Deprecated: Use of this field has been migrated to serverDuration. It will be removed in a future version.
ServerLatency = "http.server.duration" // Incoming end to end duration, milliseconds
serverRequestSize = "http.server.request.size" // Incoming request bytes total
serverResponseSize = "http.server.response.size" // Incoming response bytes total
serverDuration = "http.server.duration" // Incoming end to end duration, milliseconds
)
// Client HTTP metrics.
const (
clientRequestSize = "http.client.request.size" // Outgoing request bytes total
clientResponseSize = "http.client.response.size" // Outgoing response bytes total
clientDuration = "http.client.duration" // Outgoing end to end duration, milliseconds
)
// Filter is a predicate used to determine whether a given http.request should

View File

@ -108,23 +108,23 @@ func handleErr(err error) {
func (h *middleware) createMeasures() {
var err error
h.requestBytesCounter, err = h.meter.Int64Counter(
RequestContentLength,
serverRequestSize,
metric.WithUnit("By"),
metric.WithDescription("Measures the size of HTTP request content length (uncompressed)"),
metric.WithDescription("Measures the size of HTTP request messages."),
)
handleErr(err)
h.responseBytesCounter, err = h.meter.Int64Counter(
ResponseContentLength,
serverResponseSize,
metric.WithUnit("By"),
metric.WithDescription("Measures the size of HTTP response content length (uncompressed)"),
metric.WithDescription("Measures the size of HTTP response messages."),
)
handleErr(err)
h.serverLatencyMeasure, err = h.meter.Float64Histogram(
ServerLatency,
serverDuration,
metric.WithUnit("ms"),
metric.WithDescription("Measures the duration of HTTP request handling"),
metric.WithDescription("Measures the duration of inbound HTTP requests."),
)
handleErr(err)
}

View File

@ -51,6 +51,14 @@ func HTTPClientRequest(req *http.Request) []attribute.KeyValue {
return hc.ClientRequest(req)
}
// HTTPClientRequestMetrics returns metric attributes for an HTTP request made by a client.
// The following attributes are always returned: "http.method", "net.peer.name".
// The following attributes are returned if the
// related values are defined in req: "net.peer.port".
func HTTPClientRequestMetrics(req *http.Request) []attribute.KeyValue {
return hc.ClientRequestMetrics(req)
}
// HTTPClientStatus returns a span status code and message for an HTTP status code
// value received by a client.
func HTTPClientStatus(code int) (codes.Code, string) {
@ -114,36 +122,6 @@ func HTTPServerStatus(code int) (codes.Code, string) {
return hc.ServerStatus(code)
}
// HTTPRequestHeader returns the contents of h as attributes.
//
// Instrumentation should require an explicit configuration of which headers to
// captured and then prune what they pass here. Including all headers can be a
// security risk - explicit configuration helps avoid leaking sensitive
// information.
//
// The User-Agent header is already captured in the http.user_agent attribute
// from ClientRequest and ServerRequest. Instrumentation may provide an option
// to capture that header here even though it is not recommended. Otherwise,
// instrumentation should filter that out of what is passed.
func HTTPRequestHeader(h http.Header) []attribute.KeyValue {
return hc.RequestHeader(h)
}
// HTTPResponseHeader returns the contents of h as attributes.
//
// Instrumentation should require an explicit configuration of which headers to
// captured and then prune what they pass here. Including all headers can be a
// security risk - explicit configuration helps avoid leaking sensitive
// information.
//
// The User-Agent header is already captured in the http.user_agent attribute
// from ClientRequest and ServerRequest. Instrumentation may provide an option
// to capture that header here even though it is not recommended. Otherwise,
// instrumentation should filter that out of what is passed.
func HTTPResponseHeader(h http.Header) []attribute.KeyValue {
return hc.ResponseHeader(h)
}
// httpConv are the HTTP semantic convention attributes defined for a version
// of the OpenTelemetry specification.
type httpConv struct {
@ -286,6 +264,38 @@ func (c *httpConv) ClientRequest(req *http.Request) []attribute.KeyValue {
return attrs
}
// ClientRequestMetrics returns metric attributes for an HTTP request made by a client. The
// following attributes are always returned: "http.method", "net.peer.name".
// The following attributes are returned if the related values
// are defined in req: "net.peer.port".
func (c *httpConv) ClientRequestMetrics(req *http.Request) []attribute.KeyValue {
/* The following semantic conventions are returned if present:
http.method string
net.peer.name string
net.peer.port int
*/
n := 2 // method, peer name.
var h string
if req.URL != nil {
h = req.URL.Host
}
peer, p := firstHostPort(h, req.Header.Get("Host"))
port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", p)
if port > 0 {
n++
}
attrs := make([]attribute.KeyValue, 0, n)
attrs = append(attrs, c.method(req.Method), c.NetConv.PeerName(peer))
if port > 0 {
attrs = append(attrs, c.NetConv.PeerPort(port))
}
return attrs
}
// ServerRequest returns attributes for an HTTP request received by a server.
//
// The server must be the primary server name if it is known. For example this
@ -551,31 +561,6 @@ func firstHostPort(source ...string) (host string, port int) {
return
}
// RequestHeader returns the contents of h as OpenTelemetry attributes.
func (c *httpConv) RequestHeader(h http.Header) []attribute.KeyValue {
return c.header("http.request.header", h)
}
// ResponseHeader returns the contents of h as OpenTelemetry attributes.
func (c *httpConv) ResponseHeader(h http.Header) []attribute.KeyValue {
return c.header("http.response.header", h)
}
func (c *httpConv) header(prefix string, h http.Header) []attribute.KeyValue {
key := func(k string) attribute.Key {
k = strings.ToLower(k)
k = strings.ReplaceAll(k, "-", "_")
k = fmt.Sprintf("%s.%s", prefix, k)
return attribute.Key(k)
}
attrs := make([]attribute.KeyValue, 0, len(h))
for k, v := range h {
attrs = append(attrs, key(k).StringSlice(v))
}
return attrs
}
// ClientStatus returns a span status code and message for an HTTP status code
// value received by a client.
func (c *httpConv) ClientStatus(code int) (codes.Code, string) {

View File

@ -32,24 +32,6 @@ func NetTransport(network string) attribute.KeyValue {
return nc.Transport(network)
}
// NetClient returns trace attributes for a client network connection to address.
// See net.Dial for information about acceptable address values, address should
// be the same as the one used to create conn. If conn is nil, only network
// peer attributes will be returned that describe address. Otherwise, the
// socket level information about conn will also be included.
func NetClient(address string, conn net.Conn) []attribute.KeyValue {
return nc.Client(address, conn)
}
// NetServer returns trace attributes for a network listener listening at address.
// See net.Listen for information about acceptable address values, address
// should be the same as the one used to create ln. If ln is nil, only network
// host attributes will be returned that describe address. Otherwise, the
// socket level information about ln will also be included.
func NetServer(address string, ln net.Listener) []attribute.KeyValue {
return nc.Server(address, ln)
}
// netConv are the network semantic convention attributes defined for a version
// of the OpenTelemetry specification.
type netConv struct {
@ -125,52 +107,6 @@ func (c *netConv) Host(address string) []attribute.KeyValue {
return attrs
}
// Server returns attributes for a network listener listening at address. See
// net.Listen for information about acceptable address values, address should
// be the same as the one used to create ln. If ln is nil, only network host
// attributes will be returned that describe address. Otherwise, the socket
// level information about ln will also be included.
func (c *netConv) Server(address string, ln net.Listener) []attribute.KeyValue {
if ln == nil {
return c.Host(address)
}
lAddr := ln.Addr()
if lAddr == nil {
return c.Host(address)
}
hostName, hostPort := splitHostPort(address)
sockHostAddr, sockHostPort := splitHostPort(lAddr.String())
network := lAddr.Network()
sockFamily := family(network, sockHostAddr)
n := nonZeroStr(hostName, network, sockHostAddr, sockFamily)
n += positiveInt(hostPort, sockHostPort)
attr := make([]attribute.KeyValue, 0, n)
if hostName != "" {
attr = append(attr, c.HostName(hostName))
if hostPort > 0 {
// Only if net.host.name is set should net.host.port be.
attr = append(attr, c.HostPort(hostPort))
}
}
if network != "" {
attr = append(attr, c.Transport(network))
}
if sockFamily != "" {
attr = append(attr, c.NetSockFamilyKey.String(sockFamily))
}
if sockHostAddr != "" {
attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr))
if sockHostPort > 0 {
// Only if net.sock.host.addr is set should net.sock.host.port be.
attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort))
}
}
return attr
}
func (c *netConv) HostName(name string) attribute.KeyValue {
return c.NetHostNameKey.String(name)
}
@ -179,85 +115,6 @@ func (c *netConv) HostPort(port int) attribute.KeyValue {
return c.NetHostPortKey.Int(port)
}
// Client returns attributes for a client network connection to address. See
// net.Dial for information about acceptable address values, address should be
// the same as the one used to create conn. If conn is nil, only network peer
// attributes will be returned that describe address. Otherwise, the socket
// level information about conn will also be included.
func (c *netConv) Client(address string, conn net.Conn) []attribute.KeyValue {
if conn == nil {
return c.Peer(address)
}
lAddr, rAddr := conn.LocalAddr(), conn.RemoteAddr()
var network string
switch {
case lAddr != nil:
network = lAddr.Network()
case rAddr != nil:
network = rAddr.Network()
default:
return c.Peer(address)
}
peerName, peerPort := splitHostPort(address)
var (
sockFamily string
sockPeerAddr string
sockPeerPort int
sockHostAddr string
sockHostPort int
)
if lAddr != nil {
sockHostAddr, sockHostPort = splitHostPort(lAddr.String())
}
if rAddr != nil {
sockPeerAddr, sockPeerPort = splitHostPort(rAddr.String())
}
switch {
case sockHostAddr != "":
sockFamily = family(network, sockHostAddr)
case sockPeerAddr != "":
sockFamily = family(network, sockPeerAddr)
}
n := nonZeroStr(peerName, network, sockPeerAddr, sockHostAddr, sockFamily)
n += positiveInt(peerPort, sockPeerPort, sockHostPort)
attr := make([]attribute.KeyValue, 0, n)
if peerName != "" {
attr = append(attr, c.PeerName(peerName))
if peerPort > 0 {
// Only if net.peer.name is set should net.peer.port be.
attr = append(attr, c.PeerPort(peerPort))
}
}
if network != "" {
attr = append(attr, c.Transport(network))
}
if sockFamily != "" {
attr = append(attr, c.NetSockFamilyKey.String(sockFamily))
}
if sockPeerAddr != "" {
attr = append(attr, c.NetSockPeerAddrKey.String(sockPeerAddr))
if sockPeerPort > 0 {
// Only if net.sock.peer.addr is set should net.sock.peer.port be.
attr = append(attr, c.NetSockPeerPortKey.Int(sockPeerPort))
}
}
if sockHostAddr != "" {
attr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr))
if sockHostPort > 0 {
// Only if net.sock.host.addr is set should net.sock.host.port be.
attr = append(attr, c.NetSockHostPortKey.Int(sockHostPort))
}
}
return attr
}
func family(network, address string) string {
switch network {
case "unix", "unixgram", "unixpacket":
@ -273,26 +130,6 @@ func family(network, address string) string {
return ""
}
func nonZeroStr(strs ...string) int {
var n int
for _, str := range strs {
if str != "" {
n++
}
}
return n
}
func positiveInt(ints ...int) int {
var n int
for _, i := range ints {
if i > 0 {
n++
}
}
return n
}
// Peer returns attributes for a network peer address.
func (c *netConv) Peer(address string) []attribute.KeyValue {
h, p := splitHostPort(address)

Some files were not shown because too many files have changed in this diff Show More