mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 10:53:34 +00:00
rebase: bump the github-dependencies group with 3 updates
Bumps the github-dependencies group with 3 updates: [github.com/Azure/azure-sdk-for-go/sdk/azidentity](https://github.com/Azure/azure-sdk-for-go), [github.com/aws/aws-sdk-go-v2/service/sts](https://github.com/aws/aws-sdk-go-v2) and [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang). Updates `github.com/Azure/azure-sdk-for-go/sdk/azidentity` from 1.8.2 to 1.9.0 - [Release notes](https://github.com/Azure/azure-sdk-for-go/releases) - [Changelog](https://github.com/Azure/azure-sdk-for-go/blob/main/documentation/release.md) - [Commits](https://github.com/Azure/azure-sdk-for-go/compare/sdk/azidentity/v1.8.2...sdk/azcore/v1.9.0) Updates `github.com/aws/aws-sdk-go-v2/service/sts` from 1.33.18 to 1.33.19 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Changelog](https://github.com/aws/aws-sdk-go-v2/blob/main/changelog-template.json) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/sns/v1.33.18...service/sns/v1.33.19) Updates `github.com/prometheus/client_golang` from 1.21.1 to 1.22.0 - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.21.1...v1.22.0) --- updated-dependencies: - dependency-name: github.com/Azure/azure-sdk-for-go/sdk/azidentity dependency-version: 1.9.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-dependencies - dependency-name: github.com/aws/aws-sdk-go-v2/service/sts dependency-version: 1.33.19 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-dependencies - dependency-name: github.com/prometheus/client_golang dependency-version: 1.22.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-dependencies ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
mergify[bot]
parent
0b811ff8b1
commit
72c19ab743
14
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/CHANGELOG.md
generated
vendored
@ -1,5 +1,19 @@
|
||||
# Release History
|
||||
|
||||
## 1.18.0 (2025-04-03)
|
||||
|
||||
### Features Added
|
||||
|
||||
* Added `AccessToken.RefreshOn` and updated `BearerTokenPolicy` to consider nonzero values of it when deciding whether to request a new token
|
||||
|
||||
|
||||
## 1.17.1 (2025-03-20)
|
||||
|
||||
### Other Changes
|
||||
|
||||
* Upgraded to Go 1.23
|
||||
* Upgraded dependencies
|
||||
|
||||
## 1.17.0 (2025-01-07)
|
||||
|
||||
### Features Added
|
||||
|
7
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/exported.go
generated
vendored
7
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/exported/exported.go
generated
vendored
@ -47,8 +47,13 @@ func HasStatusCode(resp *http.Response, statusCodes ...int) bool {
|
||||
// AccessToken represents an Azure service bearer access token with expiry information.
|
||||
// Exported as azcore.AccessToken.
|
||||
type AccessToken struct {
|
||||
Token string
|
||||
// Token is the access token
|
||||
Token string
|
||||
// ExpiresOn indicates when the token expires
|
||||
ExpiresOn time.Time
|
||||
// RefreshOn is a suggested time to refresh the token.
|
||||
// Clients should ignore this value when it's zero.
|
||||
RefreshOn time.Time
|
||||
}
|
||||
|
||||
// TokenRequestOptions contain specific parameter that may be used by credentials types when attempting to get a token.
|
||||
|
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go
generated
vendored
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/internal/shared/constants.go
generated
vendored
@ -40,5 +40,5 @@ const (
|
||||
Module = "azcore"
|
||||
|
||||
// Version is the semantic version (see http://semver.org) of this module.
|
||||
Version = "v1.17.0"
|
||||
Version = "v1.18.0"
|
||||
)
|
||||
|
14
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_bearer_token.go
generated
vendored
14
vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/policy_bearer_token.go
generated
vendored
@ -51,6 +51,15 @@ func acquire(state acquiringResourceState) (newResource exported.AccessToken, ne
|
||||
return tk, tk.ExpiresOn, nil
|
||||
}
|
||||
|
||||
// shouldRefresh determines whether the token should be refreshed. It's a variable so tests can replace it.
|
||||
var shouldRefresh = func(tk exported.AccessToken, _ acquiringResourceState) bool {
|
||||
if tk.RefreshOn.IsZero() {
|
||||
return tk.ExpiresOn.Add(-5 * time.Minute).Before(time.Now())
|
||||
}
|
||||
// no offset in this case because the authority suggested a refresh window--between RefreshOn and ExpiresOn
|
||||
return tk.RefreshOn.Before(time.Now())
|
||||
}
|
||||
|
||||
// NewBearerTokenPolicy creates a policy object that authorizes requests with bearer tokens.
|
||||
// cred: an azcore.TokenCredential implementation such as a credential object from azidentity
|
||||
// scopes: the list of permission scopes required for the token.
|
||||
@ -69,11 +78,14 @@ func NewBearerTokenPolicy(cred exported.TokenCredential, scopes []string, opts *
|
||||
return authNZ(policy.TokenRequestOptions{Scopes: scopes})
|
||||
}
|
||||
}
|
||||
mr := temporal.NewResourceWithOptions(acquire, temporal.ResourceOptions[exported.AccessToken, acquiringResourceState]{
|
||||
ShouldRefresh: shouldRefresh,
|
||||
})
|
||||
return &BearerTokenPolicy{
|
||||
authzHandler: ah,
|
||||
cred: cred,
|
||||
scopes: scopes,
|
||||
mainResource: temporal.NewResource(acquire),
|
||||
mainResource: mr,
|
||||
allowHTTP: opts.InsecureAllowCredentialWithHTTP,
|
||||
}
|
||||
}
|
||||
|
12
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md
generated
vendored
12
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/CHANGELOG.md
generated
vendored
@ -1,5 +1,17 @@
|
||||
# Release History
|
||||
|
||||
## 1.9.0 (2025-04-08)
|
||||
|
||||
### Features Added
|
||||
* `GetToken()` sets `AccessToken.RefreshOn` when the token provider specifies a value
|
||||
|
||||
### Other Changes
|
||||
* `NewManagedIdentityCredential` logs the configured user-assigned identity, if any
|
||||
* Deprecated `UsernamePasswordCredential` because it can't support multifactor
|
||||
authentication (MFA), which Microsoft Entra ID requires for most tenants. See
|
||||
https://aka.ms/azsdk/identity/mfa for migration guidance.
|
||||
* Updated dependencies
|
||||
|
||||
## 1.8.2 (2025-02-12)
|
||||
|
||||
### Other Changes
|
||||
|
18
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/README.md
generated
vendored
18
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/README.md
generated
vendored
@ -21,7 +21,7 @@ go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentity
|
||||
## Prerequisites
|
||||
|
||||
- an [Azure subscription](https://azure.microsoft.com/free/)
|
||||
- Go 1.18
|
||||
- [Supported](https://aka.ms/azsdk/go/supported-versions) version of Go
|
||||
|
||||
### Authenticating during local development
|
||||
|
||||
@ -146,7 +146,6 @@ client := armresources.NewResourceGroupsClient("subscription ID", chain, nil)
|
||||
|-|-
|
||||
|[InteractiveBrowserCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#InteractiveBrowserCredential)|Interactively authenticate a user with the default web browser
|
||||
|[DeviceCodeCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#DeviceCodeCredential)|Interactively authenticate a user on a device with limited UI
|
||||
|[UsernamePasswordCredential](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#UsernamePasswordCredential)|Authenticate a user with a username and password
|
||||
|
||||
### Authenticating via Development Tools
|
||||
|
||||
@ -159,7 +158,7 @@ client := armresources.NewResourceGroupsClient("subscription ID", chain, nil)
|
||||
|
||||
`DefaultAzureCredential` and `EnvironmentCredential` can be configured with environment variables. Each type of authentication requires values for specific variables:
|
||||
|
||||
#### Service principal with secret
|
||||
### Service principal with secret
|
||||
|
||||
|variable name|value
|
||||
|-|-
|
||||
@ -167,7 +166,7 @@ client := armresources.NewResourceGroupsClient("subscription ID", chain, nil)
|
||||
|`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
|
||||
### Service principal with certificate
|
||||
|
||||
|variable name|value
|
||||
|-|-
|
||||
@ -176,16 +175,7 @@ client := armresources.NewResourceGroupsClient("subscription ID", chain, nil)
|
||||
|`AZURE_CLIENT_CERTIFICATE_PATH`|path to a certificate file including private key
|
||||
|`AZURE_CLIENT_CERTIFICATE_PASSWORD`|password of the certificate file, if any
|
||||
|
||||
#### Username and password
|
||||
|
||||
|variable name|value
|
||||
|-|-
|
||||
|`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.
|
||||
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
|
||||
|
||||
|
11
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TOKEN_CACHING.MD
generated
vendored
11
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/TOKEN_CACHING.MD
generated
vendored
@ -22,12 +22,11 @@ Some credential types support opt-in persistent token caching (see [the below ta
|
||||
|
||||
Persistent caches are encrypted at rest using a mechanism that depends on the operating system:
|
||||
|
||||
| Operating system | Encryption facility |
|
||||
| ---------------- | ---------------------------------------------- |
|
||||
| Linux | kernel key retention service (keyctl) |
|
||||
| macOS | Keychain (requires cgo and native build tools) |
|
||||
| Windows | Data Protection API (DPAPI) |
|
||||
|
||||
| Operating system | Encryption facility | Limitations |
|
||||
| ---------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Linux | kernel key retention service (keyctl) | Cache data is lost on system shutdown because kernel keys are stored in memory. Depending on kernel compile options, data may also be lost on logout, or storage may be impossible because the key retention service isn't available. |
|
||||
| macOS | Keychain | Building requires cgo and native build tools. Keychain access requires a graphical session, so persistent caching isn't possible in a headless environment such as an SSH session (macOS as host). |
|
||||
| Windows | Data Protection API (DPAPI) | No specific limitations. |
|
||||
Persistent caching requires encryption. When the required encryption facility is unuseable, or the application is running on an unsupported OS, the persistent cache constructor returns an error. This doesn't mean that authentication is impossible, only that credentials can't persist authentication data and the application will need to reauthenticate the next time it runs. See the package documentation for examples showing how to configure persistent caching and access cached data for [users][user_example] and [service principals][sp_example].
|
||||
|
||||
### Credentials supporting token caching
|
||||
|
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/assets.json
generated
vendored
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/assets.json
generated
vendored
@ -2,5 +2,5 @@
|
||||
"AssetsRepo": "Azure/azure-sdk-assets",
|
||||
"AssetsRepoPrefixPath": "go",
|
||||
"TagPrefix": "go/azidentity",
|
||||
"Tag": "go/azidentity_c55452bbf6"
|
||||
"Tag": "go/azidentity_191110b0dd"
|
||||
}
|
||||
|
5
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azidentity.go
generated
vendored
5
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/azidentity.go
generated
vendored
@ -22,6 +22,7 @@ import (
|
||||
"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/managedidentity"
|
||||
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/public"
|
||||
)
|
||||
|
||||
@ -208,6 +209,10 @@ type msalConfidentialClient interface {
|
||||
AcquireTokenOnBehalfOf(ctx context.Context, userAssertion string, scopes []string, options ...confidential.AcquireOnBehalfOfOption) (confidential.AuthResult, error)
|
||||
}
|
||||
|
||||
type msalManagedIdentityClient interface {
|
||||
AcquireToken(context.Context, string, ...managedidentity.AcquireTokenOption) (managedidentity.AuthResult, error)
|
||||
}
|
||||
|
||||
// enables fakes for test scenarios
|
||||
type msalPublicClient interface {
|
||||
AcquireTokenSilent(ctx context.Context, scopes []string, options ...public.AcquireSilentOption) (public.AuthResult, error)
|
||||
|
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/confidential_client.go
generated
vendored
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/confidential_client.go
generated
vendored
@ -118,7 +118,7 @@ func (c *confidentialClient) GetToken(ctx context.Context, tro policy.TokenReque
|
||||
msg := fmt.Sprintf(scopeLogFmt, c.name, strings.Join(ar.GrantedScopes, ", "))
|
||||
log.Write(EventAuthentication, msg)
|
||||
}
|
||||
return azcore.AccessToken{Token: ar.AccessToken, ExpiresOn: ar.ExpiresOn.UTC()}, err
|
||||
return azcore.AccessToken{Token: ar.AccessToken, ExpiresOn: ar.ExpiresOn.UTC(), RefreshOn: ar.Metadata.RefreshOn.UTC()}, err
|
||||
}
|
||||
|
||||
func (c *confidentialClient) client(tro policy.TokenRequestOptions) (msalConfidentialClient, *sync.Mutex, error) {
|
||||
|
7
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/environment_credential.go
generated
vendored
7
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/environment_credential.go
generated
vendored
@ -60,7 +60,10 @@ type EnvironmentCredentialOptions struct {
|
||||
// Note that this credential uses [ParseCertificates] to load the certificate and key from the file. If this
|
||||
// function isn't able to parse your certificate, use [ClientCertificateCredential] instead.
|
||||
//
|
||||
// # User with username and password
|
||||
// # Deprecated: User with username and password
|
||||
//
|
||||
// User password authentication is deprecated because it can't support multifactor authentication. See
|
||||
// [Entra ID documentation] for migration guidance.
|
||||
//
|
||||
// AZURE_TENANT_ID: (optional) tenant to authenticate in. Defaults to "organizations".
|
||||
//
|
||||
@ -75,6 +78,8 @@ type EnvironmentCredentialOptions struct {
|
||||
// To enable multitenant authentication, set AZURE_ADDITIONALLY_ALLOWED_TENANTS with a semicolon delimited list of tenants
|
||||
// the credential may request tokens from in addition to the tenant specified by AZURE_TENANT_ID. Set
|
||||
// AZURE_ADDITIONALLY_ALLOWED_TENANTS to "*" to enable the credential to request a token from any tenant.
|
||||
//
|
||||
// [Entra ID documentation]: https://aka.ms/azsdk/identity/mfa
|
||||
type EnvironmentCredential struct {
|
||||
cred azcore.TokenCredential
|
||||
}
|
||||
|
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/go.work
generated
vendored
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/go.work
generated
vendored
@ -1,4 +1,4 @@
|
||||
go 1.18
|
||||
go 1.23.0
|
||||
|
||||
use (
|
||||
.
|
||||
|
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed-identity-matrix.json
generated
vendored
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed-identity-matrix.json
generated
vendored
@ -9,7 +9,7 @@
|
||||
}
|
||||
},
|
||||
"GoVersion": [
|
||||
"1.22.1"
|
||||
"env:GO_VERSION_PREVIOUS"
|
||||
],
|
||||
"IDENTITY_IMDS_AVAILABLE": "1"
|
||||
}
|
||||
|
431
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_client.go
generated
vendored
431
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_client.go
generated
vendored
@ -8,24 +8,18 @@ package azidentity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
azruntime "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/internal/log"
|
||||
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/confidential"
|
||||
msalerrors "github.com/AzureAD/microsoft-authentication-library-for-go/apps/errors"
|
||||
"github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -41,59 +35,20 @@ const (
|
||||
msiResID = "msi_res_id"
|
||||
msiSecret = "MSI_SECRET"
|
||||
imdsAPIVersion = "2018-02-01"
|
||||
azureArcAPIVersion = "2019-08-15"
|
||||
azureArcAPIVersion = "2020-06-01"
|
||||
qpClientID = "client_id"
|
||||
serviceFabricAPIVersion = "2019-07-01-preview"
|
||||
)
|
||||
|
||||
var imdsProbeTimeout = time.Second
|
||||
|
||||
type msiType int
|
||||
|
||||
const (
|
||||
msiTypeAppService msiType = iota
|
||||
msiTypeAzureArc
|
||||
msiTypeAzureML
|
||||
msiTypeCloudShell
|
||||
msiTypeIMDS
|
||||
msiTypeServiceFabric
|
||||
)
|
||||
|
||||
type managedIdentityClient struct {
|
||||
azClient *azcore.Client
|
||||
endpoint string
|
||||
id ManagedIDKind
|
||||
msiType msiType
|
||||
probeIMDS bool
|
||||
azClient *azcore.Client
|
||||
imds, probeIMDS, userAssigned bool
|
||||
// chained indicates whether the client is part of a credential chain. If true, the client will return
|
||||
// a credentialUnavailableError instead of an AuthenticationFailedError for an unexpected IMDS response.
|
||||
chained bool
|
||||
}
|
||||
|
||||
// arcKeyDirectory returns the directory expected to contain Azure Arc keys
|
||||
var arcKeyDirectory = func() (string, error) {
|
||||
switch runtime.GOOS {
|
||||
case "linux":
|
||||
return "/var/opt/azcmagent/tokens", nil
|
||||
case "windows":
|
||||
pd := os.Getenv("ProgramData")
|
||||
if pd == "" {
|
||||
return "", errors.New("environment variable ProgramData has no value")
|
||||
}
|
||||
return filepath.Join(pd, "AzureConnectedMachineAgent", "Tokens"), nil
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported OS %q", runtime.GOOS)
|
||||
}
|
||||
}
|
||||
|
||||
type wrappedNumber json.Number
|
||||
|
||||
func (n *wrappedNumber) UnmarshalJSON(b []byte) error {
|
||||
c := string(b)
|
||||
if c == "\"\"" {
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(b, (*json.Number)(n))
|
||||
chained bool
|
||||
msalClient msalManagedIdentityClient
|
||||
}
|
||||
|
||||
// setIMDSRetryOptionDefaults sets zero-valued fields to default values appropriate for IMDS
|
||||
@ -141,51 +96,20 @@ func newManagedIdentityClient(options *ManagedIdentityCredentialOptions) (*manag
|
||||
options = &ManagedIdentityCredentialOptions{}
|
||||
}
|
||||
cp := options.ClientOptions
|
||||
c := managedIdentityClient{id: options.ID, endpoint: imdsEndpoint, msiType: msiTypeIMDS}
|
||||
env := "IMDS"
|
||||
if endpoint, ok := os.LookupEnv(identityEndpoint); ok {
|
||||
if _, ok := os.LookupEnv(identityHeader); ok {
|
||||
if _, ok := os.LookupEnv(identityServerThumbprint); ok {
|
||||
if options.ID != nil {
|
||||
return nil, errors.New("the Service Fabric API doesn't support specifying a user-assigned identity at runtime. The identity is determined by cluster resource configuration. See https://aka.ms/servicefabricmi")
|
||||
}
|
||||
env = "Service Fabric"
|
||||
c.endpoint = endpoint
|
||||
c.msiType = msiTypeServiceFabric
|
||||
} else {
|
||||
env = "App Service"
|
||||
c.endpoint = endpoint
|
||||
c.msiType = msiTypeAppService
|
||||
}
|
||||
} else if _, ok := os.LookupEnv(arcIMDSEndpoint); ok {
|
||||
if options.ID != nil {
|
||||
return nil, errors.New("the Azure Arc API doesn't support specifying a user-assigned managed identity at runtime")
|
||||
}
|
||||
env = "Azure Arc"
|
||||
c.endpoint = endpoint
|
||||
c.msiType = msiTypeAzureArc
|
||||
}
|
||||
} else if endpoint, ok := os.LookupEnv(msiEndpoint); ok {
|
||||
c.endpoint = endpoint
|
||||
if _, ok := os.LookupEnv(msiSecret); ok {
|
||||
if options.ID != nil && options.ID.idKind() != miClientID {
|
||||
return nil, errors.New("the Azure ML API supports specifying a user-assigned managed identity by client ID only")
|
||||
}
|
||||
env = "Azure ML"
|
||||
c.msiType = msiTypeAzureML
|
||||
} else {
|
||||
if options.ID != nil {
|
||||
return nil, errors.New("the Cloud Shell API doesn't support user-assigned managed identities")
|
||||
}
|
||||
env = "Cloud Shell"
|
||||
c.msiType = msiTypeCloudShell
|
||||
}
|
||||
} else {
|
||||
c := managedIdentityClient{}
|
||||
source, err := managedidentity.GetSource()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
env := string(source)
|
||||
if source == managedidentity.DefaultToIMDS {
|
||||
env = "IMDS"
|
||||
c.imds = true
|
||||
c.probeIMDS = options.dac
|
||||
setIMDSRetryOptionDefaults(&cp.Retry)
|
||||
}
|
||||
|
||||
client, err := azcore.NewClient(module, version, azruntime.PipelineOptions{
|
||||
c.azClient, err = azcore.NewClient(module, version, azruntime.PipelineOptions{
|
||||
Tracing: azruntime.TracingOptions{
|
||||
Namespace: traceNamespace,
|
||||
},
|
||||
@ -193,28 +117,53 @@ func newManagedIdentityClient(options *ManagedIdentityCredentialOptions) (*manag
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.azClient = client
|
||||
|
||||
id := managedidentity.SystemAssigned()
|
||||
if options.ID != nil {
|
||||
c.userAssigned = true
|
||||
switch s := options.ID.String(); options.ID.idKind() {
|
||||
case miClientID:
|
||||
id = managedidentity.UserAssignedClientID(s)
|
||||
case miObjectID:
|
||||
id = managedidentity.UserAssignedObjectID(s)
|
||||
case miResourceID:
|
||||
id = managedidentity.UserAssignedResourceID(s)
|
||||
}
|
||||
}
|
||||
msalClient, err := managedidentity.New(id, managedidentity.WithHTTPClient(&c), managedidentity.WithRetryPolicyDisabled())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.msalClient = &msalClient
|
||||
|
||||
if log.Should(EventAuthentication) {
|
||||
log.Writef(EventAuthentication, "Managed Identity Credential will use %s managed identity", env)
|
||||
msg := fmt.Sprintf("%s will use %s managed identity", credNameManagedIdentity, env)
|
||||
if options.ID != nil {
|
||||
kind := "client"
|
||||
switch options.ID.(type) {
|
||||
case ObjectID:
|
||||
kind = "object"
|
||||
case ResourceID:
|
||||
kind = "resource"
|
||||
}
|
||||
msg += fmt.Sprintf(" with %s ID %q", kind, options.ID.String())
|
||||
}
|
||||
log.Write(EventAuthentication, msg)
|
||||
}
|
||||
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
// provideToken acquires a token for MSAL's confidential.Client, which caches the token
|
||||
func (c *managedIdentityClient) provideToken(ctx context.Context, params confidential.TokenProviderParameters) (confidential.TokenProviderResult, error) {
|
||||
result := confidential.TokenProviderResult{}
|
||||
tk, err := c.authenticate(ctx, c.id, params.Scopes)
|
||||
if err == nil {
|
||||
result.AccessToken = tk.Token
|
||||
result.ExpiresInSeconds = int(time.Until(tk.ExpiresOn).Seconds())
|
||||
}
|
||||
return result, err
|
||||
func (*managedIdentityClient) CloseIdleConnections() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
func (c *managedIdentityClient) Do(r *http.Request) (*http.Response, error) {
|
||||
return doForClient(c.azClient, r)
|
||||
}
|
||||
|
||||
// authenticate acquires an access token
|
||||
func (c *managedIdentityClient) authenticate(ctx context.Context, id ManagedIDKind, scopes []string) (azcore.AccessToken, error) {
|
||||
func (c *managedIdentityClient) GetToken(ctx context.Context, tro policy.TokenRequestOptions) (azcore.AccessToken, error) {
|
||||
// no need to synchronize around this value because it's true only when DefaultAzureCredential constructed the client,
|
||||
// and in that case ChainedTokenCredential.GetToken synchronizes goroutines that would execute this block
|
||||
if c.probeIMDS {
|
||||
@ -222,7 +171,7 @@ func (c *managedIdentityClient) authenticate(ctx context.Context, id ManagedIDKi
|
||||
cx, cancel := context.WithTimeout(ctx, imdsProbeTimeout)
|
||||
defer cancel()
|
||||
cx = policy.WithRetryOptions(cx, policy.RetryOptions{MaxRetries: -1})
|
||||
req, err := azruntime.NewRequest(cx, http.MethodGet, c.endpoint)
|
||||
req, err := azruntime.NewRequest(cx, http.MethodGet, imdsEndpoint)
|
||||
if err != nil {
|
||||
return azcore.AccessToken{}, fmt.Errorf("failed to create IMDS probe request: %s", err)
|
||||
}
|
||||
@ -237,32 +186,26 @@ func (c *managedIdentityClient) authenticate(ctx context.Context, id ManagedIDKi
|
||||
c.probeIMDS = false
|
||||
}
|
||||
|
||||
msg, err := c.createAuthRequest(ctx, id, scopes)
|
||||
if err != nil {
|
||||
return azcore.AccessToken{}, err
|
||||
ar, err := c.msalClient.AcquireToken(ctx, tro.Scopes[0], managedidentity.WithClaims(tro.Claims))
|
||||
if err == nil {
|
||||
msg := fmt.Sprintf(scopeLogFmt, credNameManagedIdentity, strings.Join(ar.GrantedScopes, ", "))
|
||||
log.Write(EventAuthentication, msg)
|
||||
return azcore.AccessToken{Token: ar.AccessToken, ExpiresOn: ar.ExpiresOn.UTC(), RefreshOn: ar.Metadata.RefreshOn.UTC()}, err
|
||||
}
|
||||
|
||||
resp, err := c.azClient.Pipeline().Do(msg)
|
||||
if err != nil {
|
||||
return azcore.AccessToken{}, newAuthenticationFailedError(credNameManagedIdentity, err.Error(), nil)
|
||||
}
|
||||
|
||||
if azruntime.HasStatusCode(resp, http.StatusOK, http.StatusCreated) {
|
||||
tk, err := c.createAccessToken(resp)
|
||||
if err != nil && c.chained && c.msiType == msiTypeIMDS {
|
||||
// failure to unmarshal a 2xx implies the response is from something other than IMDS such as a proxy listening at
|
||||
if c.imds {
|
||||
var ije msalerrors.InvalidJsonErr
|
||||
if c.chained && errors.As(err, &ije) {
|
||||
// an unmarshaling error implies the response is from something other than IMDS such as a proxy listening at
|
||||
// the same address. Return a credentialUnavailableError so credential chains continue to their next credential
|
||||
err = newCredentialUnavailableError(credNameManagedIdentity, err.Error())
|
||||
return azcore.AccessToken{}, newCredentialUnavailableError(credNameManagedIdentity, err.Error())
|
||||
}
|
||||
resp := getResponseFromError(err)
|
||||
if resp == nil {
|
||||
return azcore.AccessToken{}, newAuthenticationFailedErrorFromMSAL(credNameManagedIdentity, err)
|
||||
}
|
||||
return tk, err
|
||||
}
|
||||
|
||||
if c.msiType == msiTypeIMDS {
|
||||
switch resp.StatusCode {
|
||||
case http.StatusBadRequest:
|
||||
if id != nil {
|
||||
// return authenticationFailedError, halting any encompassing credential chain,
|
||||
// because the explicit user-assigned identity implies the developer expected this to work
|
||||
if c.userAssigned {
|
||||
return azcore.AccessToken{}, newAuthenticationFailedError(credNameManagedIdentity, "the requested identity isn't assigned to this resource", resp)
|
||||
}
|
||||
msg := "failed to authenticate a system assigned identity"
|
||||
@ -278,237 +221,7 @@ func (c *managedIdentityClient) authenticate(ctx context.Context, id ManagedIDKi
|
||||
return azcore.AccessToken{}, newCredentialUnavailableError(credNameManagedIdentity, fmt.Sprintf("unexpected response %q", string(body)))
|
||||
}
|
||||
}
|
||||
if c.chained {
|
||||
// the response may be from something other than IMDS, for example a proxy returning
|
||||
// 404. Return credentialUnavailableError so credential chains continue to their
|
||||
// next credential, include the response in the error message to help debugging
|
||||
err = newAuthenticationFailedError(credNameManagedIdentity, "", resp)
|
||||
return azcore.AccessToken{}, newCredentialUnavailableError(credNameManagedIdentity, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return azcore.AccessToken{}, newAuthenticationFailedError(credNameManagedIdentity, "", resp)
|
||||
}
|
||||
|
||||
func (c *managedIdentityClient) createAccessToken(res *http.Response) (azcore.AccessToken, error) {
|
||||
value := struct {
|
||||
// these are the only fields that we use
|
||||
Token string `json:"access_token,omitempty"`
|
||||
RefreshToken string `json:"refresh_token,omitempty"`
|
||||
ExpiresIn wrappedNumber `json:"expires_in,omitempty"` // this field should always return the number of seconds for which a token is valid
|
||||
ExpiresOn interface{} `json:"expires_on,omitempty"` // the value returned in this field varies between a number and a date string
|
||||
}{}
|
||||
if err := azruntime.UnmarshalAsJSON(res, &value); err != nil {
|
||||
return azcore.AccessToken{}, newAuthenticationFailedError(credNameManagedIdentity, "Unexpected response content", res)
|
||||
}
|
||||
if value.ExpiresIn != "" {
|
||||
expiresIn, err := json.Number(value.ExpiresIn).Int64()
|
||||
if err != nil {
|
||||
return azcore.AccessToken{}, err
|
||||
}
|
||||
return azcore.AccessToken{Token: value.Token, ExpiresOn: time.Now().Add(time.Second * time.Duration(expiresIn)).UTC()}, nil
|
||||
}
|
||||
switch v := value.ExpiresOn.(type) {
|
||||
case float64:
|
||||
return azcore.AccessToken{Token: value.Token, ExpiresOn: time.Unix(int64(v), 0).UTC()}, nil
|
||||
case string:
|
||||
if expiresOn, err := strconv.Atoi(v); err == nil {
|
||||
return azcore.AccessToken{Token: value.Token, ExpiresOn: time.Unix(int64(expiresOn), 0).UTC()}, nil
|
||||
}
|
||||
return azcore.AccessToken{}, newAuthenticationFailedError(credNameManagedIdentity, "unexpected expires_on value: "+v, res)
|
||||
default:
|
||||
msg := fmt.Sprintf("unsupported type received in expires_on: %T, %v", v, v)
|
||||
return azcore.AccessToken{}, newAuthenticationFailedError(credNameManagedIdentity, msg, res)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *managedIdentityClient) createAuthRequest(ctx context.Context, id ManagedIDKind, scopes []string) (*policy.Request, error) {
|
||||
switch c.msiType {
|
||||
case msiTypeIMDS:
|
||||
return c.createIMDSAuthRequest(ctx, id, scopes)
|
||||
case msiTypeAppService:
|
||||
return c.createAppServiceAuthRequest(ctx, id, scopes)
|
||||
case msiTypeAzureArc:
|
||||
// need to perform preliminary request to retreive the secret key challenge provided by the HIMDS service
|
||||
key, err := c.getAzureArcSecretKey(ctx, scopes)
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("failed to retreive secret key from the identity endpoint: %v", err)
|
||||
return nil, newAuthenticationFailedError(credNameManagedIdentity, msg, nil)
|
||||
}
|
||||
return c.createAzureArcAuthRequest(ctx, scopes, key)
|
||||
case msiTypeAzureML:
|
||||
return c.createAzureMLAuthRequest(ctx, id, scopes)
|
||||
case msiTypeServiceFabric:
|
||||
return c.createServiceFabricAuthRequest(ctx, scopes)
|
||||
case msiTypeCloudShell:
|
||||
return c.createCloudShellAuthRequest(ctx, scopes)
|
||||
default:
|
||||
return nil, newCredentialUnavailableError(credNameManagedIdentity, "managed identity isn't supported in this environment")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *managedIdentityClient) createIMDSAuthRequest(ctx context.Context, id ManagedIDKind, scopes []string) (*policy.Request, error) {
|
||||
request, err := azruntime.NewRequest(ctx, http.MethodGet, c.endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
request.Raw().Header.Set(headerMetadata, "true")
|
||||
q := request.Raw().URL.Query()
|
||||
q.Set("api-version", imdsAPIVersion)
|
||||
q.Set("resource", strings.Join(scopes, " "))
|
||||
if id != nil {
|
||||
switch id.idKind() {
|
||||
case miClientID:
|
||||
q.Set(qpClientID, id.String())
|
||||
case miObjectID:
|
||||
q.Set("object_id", id.String())
|
||||
case miResourceID:
|
||||
q.Set(msiResID, id.String())
|
||||
}
|
||||
}
|
||||
request.Raw().URL.RawQuery = q.Encode()
|
||||
return request, nil
|
||||
}
|
||||
|
||||
func (c *managedIdentityClient) createAppServiceAuthRequest(ctx context.Context, id ManagedIDKind, scopes []string) (*policy.Request, error) {
|
||||
request, err := azruntime.NewRequest(ctx, http.MethodGet, c.endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
request.Raw().Header.Set("X-IDENTITY-HEADER", os.Getenv(identityHeader))
|
||||
q := request.Raw().URL.Query()
|
||||
q.Set("api-version", "2019-08-01")
|
||||
q.Set("resource", scopes[0])
|
||||
if id != nil {
|
||||
switch id.idKind() {
|
||||
case miClientID:
|
||||
q.Set(qpClientID, id.String())
|
||||
case miObjectID:
|
||||
q.Set("principal_id", id.String())
|
||||
case miResourceID:
|
||||
q.Set(miResID, id.String())
|
||||
}
|
||||
}
|
||||
request.Raw().URL.RawQuery = q.Encode()
|
||||
return request, nil
|
||||
}
|
||||
|
||||
func (c *managedIdentityClient) createAzureMLAuthRequest(ctx context.Context, id ManagedIDKind, scopes []string) (*policy.Request, error) {
|
||||
request, err := azruntime.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.Set("api-version", "2017-09-01")
|
||||
q.Set("resource", strings.Join(scopes, " "))
|
||||
q.Set("clientid", os.Getenv(defaultIdentityClientID))
|
||||
if id != nil {
|
||||
switch id.idKind() {
|
||||
case miClientID:
|
||||
q.Set("clientid", id.String())
|
||||
case miObjectID:
|
||||
return nil, newAuthenticationFailedError(credNameManagedIdentity, "Azure ML doesn't support specifying a managed identity by object ID", nil)
|
||||
case miResourceID:
|
||||
return nil, newAuthenticationFailedError(credNameManagedIdentity, "Azure ML doesn't support specifying a managed identity by resource ID", nil)
|
||||
}
|
||||
}
|
||||
request.Raw().URL.RawQuery = q.Encode()
|
||||
return request, nil
|
||||
}
|
||||
|
||||
func (c *managedIdentityClient) createServiceFabricAuthRequest(ctx context.Context, scopes []string) (*policy.Request, error) {
|
||||
request, err := azruntime.NewRequest(ctx, http.MethodGet, c.endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
q := request.Raw().URL.Query()
|
||||
request.Raw().Header.Set("Accept", "application/json")
|
||||
request.Raw().Header.Set("Secret", os.Getenv(identityHeader))
|
||||
q.Set("api-version", serviceFabricAPIVersion)
|
||||
q.Set("resource", strings.Join(scopes, " "))
|
||||
request.Raw().URL.RawQuery = q.Encode()
|
||||
return request, nil
|
||||
}
|
||||
|
||||
func (c *managedIdentityClient) getAzureArcSecretKey(ctx context.Context, resources []string) (string, error) {
|
||||
// create the request to retreive the secret key challenge provided by the HIMDS service
|
||||
request, err := azruntime.NewRequest(ctx, http.MethodGet, c.endpoint)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
request.Raw().Header.Set(headerMetadata, "true")
|
||||
q := request.Raw().URL.Query()
|
||||
q.Set("api-version", azureArcAPIVersion)
|
||||
q.Set("resource", strings.Join(resources, " "))
|
||||
request.Raw().URL.RawQuery = q.Encode()
|
||||
// send the initial request to get the short-lived secret key
|
||||
response, err := c.azClient.Pipeline().Do(request)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// the endpoint is expected to return a 401 with the WWW-Authenticate header set to the location
|
||||
// of the secret key file. Any other status code indicates an error in the request.
|
||||
if response.StatusCode != 401 {
|
||||
msg := fmt.Sprintf("expected a 401 response, received %d", response.StatusCode)
|
||||
return "", newAuthenticationFailedError(credNameManagedIdentity, msg, response)
|
||||
}
|
||||
header := response.Header.Get("WWW-Authenticate")
|
||||
if len(header) == 0 {
|
||||
return "", newAuthenticationFailedError(credNameManagedIdentity, "HIMDS response has no WWW-Authenticate header", nil)
|
||||
}
|
||||
// the WWW-Authenticate header is expected in the following format: Basic realm=/some/file/path.key
|
||||
_, p, found := strings.Cut(header, "=")
|
||||
if !found {
|
||||
return "", newAuthenticationFailedError(credNameManagedIdentity, "unexpected WWW-Authenticate header from HIMDS: "+header, nil)
|
||||
}
|
||||
expected, err := arcKeyDirectory()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if filepath.Dir(p) != expected || !strings.HasSuffix(p, ".key") {
|
||||
return "", newAuthenticationFailedError(credNameManagedIdentity, "unexpected file path from HIMDS service: "+p, nil)
|
||||
}
|
||||
f, err := os.Stat(p)
|
||||
if err != nil {
|
||||
return "", newAuthenticationFailedError(credNameManagedIdentity, fmt.Sprintf("could not stat %q: %v", p, err), nil)
|
||||
}
|
||||
if s := f.Size(); s > 4096 {
|
||||
return "", newAuthenticationFailedError(credNameManagedIdentity, fmt.Sprintf("key is too large (%d bytes)", s), nil)
|
||||
}
|
||||
key, err := os.ReadFile(p)
|
||||
if err != nil {
|
||||
return "", newAuthenticationFailedError(credNameManagedIdentity, fmt.Sprintf("could not read %q: %v", p, err), nil)
|
||||
}
|
||||
return string(key), nil
|
||||
}
|
||||
|
||||
func (c *managedIdentityClient) createAzureArcAuthRequest(ctx context.Context, resources []string, key string) (*policy.Request, error) {
|
||||
request, err := azruntime.NewRequest(ctx, http.MethodGet, c.endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
request.Raw().Header.Set(headerMetadata, "true")
|
||||
request.Raw().Header.Set("Authorization", fmt.Sprintf("Basic %s", key))
|
||||
q := request.Raw().URL.Query()
|
||||
q.Set("api-version", azureArcAPIVersion)
|
||||
q.Set("resource", strings.Join(resources, " "))
|
||||
request.Raw().URL.RawQuery = q.Encode()
|
||||
return request, nil
|
||||
}
|
||||
|
||||
func (c *managedIdentityClient) createCloudShellAuthRequest(ctx context.Context, scopes []string) (*policy.Request, error) {
|
||||
request, err := azruntime.NewRequest(ctx, http.MethodPost, c.endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
request.Raw().Header.Set(headerMetadata, "true")
|
||||
data := url.Values{}
|
||||
data.Set("resource", strings.Join(scopes, " "))
|
||||
dataEncoded := data.Encode()
|
||||
body := streaming.NopCloser(strings.NewReader(dataEncoded))
|
||||
if err := request.SetBody(body, "application/x-www-form-urlencoded"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return request, nil
|
||||
err = newAuthenticationFailedErrorFromMSAL(credNameManagedIdentity, err)
|
||||
return azcore.AccessToken{}, err
|
||||
}
|
||||
|
28
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_credential.go
generated
vendored
28
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/managed_identity_credential.go
generated
vendored
@ -14,7 +14,6 @@ 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"
|
||||
)
|
||||
|
||||
const credNameManagedIdentity = "ManagedIdentityCredential"
|
||||
@ -110,8 +109,7 @@ type ManagedIdentityCredentialOptions struct {
|
||||
//
|
||||
// [Azure managed identity]: https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/overview
|
||||
type ManagedIdentityCredential struct {
|
||||
client *confidentialClient
|
||||
mic *managedIdentityClient
|
||||
mic *managedIdentityClient
|
||||
}
|
||||
|
||||
// NewManagedIdentityCredential creates a ManagedIdentityCredential. Pass nil to accept default options.
|
||||
@ -123,38 +121,22 @@ func NewManagedIdentityCredential(options *ManagedIdentityCredentialOptions) (*M
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cred := confidential.NewCredFromTokenProvider(mic.provideToken)
|
||||
|
||||
// It's okay to give MSAL an invalid client ID because MSAL will use it only as part of a cache key.
|
||||
// ManagedIdentityClient handles all the details of authentication and won't receive this value from MSAL.
|
||||
clientID := "SYSTEM-ASSIGNED-MANAGED-IDENTITY"
|
||||
if options.ID != nil {
|
||||
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{
|
||||
ClientOptions: options.ClientOptions,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ManagedIdentityCredential{client: c, mic: mic}, nil
|
||||
return &ManagedIdentityCredential{mic: mic}, nil
|
||||
}
|
||||
|
||||
// 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)
|
||||
ctx, endSpan := runtime.StartSpan(ctx, credNameManagedIdentity+"."+traceOpGetToken, c.mic.azClient.Tracer(), nil)
|
||||
defer func() { endSpan(err) }()
|
||||
|
||||
if len(opts.Scopes) != 1 {
|
||||
err = fmt.Errorf("%s.GetToken() requires exactly one scope", credNameManagedIdentity)
|
||||
return azcore.AccessToken{}, err
|
||||
}
|
||||
// managed identity endpoints require a Microsoft Entra ID v1 resource (i.e. token audience), not a v2 scope, so we remove "/.default" here
|
||||
// managed identity endpoints require a v1 resource (i.e. token audience), not a v2 scope, so we remove "/.default" here
|
||||
opts.Scopes = []string{strings.TrimSuffix(opts.Scopes[0], defaultSuffix)}
|
||||
tk, err := c.client.GetToken(ctx, opts)
|
||||
return tk, err
|
||||
return c.mic.GetToken(ctx, opts)
|
||||
}
|
||||
|
||||
var _ azcore.TokenCredential = (*ManagedIdentityCredential)(nil)
|
||||
|
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/public_client.go
generated
vendored
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/public_client.go
generated
vendored
@ -243,7 +243,7 @@ func (p *publicClient) token(ar public.AuthResult, err error) (azcore.AccessToke
|
||||
} else {
|
||||
err = newAuthenticationFailedErrorFromMSAL(p.name, err)
|
||||
}
|
||||
return azcore.AccessToken{Token: ar.AccessToken, ExpiresOn: ar.ExpiresOn.UTC()}, err
|
||||
return azcore.AccessToken{Token: ar.AccessToken, ExpiresOn: ar.ExpiresOn.UTC(), RefreshOn: ar.Metadata.RefreshOn.UTC()}, err
|
||||
}
|
||||
|
||||
// resolveTenant returns the correct WithTenantID() argument for a token request given the client's
|
||||
|
4
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources-post.ps1
generated
vendored
4
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/test-resources-post.ps1
generated
vendored
@ -72,6 +72,7 @@ az container create -g $rg -n $aciName --image $image `
|
||||
--acr-identity $($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY']) `
|
||||
--assign-identity [system] $($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY']) `
|
||||
--cpu 1 `
|
||||
--ip-address Public `
|
||||
--memory 1.0 `
|
||||
--os-type Linux `
|
||||
--role "Storage Blob Data Reader" `
|
||||
@ -82,7 +83,8 @@ az container create -g $rg -n $aciName --image $image `
|
||||
AZIDENTITY_USER_ASSIGNED_IDENTITY_CLIENT_ID=$($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY_CLIENT_ID']) `
|
||||
AZIDENTITY_USER_ASSIGNED_IDENTITY_OBJECT_ID=$($DeploymentOutputs['AZIDENTITY_USER_ASSIGNED_IDENTITY_OBJECT_ID']) `
|
||||
FUNCTIONS_CUSTOMHANDLER_PORT=80
|
||||
Write-Host "##vso[task.setvariable variable=AZIDENTITY_ACI_NAME;]$aciName"
|
||||
$aciIP = az container show -g $rg -n $aciName --query ipAddress.ip --output tsv
|
||||
Write-Host "##vso[task.setvariable variable=AZIDENTITY_ACI_IP;]$aciIP"
|
||||
|
||||
# Azure Functions deployment: copy the Windows binary from the Docker image, deploy it in a zip
|
||||
Write-Host "Deploying to Azure Functions"
|
||||
|
12
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/username_password_credential.go
generated
vendored
12
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/username_password_credential.go
generated
vendored
@ -17,6 +17,11 @@ import (
|
||||
const credNameUserPassword = "UsernamePasswordCredential"
|
||||
|
||||
// UsernamePasswordCredentialOptions contains optional parameters for UsernamePasswordCredential.
|
||||
//
|
||||
// Deprecated: UsernamePasswordCredential is deprecated because it can't support multifactor
|
||||
// authentication. See [Entra ID documentation] for migration guidance.
|
||||
//
|
||||
// [Entra ID documentation]: https://aka.ms/azsdk/identity/mfa
|
||||
type UsernamePasswordCredentialOptions struct {
|
||||
azcore.ClientOptions
|
||||
|
||||
@ -43,8 +48,13 @@ type UsernamePasswordCredentialOptions struct {
|
||||
|
||||
// UsernamePasswordCredential authenticates a user with a password. Microsoft doesn't recommend this kind of authentication,
|
||||
// because it's less secure than other authentication flows. This credential is not interactive, so it isn't compatible
|
||||
// with any form of multi-factor authentication, and the application must already have user or admin consent.
|
||||
// with any form of multifactor authentication, and the application must already have user or admin consent.
|
||||
// This credential can only authenticate work and school accounts; it can't authenticate Microsoft accounts.
|
||||
//
|
||||
// Deprecated: this credential is deprecated because it can't support multifactor authentication. See [Entra ID documentation]
|
||||
// for migration guidance.
|
||||
//
|
||||
// [Entra ID documentation]: https://aka.ms/azsdk/identity/mfa
|
||||
type UsernamePasswordCredential struct {
|
||||
client *publicClient
|
||||
}
|
||||
|
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go
generated
vendored
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/azidentity/version.go
generated
vendored
@ -14,5 +14,5 @@ const (
|
||||
module = "github.com/Azure/azure-sdk-for-go/sdk/" + component
|
||||
|
||||
// Version is the semantic version (see http://semver.org) of this module.
|
||||
version = "v1.8.2"
|
||||
version = "v1.9.0"
|
||||
)
|
||||
|
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/log/log.go
generated
vendored
2
vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/log/log.go
generated
vendored
@ -44,7 +44,7 @@ func Should(cls Event) bool {
|
||||
if log.lst == nil {
|
||||
return false
|
||||
}
|
||||
if log.cls == nil || len(log.cls) == 0 {
|
||||
if len(log.cls) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, c := range log.cls {
|
||||
|
51
vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/temporal/resource.go
generated
vendored
51
vendor/github.com/Azure/azure-sdk-for-go/sdk/internal/temporal/resource.go
generated
vendored
@ -11,9 +11,17 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// backoff sets a minimum wait time between eager update attempts. It's a variable so tests can manipulate it.
|
||||
var backoff = func(now, lastAttempt time.Time) bool {
|
||||
return lastAttempt.Add(30 * time.Second).After(now)
|
||||
}
|
||||
|
||||
// AcquireResource abstracts a method for refreshing a temporal resource.
|
||||
type AcquireResource[TResource, TState any] func(state TState) (newResource TResource, newExpiration time.Time, err error)
|
||||
|
||||
// ShouldRefresh abstracts a method for indicating whether a resource should be refreshed before expiration.
|
||||
type ShouldRefresh[TResource, TState any] func(TResource, TState) bool
|
||||
|
||||
// Resource is a temporal resource (usually a credential) that requires periodic refreshing.
|
||||
type Resource[TResource, TState any] struct {
|
||||
// cond is used to synchronize access to the shared resource embodied by the remaining fields
|
||||
@ -31,24 +39,43 @@ type Resource[TResource, TState any] struct {
|
||||
// lastAttempt indicates when a thread/goroutine last attempted to acquire/update the resource
|
||||
lastAttempt time.Time
|
||||
|
||||
// shouldRefresh indicates whether the resource should be refreshed before expiration
|
||||
shouldRefresh ShouldRefresh[TResource, TState]
|
||||
|
||||
// acquireResource is the callback function that actually acquires the resource
|
||||
acquireResource AcquireResource[TResource, TState]
|
||||
}
|
||||
|
||||
// NewResource creates a new Resource that uses the specified AcquireResource for refreshing.
|
||||
func NewResource[TResource, TState any](ar AcquireResource[TResource, TState]) *Resource[TResource, TState] {
|
||||
return &Resource[TResource, TState]{cond: sync.NewCond(&sync.Mutex{}), acquireResource: ar}
|
||||
r := &Resource[TResource, TState]{acquireResource: ar, cond: sync.NewCond(&sync.Mutex{})}
|
||||
r.shouldRefresh = r.expiringSoon
|
||||
return r
|
||||
}
|
||||
|
||||
// ResourceOptions contains optional configuration for Resource
|
||||
type ResourceOptions[TResource, TState any] struct {
|
||||
// ShouldRefresh indicates whether [Resource.Get] should acquire an updated resource despite
|
||||
// the currently held resource not having expired. [Resource.Get] ignores all errors from
|
||||
// refresh attempts triggered by ShouldRefresh returning true, and doesn't call ShouldRefresh
|
||||
// when the resource has expired (it unconditionally updates expired resources). When
|
||||
// ShouldRefresh is nil, [Resource.Get] refreshes the resource if it will expire within 5
|
||||
// minutes.
|
||||
ShouldRefresh ShouldRefresh[TResource, TState]
|
||||
}
|
||||
|
||||
// NewResourceWithOptions creates a new Resource that uses the specified AcquireResource for refreshing.
|
||||
func NewResourceWithOptions[TResource, TState any](ar AcquireResource[TResource, TState], opts ResourceOptions[TResource, TState]) *Resource[TResource, TState] {
|
||||
r := NewResource(ar)
|
||||
if opts.ShouldRefresh != nil {
|
||||
r.shouldRefresh = opts.ShouldRefresh
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Get returns the underlying resource.
|
||||
// If the resource is fresh, no refresh is performed.
|
||||
func (er *Resource[TResource, TState]) Get(state TState) (TResource, error) {
|
||||
// If the resource is expiring within this time window, update it eagerly.
|
||||
// This allows other threads/goroutines to keep running by using the not-yet-expired
|
||||
// resource value while one thread/goroutine updates the resource.
|
||||
const window = 5 * time.Minute // This example updates the resource 5 minutes prior to expiration
|
||||
const backoff = 30 * time.Second // Minimum wait time between eager update attempts
|
||||
|
||||
now, acquire, expired := time.Now(), false, false
|
||||
|
||||
// acquire exclusive lock
|
||||
@ -65,9 +92,8 @@ func (er *Resource[TResource, TState]) Get(state TState) (TResource, error) {
|
||||
break
|
||||
}
|
||||
// Getting here means that this thread/goroutine will wait for the updated resource
|
||||
} else if er.expiration.Add(-window).Before(now) {
|
||||
// The resource is valid but is expiring within the time window
|
||||
if !er.acquiring && er.lastAttempt.Add(backoff).Before(now) {
|
||||
} else if er.shouldRefresh(resource, state) {
|
||||
if !(er.acquiring || backoff(now, er.lastAttempt)) {
|
||||
// If another thread/goroutine is not acquiring/renewing the resource, and none has attempted
|
||||
// to do so within the last 30 seconds, this thread/goroutine will do it
|
||||
er.acquiring, acquire = true, true
|
||||
@ -121,3 +147,8 @@ func (er *Resource[TResource, TState]) Expire() {
|
||||
// Reset the expiration as if we never got this resource to begin with
|
||||
er.expiration = time.Time{}
|
||||
}
|
||||
|
||||
func (er *Resource[TResource, TState]) expiringSoon(TResource, TState) bool {
|
||||
// call time.Now() instead of using Get's value so ShouldRefresh doesn't need a time.Time parameter
|
||||
return er.expiration.Add(-5 * time.Minute).Before(time.Now())
|
||||
}
|
||||
|
Reference in New Issue
Block a user